SinhVienCNTT.Net
Thứ Sáu, Tháng 10 10, 2025
  • Login
No Result
View All Result
  • Trang chủ
  • Bài viết nổi bật
  • Security
    • Kỹ thuật phân tích mã độc
    • CEH v13
  • Các môn học đại học
    • Các môn đại cương
      • Nhập môn mạng máy tính
      • Nhập môn lập trình
      • Hệ điều hành
    • Ngành An toàn thông tin
      • Lập trình hệ thống
    • Ngành Mạng máy tính & Truyền thông dữ liệu
  • Tài liệu CNTT
  • Liên hệ
Gửi email
  • Trang chủ
  • Bài viết nổi bật
  • Security
    • Kỹ thuật phân tích mã độc
    • CEH v13
  • Các môn học đại học
    • Các môn đại cương
      • Nhập môn mạng máy tính
      • Nhập môn lập trình
      • Hệ điều hành
    • Ngành An toàn thông tin
      • Lập trình hệ thống
    • Ngành Mạng máy tính & Truyền thông dữ liệu
  • Tài liệu CNTT
  • Liên hệ
No Result
View All Result
SinhVienCNTT.Net
No Result
View All Result
Home Machine Learning

Lý thuyết toán cơ bản trong Deep Learning (phần 2)

admin by admin
6 Tháng 3, 2024
in Machine Learning
1
Lý thuyết toán cơ bản trong Deep Learning

Tiếp nối phần Lý thuyết toán cơ bản trong Deep Learning, bài viết này sẽ trình bày tiếp về các phép toán trên tensor cũng như diễn giải hình học.

Mục lục ẩn
1. Các phép toán theo phần tử
2. Broadcasting
3. Phép nhân tensor
4. Tensor reshape
5. Diễn giải hình học về các phép toán tensor trong Deep Learning

Tất cả các biến đổi mà mạng nơ-ron sâu học được có thể được giảm xuống thành các phép toán tensor (hoặc hàm tensor) được áp dụng cho các tensor chứa dữ liệu số.

Python
keras.layers.Dense(512, activation="relu")

Layer này có thể được hiểu như là một hàm, nhận một ma trận làm đầu vào và trả về một ma trận khác – một biểu diễn mới cho tensor đầu vào. Cụ thể, hàm có dạng như sau (trong đó W là một ma trận và b là một vector, đều là thuộc tính của layer).

Python
output = relu(dot(input, W) + b)


Chúng ta có ba phép toán tensor ở đây:

  • Một tích vô hướng (dot) giữa tensor đầu vào và một tensor có tên là W.
  • Một phép cộng (+) giữa ma trận kết quả và một vector b.
  • Một phép relu: relu(x) là max(x, 0); “relu” là viết tắt của “rectified linear unit” (đơn vị tuyến tính được điều chỉnh).

Các phép toán theo phần tử

Phép toán relu và phép cộng là các phép toán theo phần tử (element-wise operations). Các phép toán được áp dụng độc lập cho mỗi phần tử trong các tensor đang xem xét. Điều này có nghĩa là những phép toán này rất thích hợp cho các triển khai đồng thời (triển khai vector hóa – một thuật ngữ xuất phát từ kiến trúc siêu máy tính xử lý vector từ thập kỷ 1970-90). Đối với relu:

Python
def naive_relu(x):
 assert len(x.shape) == 2
 x = x.copy() 
 for i in range(x.shape[0]):
 for j in range(x.shape[1]):
 x[i, j] = max(x[i, j], 0)
 return x

Đối với phép cộng:

Python
def naive_add(x, y):
 assert len(x.shape) == 2
 assert x.shape == y.shape
 x = x.copy() 
 for i in range(x.shape[0]):
 for j in range(x.shape[1]):
 x[i, j] += y[i, j]
 return x

Trên cùng nguyên tắc đó, ta có thể thực hiện phép nhân theo phần tử, phép trừ, và cũng như vậy.

Python
import numpy as np
z = x + y 
z = np.maximum(z, 0.)

Broadcasting

