Skip to content

Latest commit

 

History

History
1705 lines (1348 loc) · 75 KB

geometry-linear-algebric-ops_vn.md

File metadata and controls

1705 lines (1348 loc) · 75 KB

Các phép toán Hình Học và Đại Số Tuyến Tính

🏷️sec_geometry-linear-algebric-ops

Trong :numref:sec_linear-algebra, chúng ta đã đề cập tới những kiến thức cơ bản trong đại số tuyến tính và cách nó được dùng để thể hiện các phép biến đổi dữ liệu cơ bản. Đại số tuyến tính là một trong những trụ cột toán học chính hỗ trợ học sâu và rộng hơn là học máy. Trong khi :numref:sec_linear-algebra chứa đựng đầy đủ kiến thức cần thiết cho các mô hình học sâu hiện đại, vẫn còn rất nhiều điều cần thảo luận trong lĩnh vực này. Trong mục này, chúng ta sẽ đi sâu hơn, nhấn mạnh một số diễn giải hình học của các phép toán đại số tuyến tính, và giới thiệu một vài khái niệm cơ bản, bao gồm trị riêng và vector riêng.

Ý nghĩa hình học của Vector

Trước hết, chúng ta cần thảo luận hai diễn giải hình học phổ biến của vector: điểm hoặc hướng trong không gian. Về cơ bản, một vector là một danh sách các số giống như danh sách trong Python dưới đây:

v = [1, 7, 0, 1]

Các nhà toán học thường viết chúng dưới dạng một vector cột hoặc hàng, tức:

$$ \mathbf{x} = \begin{bmatrix}1\7\0\1\end{bmatrix}, $$

hoặc

$$ \mathbf{x}^\top = \begin{bmatrix}1 & 7 & 0 & 1\end{bmatrix}. $$

Những biểu diễn này thường có những cách diễn giải khác nhau. Các điểm dữ liệu được biểu diễn bằng các vector cột và các trọng số dùng trong các tổng có trọng số được biểu diễn bằng các vector hàng. Tuy nhiên, việc linh động sử dụng các cách biểu diễn này mang lại nhiều lợi ích. Ma trận là những cấu trúc dữ liệu hữu ích: chúng cho phép chúng ta tổ chức dữ liệu với nhiều biến thể khác nhau. Ví dụ, các hàng của ma trận có thể tương ứng với các nhà (điểm dữ liệu) khác nhau, trong khi các cột có thể tương ứng với các thuộc tính khác nhau. Việc này nghe quen thuộc nếu bạn từng sử dụng các phần mềm dạng bảng (spreadsheet) hoặc đã từng đọc :numref:sec_pandas. Bởi vậy, mặc dù chiều mặc định của một vector là một vector cột, trong một ma trận biểu diễn một tập dữ liệu dạng bảng, sẽ thuận tiện hơn khi coi mỗi điểm dữ liệu là một vector hàng trong ma trận đó. Và như chúng ta sẽ thấy trong các chương sau, cách biểu diễn này phù hợp với cách triển khai các mô hình học sâu. Lấy ví dụ, dọc theo trục ngoài cùng của một ndarray, ta có thể truy cập hoặc đếm số minibatch chứa điểm dữ liệu, hoặc chỉ đơn giản là các điểm dữ liệu nếu minibatch không tồn tại.

Cách thứ nhất để giải thích một vector là coi nó như một điểm trong không gian. Trong không gian hai hoặc ba chiều, chúng ta có thể biểu diễn các điểm này bằng việc sử dụng các thành phần của vector để định nghĩa vị trí của điểm trong không gian so với một điểm tham chiều được gọi là gốc tọa độ. Xem :numref:fig_grid.

Mô tả việc biểu diễn vector như các điểm trong mặt phẳng. Thành phần thứ nhất của vector là tọa độ $x$, thành phần thứ hai là tọa độ $y$. Tương tự với số chiều cao hơn, mặc dù khó hình dung hơn 🏷️fig_grid

Góc nhìn hình học này cho phép chúng ta xem xét bài toán ở một mức trừu tượng hơn. Không giống như khi đối mặt với các bài toán khó hình dung như phân loại ảnh chó mèo, chúng ta có thể bắt đầu xem xét các bài toán này một cách trừu tượng hơn như là một tập hợp của các điểm trong không gian. Việc phân loại ảnh chó mèo có thể coi như việc tìm ra cách phân biệt hai nhóm điểm riêng biệt trong không gian.

Cách thứ hai để giải thích một vector là coi nó như một hướng trong không gian. Chúng ta không những có thể coi vector $\mathbf{v} = [2,3]^\top$ là một điểm nằm bên phải $2$ đơn vị và bên trên $3$ đơn vị so với gốc toạ độ, chúng ta cũng có thể coi nó thể hiện một hướng -- hướng $2$ bước về bên phải và $3$ bước lên trên. Theo cách này, ta coi tất cả các vector trong hình :numref:fig_arrow là như nhau.

Bất kỳ vector nào cũng có thể biểu diễn bằng một mũi tên trong mặt phẳng. Trong trường hợp này, mọi vector trong hình đều biểu diễn vector $(2,3)$. 🏷️fig_arrow

Một trong những lợi ý của việc chuyển cách hiểu này là phép cộng vector có thể được hiểu theo nghĩa hình học. Cụ thể, chúng ta đi theo một hướng được cho bởi một vector, sau đó đi theo một hướng cho bởi một vector khác, như được cho trong :numref:fig_add-vec.

Phép cộng vector có thể biểu diễn bằng cách đầu tiên đi theo một vector, sau đó đi theo vector kia. 🏷️fig_add-vec

Hiệu của hai vector có một cách diễn giải tương tự. Bằng cách biểu diễn $\mathbf{u} = \mathbf{v} + (\mathbf{u}-\mathbf{v})$, ta thấy rằng vector $\mathbf{u}-\mathbf{v}$ là hướng mang điểm $\mathbf{u}$ tới điểm $\mathbf{v}$.

