Đại số tuyến tính¶
Đại số tuyến tính là một bộ công cụ toán học rất hữu dụng trong việc biến đổi và xử lý đồng thời các nhóm số liệu. Trong đại số tuyến tính, các nhóm số liệu này được biểu diễn dưới dạng các vector và các ma trận (các bảng tính cũng là 1 dạng ma trận), đồng thời các phép cộng, trừ, nhân, chia cũng được định nghĩa lại. Phần này sẽ mô tả khái quát các khái niệm cơ bản của đại số tuyến tính, nhất là các khái niệm được sử dụng nhiều trong học máy.
Vector - Hướng lượng¶
Vector là các mảng 1 chiều chứa các số hoặc các biểu thức. Trong hình học, vector biểu thị độ lớn, phương, và chiều của một sự thay đổi (ví dụ như tác động lực) lên 1 điểm trong không gian gọi là điểm gốc. Ví dụ trong hệ toạ độ Descartes 2 chiều, vector \([3, -2]\) ám chỉ rằng từ điểm gốc ta di chuyển sang phải 3 đơn vị và đi xuống 2 đơn vị. Một vector với nhiều hơn 1 chiều được gọi là một ma trận.
Ký hiệu¶
Có rất nhiều cách để biểu diễn vector. Dưới đây là một số cách thông dụng.
Vector trong hình học¶
Vector thường biểu diễn một sự thay đổi đối với 1 điểm trong không gian hình học.
Vector \([5, -2]\) trong hệ toạ độ Descartes¶
Một vector có thể áp dụng vào bất cứ điểm nào trong không gian. Chiều của vector bằng với độ dốc của đường chéo được vẽ bởi việc di chuyển theo mô tả của vector. Ví dụ với vector \([5, -2]\) như hình minh hoạ trên, chiều của vector là đường chéo được tạo thành bằng cách di chuyển lên phía trên 5 và sang trái 2 đơn vị. Độ lớn của vector bằng với độ dài của đường chéo đó.
Các phép toán với 1 số - Scalar operations¶
Trong đại số tuyến tính, ta chỉnh sửa các vector bằng cách cộng, trừ, hay nhân 1 số với tất cả các giá trị thành phần của vector. Các phép toán này trên vector được gọi là các phép toán với 1 số.
Các phép toán theo từng phần tử - Elementwise operations¶
Đối với các phép toán giữa 2 vector trên từng phần tử như cộng, trừ, và chia, các giá trị tại cùng 1 vị trí được kết hợp với nhau để tạo ra 1 vector mới. Phần từ đầu tiên của vector A được cặp với phần tử đầu tiên của vector B. Phần từ thứ 2 của vector A được cặp với phần tử thứ 2 của vector B, và tương tự. Điều này có nghĩa là các vector phải có cùng số phần tử, hay số chiều, để có thể tham gia thực hiện các phép toán này.
y = np.array([1,2,3])
x = np.array([2,3,4])
y + x = [3, 5, 7]
y - x = [-1, -1, -1]
y / x = [.5, .67, .75]
Đoạn code trên minh hoạ các phép toán này sử dụng thư viện numpy. Tuy các phép toán này yêu cầu các vector phải có số chiều bằng nhau, trong numpy có cung cấp cơ chế broadcasting giúp các phép toán trên ma trận và vector được thực hiện dễ dàng hơn và sẽ được trình bày kỹ hơn sau.
Tích vô hướng - Dot product¶
Tích vô hướng của hai vector là một số vô hướng. Tích vô hướng gữa các vector và ma trận (phép nhân ma trận) là một trong những phép toán quan trọng nhất trong học sâu.
y = np.array([1,2,3])
x = np.array([2,3,4])
np.dot(y,x) = 20
Tích Hadamard¶
Tích Hadamard giữa 2 vector là phép nhân theo từng phần tử (elementwise multiplication) và trả về một vector.
y = np.array([1,2,3])
x = np.array([2,3,4])
y * x = [2, 6, 12]
Trường vector¶
Một trường vector là một kết cấu gán cho mỗi điểm trong không gian 1 vector tương ứng, giúp biểu diễn một điểm trong không gian \((x,y)\) sẽ di chuyển thế nào nếu ta áp dụng một phép toán vector lên điểm đó, ví dụ như cộng hay nhân 2.
Trường vector \((sin(y), sin(x))\)¶
Khác với 1 vector thông thường, trường vector tác động theo các hướng và độ lớn khác nhau phụ thuộc vào điểm gốc. Lý do vì các vector trong trường vector có dạng các biểu thức \(2x\) hay \(x^2\) thay vì các số vô hướng như \(-2\) hay \(5\). Với mỗi điểm trong đồ thị, ta tính \(2x\) hay \(x^2\) theo trục hoành và vẽ một mũi tên từ điểm gốc đó tới vị trí mới. Hình minh hoạ trên biểu diễn trường vector \((sin(y), sin(x))\). Trường vector rất hữu dụng trong việc biểu diễn một cách trực quan các kỹ thuật tối ưu trong học máy như Hạ Gradient (Gradient Descent).
Ma trận - Matrices¶
Một ma trận là một mảng hình chữ nhật chứa các số, các ký hiệu, hoặc các biểu thức (giống như một bảng tính Excel) với các quy tắc cộng, trừ, và nhân đặc biệt.
Chiều - Dimensions¶
Ta mô tả các chiều của một ma trận dưới dạng hàng và cột.
Ma trận đầu tiên có chiều \((3,2)\), hay 3 hàng 2 cột. Ma trận thứ hai có chiều \((2,3)\).
a = np.array([
[1,2,3],
[4,5,6]
])
a.shape == (2,3)
b = np.array([
[1,2,3]
])
b.shape == (1,3)
Các phép toán với 1 số¶
Các phép toán với 1 số của ma trận cũng giống như các vector, chỉ đơn giản là áp dụng phép toán với số đó cho từng phần tử của ma trận khi cộng, trừ, nhân, chia, ... một ma trận với 1 số.
# Cộng ma trận với 1 số
a = np.array(
[[1,2],
[3,4]])
a + 1
[[2,3],
[4,5]]
Các phép toán theo từng phần tử - Elementwise operations¶
Để có thể cộng, trừ, hay chia 2 ma trận thì 2 ma trận đó cần có cùng số chiều. Ta kết hợp các giá trị tương ứng theo từng vị trí để tạo ra ma trận mới.
a = np.array([
[1,2],
[3,4]])
b = np.array([
[1,2],
[3,4]])
a + b
[[2, 4],
[6, 8]]
a — b
[[0, 0],
[0, 0]]
Tích Hadamard¶
Tích Hadamard giữa các ma trận là phép nhân theo từng phần tử (elementwise multiplication). Các giá trị tương ứng theo từng vị trí được nhân với nhau và trả về một ma trận mới.
a = np.array(
[[2,3],
[2,3]])
b = np.array(
[[3,4],
[5,6]])
# Sử dụng toán tử nhân của Python
a * b
[[ 6, 12],
[10, 18]]
Trong thư viện numpy, ta có thể tính tích Hadamard của một ma trận với một vector nếu như số chiều của chúng thoả mãn điều kiện của cơ chế broadcasting.
Ma trận chuyển vị - Matrix transpose¶
Mạng nơ-ron thường xuyên phải tính toán các trọng số và đầu vào với các kích thước khác nhau và không thoả mãn điều kiện của phép nhân ma trận. Phép chuyển vị ma trận (Matrix transposition), thường được ký hiệu bằng chỉ số trên 'T' ví dụ như \(M^T\), cho phép ta "xoay" một ma trận sao cho ma trận mới tuân theo điều kiện của phép nhân ma trận và giúp việc tính toán dễ dàng hơn. Phép chuyển vị ma trận gồm 2 bước:
Xoay phải ma trận 90°
Đảo thứ tự của mỗi phần tử tại mỗi hàng (ví dụ, \([a\ b\ c]\) thành \([c\ b\ a]\))
Ví dụ sau đảo ma trận \(M\) thành ma trận \(T\):
a = np.array([
[1, 2],
[3, 4]])
a.T
[[1, 3],
[2, 4]]
Nhân ma trận¶
Không phải tất cả các ma trận đều có thể nhân được với nhau. Để thực hiện phép nhân các ma trận với nhau và tạo thành ma trận mới, cần thoả mãn các điều kiện sau:
Điều kiện
Số cột của ma trận thứ nhất phải bằng với số hàng của ma trận thứ 2.
Tích của một ma trận kích thước M x N và một ma trận kích thước N x K là một ma trận kích thước M x K, tức là số chiều của ma trận mới là số hàng của ma trận đầu tiên và số cột của ma trận thứ 2.
Các bước nhân ma trận
Phép nhân ma trận phụ thuộc vào tích vô hướng giữa các hàng và cột của 2 ma trận ban đầu. Trong hình minh hoạ ở dưới, được trích từ khoá học về đại số tuyến tính trên Khan Academy 3, mỗi phần tử của ma trận \(C\) là một tích vô hướng của một hàng của ma trận \(A\) và một cột của ma trận \(B\).
Thao tác \(a_1 \cdot b_1\) nghĩa là ta tính tích vô hướng giữa hàng đầu tiên của ma trận \(A\) \([1,7]\) với cột đầu tiên của ma trận \(B\) \([3,5]\).
Thư viện Numpy¶
Tích vô hướng¶
Thư viện numpy sử dụng hàm np.dot(A,B) cho cả phép nhân ma trận và vector.
Hàm này có một số chức năng khá hay à bạn đọc có thể tham khảo thêm tại đây để sử dụng hiệu quả hơn.
a = np.array([
[1, 2]
])
a.shape == (1,2)
b = np.array([
[3, 4],
[5, 6]
])
b.shape == (2,2)
# Nhân ma trận
mm = np.dot(a,b)
mm == [13, 16]
mm.shape == (1,2)
Cơ chế Broadcasting¶
Trong numpy, các yêu cầu về chiều trong phép nhân từng phân tử khá thoải mái nhờ một cơ chế có tên gọi broadcasting. Hai ma trận được coi là phù hợp nếu các chiều tương ứng của mỗi ma trận (hàng với hàng, hoặc cột với cột) thoả mãn một trong 2 điều kiện sau:
Tất cả các số chiều là bằng nhau, hoặc
Có 1 chiều có kích thước bằng 1
a = np.array([
[1],
[2]
])
b = np.array([
[3,4],
[5,6]
])
c = np.array([
[1,2]
])
# Có cùng số hàng
# Nhưng khác số cột
# Tuy nhiên vẫn nhân từng phần tử được do số cột của a bằng 1
a * b
[[ 3, 4],
[10, 12]]
# Có cùng số cột
# Nhưng khác số hàng
# Tuy nhiên vẫn nhân từng phần tử được do số hàng của c bằng 1
b * c
[[ 3, 8],
[5, 12]]
# Khác số hàng
# Khác số hàng
# Nhưng cả a và c đều thoả mãn điều kiện
# có kích thước 1 chiều bằng 1
a + c
[[2, 3],
[3, 4]]
Một số tài liệu hướng dẫn về đại số tuyến tính
Tài liệu tham khảo