Hàm naive_add phía trên chỉ hỗ trợ phép cộng giữa các tensor có hạng là 2 và có shape giống nhau. Nhưng trong class Dense đã giới thiệu trước đó (ở đoạn code đầu tiên bài viết này), ta đã thêm một tensor hạng 2 với một vector. Điều gì sẽ xảy ra khi shape của hai tensor khác nhau và được cộng với nhau? Đó là tensor nhỏ hơn sẽ được broadcast để phù hợp với shape của tensor lớn hơn. Quá trình broadcast bao gồm 2 bước:

  1. Các trục (được gọi là trục broadcast được thêm vào tensor nhỏ hơn để phù hợp với ndim của tensor lớn hơn.
  2. Tensor nhỏ hơn được lặp lại theo các trục mới này để phù hợp với shape đầy đủ của tensor lớn hơn.

Giả sử có tensor X với shape là (32, 10) và tensor y với shape là (10,).

Python
import numpy as np
X = np.random.random((32, 10)) 
y = np.random.random((10,))

Trước hết, ta thêm một trục đầu tiên trống vào tensor y, khiến cho shape của nó trở thành (1, 10):

Python
y = np.expand_dims(y, axis=0)

Sau đó, ta lặp lại tensor y 32 lần theo chiều của trục mới này, để cuối cùng chúng ta thu được tensor Y với shape là (32, 10), trong đó Y[i, :] == y cho i trong khoảng từ 0 đến 32:

Python
Y = np.concatenate([y] * 32, axis=0)

Ở điểm này, ta có thể tiếp tục thực hiện phép cộng giữa X và Y, vì chúng có cùng shape. Về mặt triển khai, không có tensor mới hạng 2 được tạo ra, vì điều đó sẽ rất không hiệu quả.

Python
def naive_add_matrix_and_vector(x, y):
 assert len(x.shape) == 2 
 assert len(y.shape) == 1 
 assert x.shape[1] == y.shape[0]
 x = x.copy() 
 for i in range(x.shape[0]):
   for j in range(x.shape[1]):
   x[i, j] += y[j]
 return x

Với phép broadcasting, ta thường có thể thực hiện các phép toán theo từng phần tử trên hai tensor đầu vào nếu một tensor có shape là (a, b, … n, n + 1, … m) và tensor kia có shape là (n, n + 1, … m). Phép broadcast sẽ tự động xảy ra cho các trục từ a đến n – 1. Dưới đây là một ví dụ sử dụng phép toán tối đa theo từng phần tử giữa hai tensor có hình dạng khác nhau thông qua phép broadcast:

Python
import numpy as np
x = np.random.random((64, 3, 32, 10)) 
y = np.random.random((32, 10)) 
z = np.maximum(x, y)

Phép nhân tensor

Phép nhân tensor, hay còn gọi là phép nhân chấm (không nên nhầm lẫn với phép nhân theo từng phần tử, toán tử *), là một trong những phép toán tensor phổ biến và hữu ích nhất. Trong NumPy, phép nhân tensor được thực hiện bằng cách sử dụng hàm np.dot (vì ký hiệu toán học cho phép nhân tensor thường là dấu chấm):

Python
x = np.random.random((32,))
y = np.random.random((32,))
z = np.dot(x, y)

Trong ký hiệu toán học, phép toán này được kí hiệu bằng dấu chấm (•).

Vậy phép toán dot hoạt động như thế nào? Hãy bắt đầu với tích vô hướng của hai vector, x và y. Nó được tính như sau:

Python
def naive_vector_dot(x, y):
 assert len(x.shape) == 1 
 assert len(y.shape) == 1 
 assert x.shape[0] == y.shape[0]
 z = 0.
 for i in range(x.shape[0]):
 z += x[i] * y[i]
 return z

Ta thấy rằng tích vô hướng giữa hai vector là một scalar và chỉ có các vector có cùng số lượng phần tử mới phù hợp cho phép toán dot. Ta cũng có thể thực hiện phép toán dot giữa một ma trận x và một vector y, kết quả trả về một vector trong đó các hệ số là tích vô hướng giữa y và các hàng của x. Ta có thể triển khai nó như sau.

Python
def naive_matrix_vector_dot(x, y):
 assert len(x.shape) == 2 
 assert len(y.shape) == 1 
 assert x.shape[1] == y.shape[0] 
 z = np.zeros(x.shape[0]) 
 for i in range(x.shape[0]):
 for j in range(x.shape[1]):
 z[i] += x[i, j] * y[j]
 return z

Ngắn gọn:

Python
def naive_matrix_vector_dot(x, y):
 z = np.zeros(x.shape[0])
 for i in range(x.shape[0]):
 z[i] = naive_vector_dot(x[i, :], y)
 return z

Lưu ý khi một trong hai tensor có ndim lớn hơn 1, phép toán dot không còn là đối xứng, có nghĩa là dot(x, y) không giống như dot(y, x).

Tất nhiên, phép nhân dot có thể tổng quát hóa cho các tensor có một số lượng trục tùy ý. Ứng dụng phổ biến nhất có thể là phép nhân dot giữa hai ma trận. Ta có thể thực hiện phép nhân dot giữa hai ma trận x và y (dot(x, y)) nếu và chỉ nếu x.shape[1] == y.shape[0]. Kết quả là một ma trận có hình dạng (x.shape[0], y.shape[1]), trong đó các hệ số là tích vô hướng giữa các hàng của x và các cột của y.

Python
def naive_matrix_dot(x, y):
 assert len(x.shape) == 2 
 assert len(y.shape) == 2 
 assert x.shape[1] == y.shape[0] 
 z = np.zeros((x.shape[0], y.shape[1])) 
 for i in range(x.shape[0]): 
 for j in range(y.shape[1]): 
 row_x = x[i, :]
 column_y = y[:, j]
 z[i, j] = naive_vector_dot(row_x, column_y)
 return z

Xem hình dưới để hiểu rõ hơn:

Lý thuyết toán cơ bản trong Deep Learning (phần 2) 2
Matrix dot-product box diagram

Nói chung, ta có thể thực hiện phép nhân dot giữa các tensor có số chiều cao hơn, theo các quy tắc tương thích hình dạng giống như đã được mô tả trước đó cho trường hợp 2D.

Python
(a, b, c, d) • (d,) → (a, b, c)
(a, b, c, d) • (d, e) → (a, b, c, e)

Tensor reshape

Một loại phép toán tensor thứ ba quan trọng để hiểu là thay đổi hình dạng tensor (tensor reshape).

Python
train_images = train_images.reshape((60000, 28 * 28))

Thay đổi hình dạng của một tensor có nghĩa là sắp xếp lại các hàng và cột của nó để phù hợp với một hình dạng mục tiêu. Đương nhiên, tensor đã thay đổi shape sẽ có cùng số lượng hệ số tổng cộng như tensor ban đầu. Việc thay đổi hình dạng được hiểu rõ nhất thông qua ví dụ đơn giản sau:

Python
>>> x = np.array([[0., 1.],
           [2., 3.],
           [4., 5.]])
>>> x.shape
(3, 2)
>>> x = x.reshape((6, 1))
>>> x
array([[ 0.],
     [ 1.],
     [ 2.],
     [ 3.],
     [ 4.],
     [ 5.]])
>>> x = x.reshape((2, 3))
>>> x
array([[ 0., 1., 2.],
      [ 3., 4., 5.]])

Một trường hợp đặc biệt của thay đổi hình dạng mà thường gặp là phép chuyển vị. Chuyển vị một ma trận có nghĩa là hoán đổi các hàng và cột của nó, sao cho x[i, :] trở thành x[:, i].

Python
>>> x = np.zeros((300, 20)) 
>>> x = np.transpose(x)
>>> x.shape
(20, 300)

Diễn giải hình học về các phép toán tensor trong Deep Learning

Phép toán tensor có thể được hiểu theo góc độ hình học bởi vì nội dung của các tensor được thao tác có thể được hiểu như là tọa độ của các điểm trong không gian hình học nào đó. Do đó, tất cả các phép toán tensor đều có một diễn giải hình học. Chẳng hạn phép cộng:

Python
A = [0.5, 1]

Đó là một điểm trong không gian 2 chiều.

Lý thuyết toán cơ bản trong Deep Learning (phần 2) 4
A point in a 2D space

Một vector được thể hiện như một mũi tên nối từ gốc tọa độ đến điểm đó như hình bên dưới.

Lý thuyết toán cơ bản trong Deep Learning (phần 2) 6
A point in a 2D space pictured as an arrow

Cho điểm B = [1, 0.25] vector AB được biểu diễn bằng hình học bằng cách nối các mũi tên vector lại với nhau, với vị trí kết quả là vector đại diện cho tổng của hai vector trước đó.

Lý thuyết toán cơ bản trong Deep Learning (phần 2) 8
Geometric interpretation of the sum of two vectors

Như các bạn có thể thấy, việc cộng vector B vào vector A đại diện cho việc sao chép điểm A vào một vị trí mới, với khoảng cách và hướng từ điểm ban đầu A được xác định bởi vector B. Nếu ta áp dụng phép cộng vector tương tự cho một nhóm điểm trong mặt phẳng (một “đối tượng”), ta sẽ tạo ra một bản sao của toàn bộ đối tượng ở một vị trí mới.

deep learning
2D translation as a vector addition

Do đó, phép cộng tensor đại diện cho hành động dịch chuyển một đối tượng (di chuyển đối tượng mà không làm biến dạng nó) một lượng nhất định theo một hướng cụ thể.

Nói chung, các phép toán hình học cơ bản như dịch chuyển (translation), xoay (rotating), co giãn (scaling), nghiêng (skewing), và những phép toán khác có thể được biểu diễn dưới dạng các phép toán tensor. Dưới đây là một số ví dụ:

  • Dịch chuyển (Translation): Việc cộng một vector vào một điểm sẽ di chuyển điểm đó một lượng cố định theo một hướng cố định. Khi áp dụng cho một tập hợp điểm (như một đối tượng 2D), điều này được gọi là “dịch chuyển“.
  • Xoay (Rotation): Xoay ngược chiều kim đồng hồ của một vector 2D một góc theta (như hình bên dưới) có thể được thực hiện thông qua tích vô hướng với ma trận 2 × 2 là R = [[cos(theta), -sin(theta)], [sin(theta), cos(theta)]].
Lý thuyết toán cơ bản trong Deep Learning (phần 2) 11
2D rotation (counterclockwise) as a dot product
  • Co giãn (Scaling): Co giãn theo chiều dọc và chiều ngang của hình ảnh có thể được thực hiện thông qua tích vô hướng với ma trận 2 × 2 là S = [[horizontal_factor, 0], [0, vertical_factor]] (lưu ý rằng ma trận như vậy được gọi là “ma trận chéo,” vì nó chỉ có các hệ số khác 0 trên “đường chéo” của nó, từ trên cùng bên trái đến dưới cùng bên phải).
Lý thuyết toán cơ bản trong Deep Learning (phần 2) 13
2D scaling as a dot product
  • Biến đổi tuyến tính (Linear transform): Tích vô hướng với một ma trận tùy ý thực hiện một biến đổi tuyến tính. Lưu ý rằng phép co giãn và phép xoay theo định nghĩa là biến đổi tuyến tính.
  • Biến đổi affine: Một biến đổi affine (hình dưới) là sự kết hợp giữa một biến đổi tuyến tính (thực hiện thông qua tích vô hướng với một số ma trận) và một dịch chuyển (thực hiện thông qua việc cộng thêm một vector). Đó chính xác là phép tính y = W • x + b được thực hiện bởi lớp Dense! Một lớp Dense mà không có hàm kích hoạt là một lớp affine.
Lý thuyết toán cơ bản trong Deep Learning (phần 2) 15
Affine transform in the plane
  • Layer Dense với hàm kích hoạt relu: Một quan sát quan trọng về các biến đổi affine là nếu ta áp dụng chúng nhiều lần liên tiếp, ta vẫn sẽ thu được một biến đổi affine (vì vậy ta có thể áp dụng một biến đổi affine đó từ đầu). Thử với hai lớp: affine2(affine1(x)) = W2 • (W1 • x + b1) + b2 = (W2 • W1) • x + (W2 • b1 + b2). Đó là một biến đổi affine với phần tuyến tính là ma trận W2 • W1 và phần dịch chuyển là vector W2 • b1 + b2. Do đó, một mạng nơ-ron nhiều lớp được tạo hoàn toàn từ các lớp Dense mà không có hàm kích hoạt sẽ tương đương với một lớp Dense duy nhất. Mạng nơ-ron “sâu” này chỉ là một mô hình tuyến tính ẩn! Đây là lý do tại sao ta cần các hàm kích hoạt, như relu. Nhờ các hàm kích hoạt, một chuỗi các lớp Dense có thể được thiết kế để thực hiện các biến đổi hình học phi tuyến, tạo ra không gian giả định rất phong phú cho các mạng nơ-ron sâu.
Lý thuyết toán cơ bản trong Deep Learning (phần 2) 17
Affine transform followed by relu activation
Tags: Machine Learning
Share66Tweet41
Previous Post

Lý thuyết toán cơ bản trong Deep Learning

Next Post

Cách tiếp cận dễ hiểu nhất về Gradient Descent

admin

admin

A Winner Never Stops Trying.

Related Posts

Ví dụ huấn luyện mô hình phân loại chữ viết tay cơ bản sử dụng Python
Machine Learning

Ví dụ huấn luyện mô hình phân loại chữ viết tay cơ bản sử dụng Python

4 Tháng 5, 2025
Thuật toán lan truyền ngược – Backpropagation
Machine Learning

Thuật toán lan truyền ngược – Backpropagation

6 Tháng 3, 2024
Cách tiếp cận dễ hiểu nhất về Gradient Descent
Machine Learning

Cách tiếp cận dễ hiểu nhất về Gradient Descent

6 Tháng 3, 2024
Lý thuyết toán cơ bản trong Deep Learning
Machine Learning

Lý thuyết toán cơ bản trong Deep Learning

6 Tháng 3, 2024
Lịch sử của phát triển của học sâu – Deep Learning
Machine Learning

Lịch sử của phát triển của học sâu – Deep Learning

2 Tháng 3, 2024
Học sâu và nguyên lý của học sâu
Machine Learning

Học sâu và nguyên lý của học sâu

1 Tháng 3, 2024
Next Post
Cách tiếp cận dễ hiểu nhất về Gradient Descent

Cách tiếp cận dễ hiểu nhất về Gradient Descent

Comments 1

  1. Pingback: Cách tiếp cận dễ hiểu nhất về Gradient Descent

Để lại một bình luận Hủy

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Danh mục

  • Các môn học đại học
  • CCNA 200-301
  • CEH Tiếng Việt – CEH v13
  • Chưa phân loại
  • Digital Forensics
  • Machine Learning
  • Network
  • Nổi bật
  • Phân tích mã độc
  • Security
  • Tài liệu CNTT
  • Từ vựng IELTS

Series

  • CHFI Tiếng Việt (1)
  • Cơ sở dữ liệu (2)
  • [2023] Share 1200 câu dump CCNA 200-301 mới nhất (3)
  • 1000 collocations IELTS phổ biến nhất (1)
  • Hệ điều hành (5)
  • Series cấu hình Firewall Cisco ASA (2)
  • Nhập môn lập trình (1)
  • 22 Lab thực hành Amazon Web Service (AWS) từ cơ bản đến nâng cao (4)
  • Nhập môn mạng máy tính (20)
  • Lập trình hệ thống (3)

logo sinhviencntt.net

Blog Sinh viên CNTT chia sẻ kiến thức, tài liệu liên quan đến nhóm ngành Công nghệ thông tin.

Chúng tôi sẵn sàng đón những ý kiến đóng góp, cũng như bài viết của các bạn gửi đến SinhVienCNTT.Net.

Giới thiệu

Blog Sinh viên CNTT chia sẻ kiến thức, tài liệu liên quan đến nhóm ngành Công nghệ thông tin.

Liên hệ

Email: sinhviencntt.net@gmail.com

Tìm kiếm

No Result
View All Result

Danh mục

  • Các môn học đại học
  • CCNA 200-301
  • CEH Tiếng Việt – CEH v13
  • Chưa phân loại
  • Digital Forensics
  • Machine Learning
  • Network
  • Nổi bật
  • Phân tích mã độc
  • Security
  • Tài liệu CNTT
  • Từ vựng IELTS
  • Home
  • Liên hệ
  • Privacy & Policy
  • Other Links

© 2023 SinhVienCNTT.Net - Blog Sinh viên Công nghệ thông tin.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • Bài viết nổi bật
  • Security
    • Kỹ thuật phân tích mã độc
    • CEH v13
  • Các môn học đại học
    • Các môn đại cương
      • Nhập môn mạng máy tính
      • Nhập môn lập trình
      • Hệ điều hành
    • Ngành An toàn thông tin
      • Lập trình hệ thống
    • Ngành Mạng máy tính & Truyền thông dữ liệu
  • Tài liệu CNTT
  • Liên hệ

© 2023 SinhVienCNTT.Net - Blog Sinh viên Công nghệ thông tin.