Tích vô hướng và Góc

Như đã thấy trong :numref:sec_linear-algebra, tích vô hướng của hai vector cột $\mathbf{u}$$\mathbf{v}$ có thể được tính bởi:

$$\mathbf{u}^\top\mathbf{v} = \sum_i u_i\cdot v_i.$$ :eqlabel:eq_dot_def

Vì biểu thức :eqref:eq_dot_def đối xứng, chúng ta có thể viết:

$$ \mathbf{u}\cdot\mathbf{v} = \mathbf{u}^\top\mathbf{v} = \mathbf{v}^\top\mathbf{u}, $$

để nhấn mạnh rằng phép đổi chỗ hai vector sẽ cho kết quả như nhau.

Tích vô hướng :eqref:eq_dot_def cũng có diễn giải hình học: nó liên quan mật thiết tới góc giữa hai vector. Xem góc hiển thị trong :numref:fig_angle.

Có một định nghĩa về góc ($\theta$) giữa hai vector bất kỳ trong không gian. Ta sẽ thấy rằng góc này có liên hệ chặt chẽ tới tích vô hướng. 🏷️fig_angle

Xét hai vector:

$$ \mathbf{v} = (r,0) ; \text{and} ; \mathbf{w} = (s\cos(\theta), s \sin(\theta)). $$

Vector $\mathbf{v}$ có độ dài $r$ và song song với trục $x$, vector $\mathbf{w}$ có độ dài $s$ và tạo một góc $\theta$ với trục $x$. Nếu tính tích vô hướng của hai vector này, ta sẽ thấy rằng

$$ \mathbf{v}\cdot\mathbf{w} = rs\cos(\theta) = |\mathbf{v}||\mathbf{w}|\cos(\theta). $$

Với một vài biến đổi đơn giản, chúng ta có thể sắp xếp lại các thành phần để được

$$ \theta = \arccos\left(\frac{\mathbf{v}\cdot\mathbf{w}}{|\mathbf{v}||\mathbf{w}|}\right). $$

Một cách ngắn gọn, với hai vector cụ thể này, tích vô hướng kết hợp với chuẩn thể hiện góc giữa hai vector. Việc này cũng đúng trong trường hợp tổng quát. Ta sẽ không viết biểu diễn ở đây, tuy nhiên, nếu viết $|\mathbf{v} - \mathbf{w}|^2$ bằng hai cách: cách thứ nhất với tích vô hướng, và cách thứ hai sử dụng công thức tính cos, ta có thể thấy được quan hệ giữa chúng. Thật vậy, với hai vector $\mathbf{v}$$\mathbf{w}$ bất kỳ, góc giữa chúng là

$$\theta = \arccos\left(\frac{\mathbf{v}\cdot\mathbf{w}}{|\mathbf{v}||\mathbf{w}|}\right).$$ :eqlabel:eq_angle_forumla

Kết quả này tổng quát cho không gian nhiều chiều vì nó không sử dụng điều gì đặc biệt trong không gian hai chiều.

Xét ví dụ đơn giản tính góc giữa cặp vector:

%matplotlib inline
from d2l import mxnet as d2l
from IPython import display
from mxnet import gluon, np, npx
npx.set_np()

def angle(v, w):
    return np.arccos(v.dot(w) / (np.linalg.norm(v) * np.linalg.norm(w)))

angle(np.array([0, 1, 2]), np.array([2, 3, 4]))

Chúng ta sẽ không sử dụng đoạn mã này bây giờ, nhưng sẽ hữu ích để biết rằng nếu góc giữa hai vector là $\pi/2$ (hay $90^{\circ}$) thì hai vector đó được gọi là trực giao. Xem xét kỹ biểu thức trên, ta thấy rằng việc này xảy ra khi $\theta = \pi/2$, tức $\cos(\theta) = 0$. Điều này chứng tỏ tích vô hướng phải bằng không, và hai vector là trực giao nếu và chỉ nếu $\mathbf{v}\cdot\mathbf{w} = 0$. Đẳng thức này sẽ hữu ích khi xem xét các đối tượng dưới con mắt hình học.

Ta sẽ tự hỏi tại sao tính góc lại hữu ích? Câu trả lời nằm ở tính bất biến ta mong đợi từ dữ liệu. Xét một bức ảnh, và một bức ảnh thứ hai giống hệt nhưng với các điểm ảnh với độ sáng chỉ bằng $10%$ ảnh ban đầu. Giá trị của từng điểm ảnh trong ảnh thứ hai nhìn chung khác xa so với ảnh ban đầu. Bởi vậy, nếu tính khoảng cách giữa ảnh ban đầu và ảnh tối hơn, khoảng cách có thể rất lớn. Tuy nhiên, trong hầu hết các ứng dụng ML, nội dung của hai bức ảnh là như nhau -- nó vẫn là một bức ảnh của một con mèo đối với một bộ phân loại chó mèo. Tuy nhiên, nếu xem xét góc giữa hai ảnh, không khó để thấy rằng với bất kỳ vector $\mathbf{v}$, góc giữa $\mathbf{v}$$0.1\cdot\mathbf{v}$ bằng không. Việc này tương ứng với việc nhân vector với một số (dương) giữ nguyên hướng và chỉ thay đổi độ dài của vector đó. Khi xét tới góc, hai bức ảnh được coi là như nhau.

Ví dụ tương tự có thể tìm thấy bất cứ đâu. Trong văn bản, chúng ta có thể muốn chủ đề được thảo luận không thay đổi nếu chúng ta viết văn bản dài gấp hai nhưng nói về cùng một thứ. Trong một số cách mã hóa (như đếm số lượng xuất hiện của một từ trong từ điển), việc này tương đương với nhân đôi vector mã hóa của văn bản, bởi vậy chúng ta lại có thể sử dụng góc.

Độ tương tự cosin

Trong văn cảnh học máy với góc được dùng để chỉ khoảng cách giữa hai vector, người làm ML sử dụng thuật ngữ độ tương tự cosin để chỉ đại lượng

$$ \cos(\theta) = \frac{\mathbf{v}\cdot\mathbf{w}}{|\mathbf{v}||\mathbf{w}|}. $$

Hàm cosin lấy giá trị lớn nhất bằng $1$ khi hai vector chỉ cùng một hướng, giá trị nhỏ nhất bằng $-1$ khi chúng cùng phương khác hướng, và $0$ khi hai vector trực giao. Chú ý rằng nếu các thành phần của hai vector nhiều chiều được lấy mẫu ngẫu nhiên với kỳ vọng $0$, cosin giữa chúng sẽ luôn gần với $0$.

Siêu phẳng

Ngoài việc làm việc với vector, một khái niệm quan trọng khác bạn phải nắm vững khi đi sâu vào đại số tuyến tính là siêu phẳng, một khái niệm tổng quát của đường thẳng (trong không gian hai chiều) hoặc một mặt phẳng (trong không gian ba chiều). Trong một không gian vector $d$ chiều, một siêu phẳng có $d-1$ chiều và chia không gian thành hai nửa không gian.

Xét ví dụ sau. Giả sử ta có một vector cột $\mathbf{w}=[2,1]^\top$. Ta muốn biết "tập hợp những điểm $\mathbf{v}$ sao cho $\mathbf{w}\cdot\mathbf{v} = 1$?" Sử dụng mối quan hệ giữa tích vô hướng và góc ở :eqref:eq_angle_forumla ở trên, ta có thể thấy điều này tương đương với

$$ |\mathbf{v}||\mathbf{w}|\cos(\theta) = 1 ; \iff ; |\mathbf{v}|\cos(\theta) = \frac{1}{|\mathbf{w}|} = \frac{1}{\sqrt{5}}. $$

Nhắc lại trong lượng giác, chúng ta coi $|\mathbf{v}|\cos(\theta)$ là độ dài hình chiếu của vector $\mathbf{v}$ lên hướng của vector $\mathbf{w}$ 🏷️fig_vector-project

Nếu xem xét ý nghĩa hình học của biểu diễn này, chúng ta thấy rằng việc này tương đương với việc độ dài hình chiếu của $\mathbf{v}$ lên hướng của $\mathbf{w}$ chính là $1/|\mathbf{w}|$ như được biểu diễn trong :numref:fig_vector-project. Tập hợp các điểm thỏa mãn điều kiện này là một đường thẳng vuông góc với vector $\mathbf{w}$. Ta có thể tìm được phương trình của đường thẳng này là $2x + y = 1$ hoặc $y = 1 - 2x$.

Tiếp theo, nếu tự hỏi về tập hợp các điểm thỏa mãn $\mathbf{w}\cdot\mathbf{v} > 1$ hoặc $\mathbf{w}\cdot\mathbf{v} < 1$, ta có thể thấy rằng đây là những trường hợp mà hình chiếu của chúng lên $\mathbf{w}$ lần lượt dài hơn hoặc ngắn hơn $1/|\mathbf{w}|$. Vì thế, hai bất phương trình này định nghĩa hai phía của đường thẳng. Bằng cách này, ta có thể cắt mặt phẳng thành hai nửa: một nửa chứa tất cả điểm có tích vô hướng nhỏ hơn một mức ngưỡng và nửa còn lại chứa những điểm có tích vô hướng lớn hơn mức ngưỡng đó. Xem hình :numref:fig_space-division.

Nếu nhìn từ dạng bất phương trình, ta thấy rằng siêu phẳng (chỉ là một đường thẳng trong trường hợp này) chia không gian ra thành hai nửa. 🏷️fig_space-division

Tương tự với không gian đa chiều. Nếu lấy $\mathbf{w} = [1,2,3]^\top$ và đi tìm các điểm trong không gian ba chiều với $\mathbf{w}\cdot\mathbf{v} = 1$, ta có một mặt phẳng vuông góc với vectơ cho trước $\mathbf{w}$. Hai bất phương trình một lần nữa định nghĩa hai phía của mặt bẳng như trong hình :numref:fig_higher-division.

Siêu phẳng trong bất kỳ không gian nào chia không gian đó ra thành hai nửa 🏷️fig_higher-division

Mặc dù không thể minh hoạ trong không gian nhiều chiều hơn, ta vẫn có thể tổng quát điều này cho không gian mười, một trăm hay một tỷ chiều. Việc này thường xuyên xảy ra khi nghĩ về các mô hình học máy. Chẳng hạn, ta có thể hiểu các mô hình phân loại tuyến tính trong :numref:sec_softmax cũng giống như những phương pháp đi tìm siêu phẳng để phân chia các lớp mục tiêu khác nhau. Ở trường hợp này, những siêu phẳng như trên thường được gọi là mặt phẳng quyết định. Phần lớn các mô hình phân loại tìm được qua học sâu đều kết thúc bởi một tầng tuyến tính và theo sau là một tầng softmax, bởi vậy ta có thể diễn giải ý nghĩa của mạng nơ-ron sâu giống như việc tìm một embedding phi tuyến sao cho các lớp mục tiêu có thể được phân chia bởi các siêu phẳng một cách gọn gàng.

Xét ví dụ sau. Chú ý rằng, ta có thể tạo một mô hình đủ tốt để phân loại những bức ảnh nhỏ xíu có áo thun và quần từ tập dữ liệu Fashion MNIST (Xem :numref:sec_fashion_mnist) bằng cách lấy vector giữa điểm trung bình của mỗi lớp để định nghĩa một mặt phẳng quyết định và chọn thủ công một ngưỡng. Trước tiên, chúng ta tải dữ liệu và tính hai ảnh trung bình:

# Load in the dataset
train = gluon.data.vision.FashionMNIST(train=True)
test = gluon.data.vision.FashionMNIST(train=False)

X_train_0 = np.stack([x[0] for x in train if x[1] == 0]).astype(float)
X_train_1 = np.stack([x[0] for x in train if x[1] == 1]).astype(float)
X_test = np.stack(
    [x[0] for x in test if x[1] == 0 or x[1] == 1]).astype(float)
y_test = np.stack(
    [x[1] for x in test if x[1] == 0 or x[1] == 1]).astype(float)

# Compute averages
ave_0 = np.mean(X_train_0, axis=0)
ave_1 = np.mean(X_train_1, axis=0)

Để có cái nhìn rõ hơn, ta có thể biểu diễn các ảnh trung bình này. Trong trường hợp này, chúng ta thấy rằng ảnh trung bình của áo thun cũng ở dạng một phiên bản mờ của một chiếc áo thun.

# Plot average t-shirt
d2l.set_figsize()
d2l.plt.imshow(ave_0.reshape(28, 28).tolist(), cmap='Greys')
d2l.plt.show()

Trong trường hợp thứ hai, chúng ta cũng thấy ảnh trung bình có dạng một ảnh phiên bản mờ một chiếc quần dài.

# Plot average trousers
d2l.plt.imshow(ave_1.reshape(28, 28).tolist(), cmap='Greys')
d2l.plt.show()

Trong lời giải học máy hoàn chỉnh, ta sẽ học được mức ngưỡng từ tập dữ liệu. Trong trường hợp này, tôi chỉ đơn giản chọn thủ công một ngưỡng mà cho kết quả khá tốt trên tập huấn luyện.

# Print test set accuracy with eyeballed threshold
w = (ave_1 - ave_0).T
predictions = X_test.reshape(2000, -1).dot(w.flatten()) > -1500000

# Accuracy
np.mean(predictions.astype(y_test.dtype) == y_test, dtype=np.float64)

Ý nghĩa hình học của các Phép biến đổi Tuyến tính

Thông qua :numref:sec_linear-algebra và các thảo luận phía trên, ta có một cái nhìn trọn vẹn về ý nghĩa hình học của vector, độ dài, và góc. Tuy nhiên, có một khái niệm quan trọng chúng ta đã bỏ qua, đó là ý nghĩa hình học của các phép biến đổi tuyến tính thể hiện bởi các ma trận. Hiểu một cách đầy đủ cách ma trận được dùng để biến đổi dữ liệu giữa hai không gian nhiều chiều khác nhau cần một lượng thực hành đáng kể và nằm ngoài phạm vi của phần phụ lục này. Tuy nhiên, chúng ta có thể xây dựng ý niệm trong không gian hai chiều.

Giả sử ta có một ma trận:

$$ \mathbf{A} = \begin{bmatrix} a & b \ c & d \end{bmatrix}. $$

Nếu muốn áp dụng ma trận này vào một vector bất kỳ $\mathbf{v} = [x, y]^\top$, ta thực hiện phép nhân và thấy rằng

$$ \begin{aligned} \mathbf{A}\mathbf{v} & = \begin{bmatrix}a & b \ c & d\end{bmatrix}\begin{bmatrix}x \ y\end{bmatrix} \\ & = \begin{bmatrix}ax+by\ cx+dy\end{bmatrix} \\ & = x\begin{bmatrix}a \ c\end{bmatrix} + y\begin{bmatrix}b \d\end{bmatrix} \\ & = x\left{\mathbf{A}\begin{bmatrix}1\0\end{bmatrix}\right} + y\left{\mathbf{A}\begin{bmatrix}0\1\end{bmatrix}\right}. \end{aligned} $$

Thoạt nhìn đây là một phép tính khá kỳ lạ, nó biến một thứ vốn rõ ràng thành một thứ khó hiểu. Tuy nhiên, điều này cho ta thấy cách một ma trận biến đổi bất kỳ vector nào thông qua cách nó biến đổi hai vector cụ thể: $[1,0]^\top$$[0,1]^\top$. Quan sát một chút, chúng ta thực tế đã thu gọn một bài toán vô hạn (tính toán cho bất kỳ vector nào) thành một bài toán hữu hạn (tính toán cho chỉ hai vector). Hai vector này còn có tên gọi khác là vector cơ sở - có nghĩa là vector bất kỳ nào trong không gian đều có thể biểu diễn dưới dạng tổng có trọng số của những vector này.

Cùng xét ví dụ với một ma trận cụ thể

$$ \mathbf{A} = \begin{bmatrix} 1 & 2 \\ -1 & 3 \end{bmatrix}. $$

Xét vector $\mathbf{v} = [2, -1]^\top$, ta thấy rằng vector này chính bằng $2\cdot[1,0]^\top + -1\cdot[0,1]^\top$, và bởi vậy ta biết ma trận $A$ sẽ biến đổi nó thành $2(\mathbf{A}[1,0]^\top) + -1(\mathbf{A}[0,1])^\top = 2[1, -1]^\top - [2,3]^\top = [0, -5]^\top$. Bằng cách xem lưới của tất cả các điểm có tọa độ nguyên, ta có thể thấy rằng phép nhân ma trận có thể làm xiên, xoay và co giãn lưới đó, nhưng cấu trúc của lưới phải giữ nguyên như trong :numref:fig_grid-transform.

Ma trận $\mathbf{A}$ biến đổi các vector cơ sở cho trước. Hãy chú ý việc toàn bộ lưới cũng bị biến đổi theo như thế nào. 🏷️fig_grid-transform

Đây là điểm quan trọng nhất để hình dung các phép biến đổi tuyến tính thông qua ma trận. Ma trận không thể làm biến dạng một vài phần của không gian khác với các phần khác. Chúng chỉ có thể lấy các tọa độ ban đầu và làm xiên, xoay và co giãn chúng.

Một vài phép biển đổi có thể rất kỳ dị. Chẳng hạn ma trận

$$ \mathbf{B} = \begin{bmatrix} 2 & -1 \ 4 & -2 \end{bmatrix}, $$

nén toàn bộ mặt phẳng hai chiều thành một đường thẳng. Xác định và làm việc với các phép biến đổi này là chủ đề của phần sau, nhưng nhìn trên khía cạnh hình học, ta có thể thấy rằng điều này cơ bản khác so với các phép biến đổi ở trên. Ví dụ, kết quả từ ma trận $\mathbf{A}$ có thể bị "bẻ cong lại" thành dạng ban đầu. Kết quả từ ma trận $\mathbf{B}$ thì không thể vì sẽ không thể biết vector $[1,2]^\top$ đến từ đâu -- từ $[1,1]^\top$ hay $[0, -1]^\top$?

Trong khi hình vẽ này áp dụng cho ma trận $2\times2$, kết quả tương tự cũng có thể được mở rộng cho ma trận bậc cao hơn. Nếu chúng ta lấy các vector cơ sở như $[1,0, \ldots,0]$ và xem ma trận đó biến đổi các vector này như thế nào, ta có thể phần nào hình dung được phép nhân ma trận đã làm biến dạng toàn bộ không gian đa chiều như thế nào.

Phụ thuộc Tuyến tính

Quay lại với ma trận

$$ \mathbf{B} = \begin{bmatrix} 2 & -1 \ 4 & -2 \end{bmatrix}. $$

Ma trận này nén toàn bộ mặt phẳng xuống thành một đường thằng $y = 2x$. Câu hỏi đặt ra là: có cách nào phát hiện ra điều này nếu chỉ nhìn vào ma trận? Câu trả lời là có thể. Đặt $\mathbf{b}_1 = [2,4]^\top$$\mathbf{b}_2 = [-1, -2]^\top$ là hai cột của $\mathbf{B}$. Nhắc lại rằng chúng ta có thể viết bất cứ vector nào được biến đổi bằng ma trận $\mathbf{B}$ dưới dạng tổng có trọng số các cột của ma trận này, chẳng hạn $a_1\mathbf{b}_1 + a_2\mathbf{b}_2$. Tổng này được gọi là tổ hợp tuyến tính (linear combination). Vì $\mathbf{b}_1 = -2\cdot\mathbf{b}_2$, ta có thể viết tổ hợp bất kỳ của hai cột này mà chỉ dùng $\mathbf{b}_2$:

$$ a_1\mathbf{b}_1 + a_2\mathbf{b}_2 = -2a_1\mathbf{b}_2 + a_2\mathbf{b}_2 = (a_2-2a_1)\mathbf{b}_2. $$

Điều này chỉ ra rằng một trong hai cột là dư thừa vì nó không định nghĩa một hướng độc nhất trong không gian. Việc này cũng không quá bất ngờ bởi vì ma trận này đã biến toàn bộ mặt phẳng xuống thành một đường thẳng. Hơn nữa, điều này có thể được nhận thấy do hai cột trên phụ thuộc tuyến tính $\mathbf{b}_1 = -2\cdot\mathbf{b}_2$. Để thấy sự đối xứng giữa hai vector này, ta sẽ viết dưới dạng

$$ \mathbf{b}_1 + 2\cdot\mathbf{b}_2 = 0. $$

Tổng quát, ta sẽ nói rằng: một tập hợp các vector $\mathbf{v}_1, \ldots \mathbf{v}_k$phụ thuộc tuyến tính nếu tồn tại các hệ số $a_1, \ldots, a_k$ không đồng thời bằng không sao cho

$$ \sum_{i=1}^k a_i\mathbf{v_i} = 0. $$

Trong trường hợp này, ta có thể biểu diễn một vector dưới dạng một tổ hợp nào đó của các vector khác, điều này khiến cho sự tồn tại của nó trở nên dư thừa. Bởi vậy, sự phụ thuộc tuyến tính giữa các cột của một ma trận là một bằng chứng cho thấy ma trận đó đang làm giảm số chiều không gian. Nếu không có sự phụ thuộc tuyến tính, chúng ta nói rằng các vector này độc lập tuyến tính (linearly independent). Nếu các cột của một ma trận là độc lập tuyến tính, không có việc nén nào xảy ra và phép toán này có thể đảo ngược (khả nghịch) được.

Hạng

Với một ma trận tổng quát $n\times m$, câu hỏi tự nhiên được đặt ra là ma trận đó ánh xạ vào không gian có bao nhiêu chiều. Để trả lời cho câu hỏi này, ta dùng khái niệm hạng (rank). Trong mục trước, chúng ta lưu ý rằng một hệ phụ thuộc tuyến tính nén không gian xuống một không gian khác với số chiều thấp hơn. Chúng ta sẽ sử dụng tính chất này để định nghĩa hạng. Cụ thể, hạng của một ma trận $\mathbf{A}$ là số lượng lớn nhất các cột độc lập tuyến tính trong mọi tập con các cột của ma trận đó. Ví dụ, ma trận

$$ \mathbf{B} = \begin{bmatrix} 2 & 4 \ -1 & -2 \end{bmatrix}, $$

$\mathrm{rank}(B)=1$ vì hai cột của nó là phụ thuộc tuyến tính và bản thân mỗi cột là không phụ thuộc tuyến tính. Xét một ví dụ phức tạp hơn

$$ \mathbf{C} = \begin{bmatrix} 1& 3 & 0 & -1 & 0 \\ -1 & 0 & 1 & 1 & -1 \\ 0 & 3 & 1 & 0 & -1 \\ 2 & 3 & -1 & -2 & 1 \end{bmatrix}, $$

Ta có thể chứng minh được $\mathbf{C}$ có hạng bằng hai, bởi hai cột đầu tiên là độc lập tuyến tính, trong khi tập hợp ba cột bất kỳ trong ma trận đều phụ thuộc tuyến tính.

Quá trình được mô tả ở trên rất không hiệu quả. Nó đòi hỏi xét mọi tập con các cột của một ma trận cho trước, số tập con này tăng theo hàm mũ khi số cột tăng lên. Sau này chúng ta sẽ thấy một cách hiệu quả hơn để tính hạng của ma trận, nhưng bây giờ những gì được nói đến ở trên là đủ để hiểu khái niệm và ý nghĩa của hạng.

Tính nghịch đảo (khả nghịch)

Như chúng ta đã thấy ở trên, phép nhân một ma trận có các cột phụ thuộc tuyến tính là không thể hoàn tác, tức là không tồn tại thao tác đảo nào có thể khôi phục lại đầu vào. Tuy nhiên, nhân một ma trận hạng đầy đủ (ví dụ, một ma trận $\mathbf{A}$ kích thước $n \times n$ nào đó với hạng $n$), chúng ta luôn có thể hoàn tác nó. Xét ma trận

$$ \mathbf{I} = \begin{bmatrix} 1 & 0 & \cdots & 0 \\ 0 & 1 & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & 1 \end{bmatrix}. $$

đây là ma trận với các phần tử trên đường chéo có giá trị 1 và các phẩn tử còn lại có giá trị 0. Ma trận này được gọi là ma trận đơn vị. �Dữ liệu sẽ không bị thay đổi khi nhân với ma trận này. Để có một ma trận hoàn tác những gì ma trận $\mathbf{A}$ đã làm, ta tìm một ma trận $\mathbf{A}^{-1}$ sao cho

$$ \mathbf{A}^{-1}\mathbf{A} = \mathbf{A}\mathbf{A}^{-1} = \mathbf{I}. $$

Nếu coi đây là một hệ phương trình, ta có $n \times n$ biến (các giá trị của $\mathbf{A}^{-1}$) và $n \times n$ phương trình (đẳng thức cần thỏa mãn giữa mỗi giá trị của tích $\mathbf{A}^{-1}\mathbf{A}$ và giá trị tương ứng của $\mathbf{I}$) nên nhìn chung hệ phương trình có nghiệm. Thật vậy, phần tiếp theo sẽ giới thiệu một đại lượng được gọi là định thức với tính chất: nghiệm tồn tại khi đại lượng này khác 0. Ma trận $\mathbf{A}^{-1}$ như vậy được gọi là ma trận nghịch đảo. Ví dụ, nếu $\mathbf{A}$ là ma trận $2 \times 2$

$$ \mathbf{A} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}, $$

thì nghịch đảo của ma trận này là

$$ \frac{1}{ad-bc} \begin{bmatrix} d & -b \\ -c & a \end{bmatrix}. $$

Việc này có thể kiểm chứng bằng công thức ma trận nghịch đảo trình bày ở trên.

M = np.array([[1, 2], [1, 4]])
M_inv = np.array([[2, -1], [-0.5, 0.5]])
M_inv.dot(M)

Vấn đề tính toán

While the inverse of a matrix is useful in theory, we must say that most of the time we do not wish to use the matrix inverse to solve a problem in practice. In general, there are far more numerically stable algorithms for solving linear equations like -->

Mặc dù ma trận nghịch đảo khá hữu dụng trong lý thuyết, chúng ta nên tránh sử dụng chúng khi giải quyết các bài toán thực tế. Nhìn chung, có rất nhiều phương pháp tính toán ổn định hơn trong việc giải các phương trình tuyến tính dạng

$$ \mathbf{A}\mathbf{x} = \mathbf{b}, $$

so với việc tính ma trận nghịch đảo và thực hiện phép nhân để có

$$ \mathbf{x} = \mathbf{A}^{-1}\mathbf{b}. $$

Giống như việc thực hiện phép chia một số nhỏ có thể dẫn đến sự mất ổn định tính toán, việc nghịch đảo một ma trận gần với hạng thấp cũng đưa lại hệ quả tương tự.

Thêm vào đó, thông thường ma trận $\mathbf{A}$ là ma trận thưa (sparse), có nghĩa là nó chỉ chứa một số lượng nhỏ các số khác 0. Nếu thử một vài ví dụ, chúng ta có thể thấy điều này không có nghĩa ma trận nghịch đảo cũng là một ma trận thưa. Kể cả khi ma trận A là ma trận $1$ triệu nhân $1$ triệu với chỉ $5$ triệu giá trị khác 0 (có nghĩa là chúng ta chỉ cần lưu trữ $5$ triệu giá trị đó), ma trận nghịch đảo vẫn hầu như có tất cả các thành phần không âm và đòi hỏi chúng ta phải lưu trữ 1\text{M}^2$ phần tử---tương đương với $1$ nghìn tỉ phần tử!

Mặc dù không đủ thời gian để đi sâu vào các vấn đề tính toán phức tạp thường gặp khi làm việc với đại số tuyến tính, chúng tôi vẫn mong muốn có thể cung cấp một vài lưu ý, và quy tắc chung trong thực hành là hạn chế việc tính nghịch đảo.

Định thức

The geometric view of linear algebra gives an intuitive way to interpret a a fundamental quantity known as the determinant. Consider the grid image from before, but now with a highlighted region (:numref:fig_grid-filled). -->

Góc nhìn hình học của đại số tuyến tính cung cấp một cái nhìn trực quan để diễn giải một đại lượng cơ bản được gọi là định thức. Xét hình lưới trước đây với một vùng được tô màu (:numref:fig_grid-filled).

Ma trận $\mathbf{A}$ vẫn làm biến dạng lưới. Lần này, tôi muốn dồn sự chú ý vào điều đã xảy ra với hình vuông được tô màu. 🏷️fig_grid-filled

Cùng nhìn vào hình vuông được tô màu. Đây là một hình vuông có diện tích bằng một với các cạnh được tạo bởi $(0, 1)$$(1, 0)$. Sau khi ma trận $\mathbf{A}$ biến đổi hình vuông này, ta thấy rằng nó trở thành một hình bình hành. Không có lý do nào để nói hình bình hành này có cùng diện tích với hình vuông, và trong trường hợp đặc biệt này

$$ \mathbf{A} = \begin{bmatrix} 1 & -1 \\ 2 & 3 \end{bmatrix}, $$

bạn có thể tính được diện tích hình bình hành bằng $5$ như một bài tập hình học tọa độ nhỏ.

Tổng quát, nếu ta có một ma trận

$$ \mathbf{A} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}, $$

với một vài phép tính, ta có thể thấy rằng diện tích của hình bình hành là $ad-bc$. Diện tích này được coi là định thức.

Cùng kiểm tra nhanh điều này với một đoạn mã ví dụ.

import numpy as np
np.linalg.det(np.array([[1, -1], [2, 3]]))

Không khó để nhận ra rằng biểu thức này có thể bằng không hoặc thậm chí âm. Khi biểu thức này âm, đó là quy ước thường dùng trong toán học: nếu ma trận đó "lật" một hình, ta nói diện tính bị đảo dấu. Còn khi định thức bằng không thì sao?

Xét

$$ \mathbf{B} = \begin{bmatrix} 2 & 4 \ -1 & -2 \end{bmatrix}. $$

Nếu ta tính định thức của ma trận này, ta nhận được $2\cdot(-2 ) - 4\cdot(-1) = 0$. Điều này là có lý bởi ma trận $\mathbf{B}$ đã nén hình vuông ban đầu xuống thành một đoạn thẳng với diện tích bằng không. Thật vậy, nén một hình xuống không gian mới với số chiều thấp hơn là cách duy nhất để có diện tích bằng không sau phép biến đổi. Do đó chúng ta suy ra được kết quả sau: một ma trận $A$ khả nghịch nếu và chỉ nếu định thức khác không.

Hãy tưởng tượng ta có một hình bất kỳ trên mặt phẳng. Ta có thể chia nhỏ hình này thành một tập hợp các hình vuông nhỏ sao cho diện tính của hình đó bằng số lượng hình vuông trong cách chia này. Bây giờ nếu ta biến đổi hình đó bằng một ma trận, ta biến đổi các hình vuông nhỏ thành các hình bình hành với diện tích bằng với định thức của ma trận. Ta thấy rằng với bất kỳ hình nào, định thức cho ta một con số (có dấu) mà ma trận co giãn diện tích của một hình bất kỳ.

Việc tính định thức cho các ma trận lớn có thể phức tạp hơn, nhưng ý tưởng là như nhau. Định thức vẫn có tính chất rằng ma trận $n\times n$ co giãn các khối thể tích trong không gian $n$ chiều.

Tensors và các Phép Toán Đại Số Tuyến Tính Thông Dụng

Khái niệm về tensor đã được giới thiệu ở :numref:sec_linear-algebra. Trong mục này, chúng ta sẽ đi sâu hơn vào phép co tensor (tương đương với phép nhân ma trận), và xem cách chúng có thể cung cấp một cái nhìn nhất quán như thế nào đối với một số phép toán trên ma trận và vector.

Chúng ta đã biết cách nhân với ma trận và vector như thế nào để biến đổi dữ liệu. Để tensor trở nên hữu ích, ta cần một định nghĩa tương tự như thế. Xem lại phép nhân ma trận:

$$ \mathbf{C} = \mathbf{A}\mathbf{B}, $$

hoặc tương đương

$$ c_{i, j} = \sum_{k} a_{i, k}b_{k, j}.$$

Cách thức biểu diễn này có thể lặp lại với tensor. Với tensor, không có một trường hợp tổng quát để chọn tính tổng theo chỉ số nào. Bởi vậy, ta cần chỉ ra chính xác những chỉ số nào mà ta muốn tính tổng theo. Ví dụ, ta có thể xét

$$ y_{il} = \sum_{jk} x_{ijkl}a_{jk}. $$

Phép biến đổi này được gọi là một phép co tensor. Nó có thể biểu diễn được các phép biến đổi một cách linh động hơn nhiều so với phép nhân ma trận đơn thuần.

Để đơn giản cho việc ký hiệu, ta có thể để ý rằng tổng chỉ được tính theo những chỉ số mà xuất hiện nhiều hơn một lần trong biểu thức. Bởi vậy, người ta thường làm việc với ký hiệu Einstein với quy ước rằng phép tính tổng sẽ được lấy trên các chỉ số xuất hiện nhiều lần. Từ đó, ta có một phép biểu diễn ngắn gọn: $$ y_{il} = x_{ijkl}a_{jk}. $$

Một số ví dụ thông dụng trong Đại Số Tuyến Tính

Hãy xem ta có thể biểu diễn bao nhiêu khái niệm đại số tuyến tính đã học dưới biểu diễn tensor nén gọn này:

  • $\mathbf{v} \cdot \mathbf{w} = \sum_i v_iw_i$
  • $|\mathbf{v}|_2^{2} = \sum_i v_iv_i$
  • $(\mathbf{A}\mathbf{v})i = \sum_j a{ij}v_j$
  • $(\mathbf{A}\mathbf{B}){ik} = \sum_j a{ij}b_{jk}$
  • $\mathrm{tr}(\mathbf{A}) = \sum_i a_{ii}$

Với cách này, ta có thể thay thế hàng loạt ký hiệu chuyên dụng chỉ với những biểu diễn tensor ngắn.

Biểu diễn khi lập trình

Tensor cũng có thể được thao tác linh hoạt dưới dạng mã. Như đã thấy ở :numref:sec_linear-algebra, ta có thể tạo tensor bằng những cách bên dưới.

# Define tensors
B = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
A = np.array([[1, 2], [3, 4]])
v = np.array([1, 2])

# Print out the shapes
A.shape, B.shape, v.shape

Phép tính tổng Einstein đã được lập trình thông qua hàm np.einsum. Các chỉ số xuất hiện trong phép tổng Einstein có thể được truyền vào dưới dạng chuỗi ký tự, theo sau là những tensor để thao tác trên đó. Ví dụ, để thực hiện phép nhân ma trận, ta có thể sử dụng phép tổng Einstein ở trên ($\mathbf{A}\mathbf{v} = a_{ij}v_j$) và tách ra riêng những indices để có được cài đặt mong muốn:

# Reimplement matrix multiplication
np.einsum("ij, j -> i", A, v), A.dot(v)

Đây là một ký hiệu cực kỳ linh hoạt. Giả sử ta muốn tính toán một phép tính thường được ghi một cách truyền thống là

$$ c_{kl} = \sum_{ij} \mathbf{B}{ijk}\mathbf{A}{il}v_j. $$

nó có thể được thực hiện thông qua phép tổng Einstein như sau:

np.einsum("ijk, il, j -> kl", B, A, v)

Cách ký hiệu này vừa dễ đọc và hiệu quả cho chúng ta, tuy nhiên lại khá rườm rà nếu ta cần tạo ra một phép co tensor tự động bằng cách lập trình. Vì lý do này, einsum có một cách ký hiệu thay thế bằng cách cung cấp các chỉ số nguyên cho mỗi tensor. Ví dụ, cùng một phép co tensor, có thể viết lại bằng:

np.einsum(B, [0, 1, 2], A, [0, 3], v, [1], [2, 3])

Cả hai cách ký hiệu đều biểu diễn phép co tensor một cách chính xác và hiệu quả.

Tóm tắt

Về phương diện hình học vector có thể được hiểu như là điểm hoặc hướng trong không gian.

  • Tích vô hướng định nghĩa khái niệm góc trong không gian đa chiều bất kỳ.
  • Siêu phẳng (hyperplane) là sự khái quát hóa của đường thẳng và mặt phẳng trong không gian đa chiều. Chúng có thể được dùng để định nghĩa mặt phẳng quyết định được dùng trong bước cuối cùng của bài toán phân loại.
  • Phép nhân ma trận có thể được biểu diễn hình học như việc biến dạng một cách đồng nhất các các điểm toạ độ. Cách biểu diễn sự biến đổi vector này tuy có nhiều hạn chế nhưng lại gọn gàng về mặt toán học.
  • Độc lập tuyến tính là cách nói khi một tập hợp các vector lại ở trong một không gian ít chiều hơn so với dự kiến (chẳng hạn bạn có $3$ vector nhưng chỉ nằm trong không gian $2$ chiều). Hạng của ma trận là kích thước của tập con lớn nhất của ma trận đó có tính chất độc lập tuyến tính.
  • Khi phép nghịch đảo của một ma trận là xác định, việc nghịch đảo ma trận cho phép chúng ta tìm một ma trận khác mà hoàn tác lại hành động trước đó. Việc nghịch đảo ma trận hữu dụng trong lý thuyết, nhưng yêu cầu cẩn trọng khi sử dụng vì tính bất ổn định số học (numerical instability) của nó.
  • Các định thức cho phép ta đo đạc mức độ mở rộng hoặc co hẹp của một ma trận trong một không gian. Một ma trận là khả nghịch khi và chỉ khi định thức của nó khác không.
  • Phép co tensor và phép lấy tổng Einstein cho ta cách biểu diễn gọn gàng và sạch sẽ cho nhiều phép toán thường gặp trong học máy.

Bài tập

  1. Góc giữa hai vectors dưới đây là bao nhiêu?

$$ \vec v_1 = \begin{bmatrix} 1 \ 0 \ -1 \ 2 \end{bmatrix}, \qquad \vec v_2 = \begin{bmatrix} 3 \ 1 \ 0 \ 1 \end{bmatrix}? $$

  1. Đúng hay sai: $\begin{bmatrix}1 & 2\0&1\end{bmatrix}$ và $\begin{bmatrix}1 & -2\0&1\end{bmatrix}$ có phải là nghịch đảo của nhau?

Giả sử ta vẽ ra một hình trong mặt phẳng với diện tích $100\mathrm{m}^2$. Diện tích đó sẽ bằng bao nhiêu sau khi biến đổi hình đó bằng ma trận

$$ \begin{bmatrix} 2 & 3\\ 1 & 2 \end{bmatrix}. $$

  1. Trong các nhóm vector sau, nhóm nào là độc lập tuyến tính?
  • $\left{\begin{pmatrix}1\0\-1\end{pmatrix}, \begin{pmatrix}2\1\-1\end{pmatrix}, \begin{pmatrix}3\1\1\end{pmatrix}\right}$
  • $\left{\begin{pmatrix}3\1\1\end{pmatrix}, \begin{pmatrix}1\1\1\end{pmatrix}, \begin{pmatrix}0\0\0\end{pmatrix}\right}$
  • $\left{\begin{pmatrix}1\1\0\end{pmatrix}, \begin{pmatrix}0\1\-1\end{pmatrix}, \begin{pmatrix}1\0\1\end{pmatrix}\right}$
  1. Giả sử ta có ma trận viết là $A = \begin{bmatrix}c\d\end{bmatrix}\cdot\begin{bmatrix}a & b\end{bmatrix}$ với các giá trị $a, b, c$, và $d$ nào đó. Đúng hay sai: một ma trận như thế luôn có định thức bằng $0$?
  1. Các vector $e_1 = \begin{bmatrix}1\0\end{bmatrix}$ và $e_2 = \begin{bmatrix}0\1\end{bmatrix}$ là trực giao. Cần điều kiện gì với ma trận $A$ để $Ae_1$$Ae_2$ trực giao?
  1. Viết $\mathrm{tr}(\mathbf{A}^4)$ theo cách biểu diễn Einstein như thế nào với ma trận $A$? tùy ý?

Những người thực hiện

Bản dịch trong trang này được thực hiện bởi:

  • Vũ Hữu Tiệp
  • Lê Khắc Hồng Phúc
  • Hoàng Trọng Tuấn
  • Nguyễn Cảnh Thướng
  • Nguyễn Xuân Tú
  • Phạm Hồng Vinh
  • Trần Thị Hồng Hạnh
  • Nguyễn Lê Quang Nhật
  • Mai Sơn Hải