Chuyển tới nội dung chính

Ma trận là phép biến hình

Kéo hai cộtĐịnh thức = hệ số diện tíchMốc det = 0Cổng kiểm 340 khẳng định

Ma trận là phép biến hình

Đừng đọc ma trận như bảng số. Đọc nó như một câu lệnh: hai cột nói cho cả mặt phẳng biết phải đi đâu.

Bài trước xem một vector là một mũi tên và tích vô hướng là một con số đo góc. Bài này đổi vai: cái được nhìn không còn là một mũi tên mà là một phép biến hình, tức một cái máy nhận vào một vector và trả ra một vector khác. Ma trận là cách viết cái máy đó xuống giấy.

Cái đáng học nằm ở chỗ một bảng bốn số lại đọc được rất nhanh nếu bạn biết nhìn đúng chỗ, và ở chỗ một con số duy nhất, định thức, nói cho bạn biết phép biến hình làm phình hay làm co diện tích bao nhiêu lần, có lật mặt phẳng hay không, và có lấy lại được cái đã làm hay không.

Ma trận là phép biến hình · kéo hai cột
[1101]det = 1diện tích = 1
1(1,1) ↦jiKéo để đổi cột 2 (vector j)Kéo để đổi cột 1 (vector i)

Ở trạng thái mở bài, sim đang nói gì

Sim mở ra ở phép trượt. Cột 1 là mũi tên đỏ, đang ở (1, 0). Cột 2 là mũi tên vàng, đang ở (1, 1). Ô đọc kết quả vì thế in ma trận

[ 1 1 ]
[ 0 1 ]

và ngay bên cạnh là det = 1 với dòng nhỏ diện tích = 1. Hình bình hành tô đậm có bốn đỉnh (0, 0), (1, 0), (2, 1), (1, 1), và con số 1 viết ở giữa nó là diện tích của chính nó. Điểm mẫu (1, 1) bị đưa tới (2, 1), tức đúng cái đỉnh xa nhất của hình bình hành, nên ở trạng thái mở bài dấu chấm nằm chồng lên đỉnh đó.

Lưới mờ phía sau là lưới gốc, chạy 4 ô mỗi phía tính từ gốc toạ độ. Lưới đậm hơn là ảnh của lưới gốc sau khi đi qua ma trận: mỗi đường thẳng vẫn là đường thẳng, và hai họ đường song song vẫn song song. Đó là toàn bộ nội dung của chữ "tuyến tính".

Mỗi toạ độ kéo được từ -4.4 tới 4.4 theo bước 0.25. Có một chi tiết nhỏ đáng nói ngay vì cả bài dựa vào nó: hai đầu mút 4.4 không nằm trên lưới 0.25, vì hệ làm tròn về lưới trước rồi mới kẹp vào dải. Nên số giá trị kéo tới được của một toạ độ là 37 chứ không phải 36: ba mươi lăm giá trị trên lưới từ -4.25 tới 4.25, cộng hai đầu mút, và khe cạnh hai đầu mút rộng 0.15 thay vì 0.25. Bốn toạ độ như vậy cho đúng 1874161 cấu hình, tức toàn bộ không gian trạng thái bạn bấm tới được. Nó nhỏ tới mức quét được hết, nên mọi con số trong bài này là kết quả quét cả 1874161 cấu hình chứ không phải quét mẫu.

Hai cột là ảnh của hai vector đơn vị

Đây là cách đọc ma trận nhanh nhất, và nó không phải mẹo mà là định nghĩa. Một phép biến hình tuyến tính đã bị nó làm với (1, 0)(0, 1) quyết định hoàn toàn, vì mọi vector khác là một tổ hợp của hai vector đó.

Lấy ma trận có cột 1 là (1.5, -2) và cột 2 là (0.25, 3), tức

[ 1.5 0.25 ]
[ -2 3 ]

Nó đưa (1, 0) tới đúng (1.5, -2), và đưa (0, 1) tới đúng (0.25, 3). Không cần tính gì: cột nào là ảnh của vector đơn vị nào, viết luôn ở đó. Từ đó suy tiếp: (1, 1) đi tới tổng hai cột, tức (1.75, 1), còn (2, 2) đi tới gấp đôi chỗ đó. Và gốc toạ độ (0, 0) thì không đi đâu cả.

Câu cuối quan trọng hơn nó trông. Một ma trận luôn giữ gốc toạ độ tại chỗ. Muốn dời cả mặt phẳng đi một đoạn thì bốn số không đủ, phải thêm một vector dịch, và đó chính là chỗ bias xuất hiện trong mạng nơ-ron ở mục cuối bài.

Trong sim, hai mũi tên bạn kéo chính là hai cột. Kéo mũi tên đỏ là sửa cột 1, tức sửa hai số bên trái của ma trận. Kéo mũi tên vàng là sửa cột 2. Đọc theo chiều ngược lại thì hình bình hành tô đậm luôn là hình vuông đơn vị sau biến hình, vì bốn đỉnh của nó là (0, 0), cột 1, tổng hai cột, và cột 2.

Định thức là hệ số đổi diện tích

Định thức của ma trận [[a, c], [b, d]]a*d - b*c. Ở dạng công thức nó chỉ là hai phép nhân và một phép trừ. Ở dạng hình học nó là diện tích có dấu của hình bình hành căng bởi hai cột, và vì hình bình hành đó là ảnh của hình vuông đơn vị có diện tích 1, con số đó cũng chính là hệ số mà mọi diện tích trên mặt phẳng bị nhân với.

Chữ "mọi diện tích" là một khẳng định mạnh, nên hãy kiểm nó trên một hình không phải hình vuông đơn vị. Lấy tam giác có ba đỉnh (0, 0), (2, 0), (0, 3), diện tích của nó là 3, tính bằng đầu. Bấm nút Co giãn, tức ma trận

[ 1.5 0 ]
[ 0 0.5 ]

Định thức là 1.5 nhân 0.5 bằng 0.75. Ảnh của tam giác kia có diện tích 2.25, và 2.25 chia 3 bằng đúng 0.75. Diện tích trước là 3, diện tích sau là 2.25, tỉ số bằng đúng định thức. Cổng kiểm làm phép đo này với cả 1874161 ma trận kéo tới được, chứ không chỉ với ma trận co giãn ở trên.

Dấu thì nói chuyện khác. Bấm nút Lật, tức ma trận

[ 1 0 ]
[ 0 -1 ]

Định thức là -1. Diện tích tam giác sau biến hình vẫn3 về độ lớn, nhưng tính theo công thức đa giác thì nó ra -3, và dấu trừ đó có nghĩa: thứ tự ba đỉnh đã đi từ chiều ngược kim đồng hồ thành chiều cùng kim đồng hồ. Mặt phẳng đã bị lật. Ô đọc kết quả tách đúng hai việc đó ra: det giữ dấu và in -1, dòng diện tích bỏ dấu và in 1, kèm chữ đã lật.

Cổng kiểm không tin một đường tính nào cả nên nó tính định thức bằng ba đường khác nhau và so với nhau trên toàn bộ 1874161 cấu hình. Đường thứ nhất là a*d - b*c của engine. Đường thứ hai đổi mọi toạ độ thành số nguyên rồi nhân và trừ trong số nguyên, vì mọi toạ độ kéo tới được đều là số nguyên lần 0.05. Đường thứ ba lấy diện tích hình bình hành trên hình bằng công thức đa giác, tức tổng các x_k * y_(k+1) - x_(k+1) * y_k rồi chia hai. Khe lệch lớn nhất giữa chúng là 7.105427357601002e-15, và ba đường trùng nhau tới từng bit ở lần lượt 1692993, 17763131714193 cấu hình. Ba con số khác nhau là bằng chứng đây thật là ba biểu thức khác nhau: nếu chúng bằng nhau hết thì đó mới là điều đáng lo, vì nó có nghĩa một đường đang mang ba cái tên.

Định thức bằng 0 là mốc quan trọng nhất

Bấm nút Bóp phẳng. Cột 1 thành (1, 0.5), cột 2 thành (2, 1), và cột 2 đúng bằng 2 lần cột 1. Hai cột nằm trên một đường thẳng, nên hình bình hành không còn hình bình hành nào nữa: nó dẹp thành một đoạn thẳng, diện tích 0, và det in ra 0.

Chuyện xảy ra không chỉ với hình vuông đơn vị. Mọi điểm của mặt phẳng đều đáp xuống đúng đường thẳng y = 0.5x. Tam giác diện tích 3 ở mục trên cũng thành diện tích 0. Và đây là hệ quả đắt nhất: (2, 0)(0, 1) cùng đáp xuống (2, 1). Hai điểm khác nhau, một ảnh duy nhất. Không có phép biến hình nào đưa (2, 1) về được cả hai chỗ, nên không có ma trận nghịch đảo. Thông tin về việc điểm đó vốn là điểm nào đã mất, và mất thật, không phải mất tạm.

Đó cũng chính là lý do một phép nén từ d chiều xuống r chiều với r nhỏ hơn d không thể lấy lại nguyên vẹn cái đã nén, chuyện bạn gặp lại ở bài MLA nén bộ đệm KV. Ở đây là 2 chiều xuống 1 chiều nên nhìn thấy được bằng mắt.

Trên toàn bộ không gian trạng thái, 13185 trong 1874161 ma trận là suy biến, tức có định thức bằng 0 theo số học chính xác. Cổng kiểm khẳng định đúng tại mốc đó và ở cả hai bên mốc, và chỗ này có ba điều đáng nói rõ.

Thứ nhất, một bước lưới sang hai bên thì ra khỏi mốc, và ra rất xa. Từ trạng thái bóp phẳng, kéo cột 2 sang một bước, j_x từ 2 thành 1.75, thì định thức thành 0.125. Sang bước kia, j_x thành 2.25, thì định thức thành -0.125, và hình đổi màu vì nó đã lật. Đổi toạ độ khác cũng vậy: i_y từ 0.5 xuống 0.25 cho 0.5, lên 0.75 cho -0.5.

Thứ hai, màn hình làm tròn hai chữ số nên nó che một chút. 0.125 in ra 0.13, không phải 0.12 và cũng không phải 0.125. Trên 1261184 trong 1874161 cấu hình thì con số in ra là một bản đã làm tròn của con số thật, và chỗ làm tròn nặng nhất lệch 0.005. Nhưng có một chuyện màn hình không bao giờ làm: in 0 cho một định thức khác 0. Đo trên cả 1874161 cấu hình được 0 trường hợp, và lý do là số học: định thức khác 0 nhỏ nhất kéo tới được là 0.0125, in ra 0.01, còn xa mức 0.005 là mức bắt đầu làm tròn thành 0.

Thứ ba, mốc 0 phải hỏi bằng một cửa sổ chứ không bằng dấu bằng, và ở đây cổng kiểm phải nói thật một điều: trên lưới kéo được thì dấu bằng đã đủ. Cả 13185 ma trận suy biến đều cho định thức số thực bằng đúng 0, khe lệch tệ nhất đo được là 0 chằn chặn. Cửa sổ vẫn đúng và vẫn nên có, vì nó cần cho những giá trị không kéo tới được: lấy cột 1 là (0.1, 0.5) và cột 2 là (0.14, 0.7), tức cột 2 gấp 1.4 lần cột 1 nên hai cột song song chằn chặn. Hai tích số phải triệt tiêu nhau đều bằng 0.07 khi tính bằng tay, nhưng trên máy 0.1 nhân 0.7 cho 0.06999999999999999 còn 0.5 nhân 0.14 cho đúng 0.07. Định thức vì thế ra -1.3877787807814457e-17, một số âm. Nếu cờ "đã lật" được viết là det < 0 thì ma trận đó sẽ tuyên bố đã lật mặt phẳng trong khi ô bên cạnh in 0. Viết theo cửa sổ thì không.

Còn một chỗ đặc tả tôi được giao đã nói quá, và cổng kiểm đo ra phản ví dụ. Câu "một bước hai bên mốc thì ra khỏi mốc" không đúng cho mọi ma trận suy biến. Cổng thử cả 103648 bước một-lưới đi ra từ 13185 ma trận suy biến, và 21024 bước trong số đó vẫn suy biến. Lý do rất cụ thể: 2737 ma trận suy biến có một cột bằng vector 0, và khi một cột đã là 0 thì kéo cột kia đi đâu cũng vẫn det = 0. Câu phát biểu đúng là: trong 82624 bước có ra khỏi mốc, không bước nào rơi vào cửa sổ 0, và bước nhỏ nhất trong số đó cho định thức 0.0375, in ra 0.04, tức trên cửa sổ 1e-9 bảy bậc độ lớn.

Quay, co giãn, trượt: đọc từ bốn số

Ba phép biến hình quen mặt phân biệt được bằng cách nhìn bốn số, không cần vẽ.

  • Quay: hai cột dài đúng 1 và vuông nhau, và cột 2 là cột 1 quay một phần tư vòng sang trái, tức cột 1 là (a, b) thì cột 2 là (-b, a). Định thức bằng 1.
  • Co giãn theo trục: hai số ở hai góc chéo phụ đều bằng 0, tức cột 1 nằm trên trục ngang và cột 2 nằm trên trục dọc. Định thức là tích hai hệ số kéo, 1.5 nhân 0.5 bằng 0.75.
  • Trượt: đường chéo chính là 11, và đúng một trong hai số còn lại khác 0. Một vector đơn vị đứng yên, vector kia nghiêng đi. Định thức bằng 1 bất kể nghiêng bao nhiêu: kéo j_x tới 4.4, tức nghiêng hết cỡ, định thức vẫn đúng 1.
  • Phản chiếu: hai cột vẫn dài 1 và vuông nhau như phép quay, chỉ khác định thức bằng -1. Nút Lật là một phép phản chiếu, không phải một phép quay.

Bốn họ đó là những lát rất mỏng trong không gian ma trận, và đây là chỗ nên đo thay vì cảm nhận. Trong 1874161 ma trận kéo tới được có đúng 1 ma trận đơn vị, 3 phép quay khác nó, 4 phép phản chiếu, 1292 phép co giãn theo trục và 72 phép trượt. Tổng bốn họ có tên là 1372 ma trận, chưa tới một phần nghìn của không gian. 13185 ma trận suy biến, và 1859604 ma trận còn lại không thuộc họ nào có tên.

Con số 3 phép quay đáng giải thích, vì nó dễ tưởng là lỗi. Kéo tới được đúng bốn phép quay: 0, 90, 180270 độ, vì trên lưới 0.25 không có cặp cột nào khác vừa dài 1 vừa vuông nhau. Phép quay 0 độ chính là ma trận đơn vị, và bộ phân loại hỏi "có phải ma trận đơn vị không" trước, nên nó được gọi tên riêng. Thứ tự hỏi đó là một quy ước, không phải chân lý, và nó được ghi rõ trong engine.

Phép quay giữ độ dài mọi vector. Cổng kiểm dựng 360 phép quay từ Math.cosMath.sin, nhân với 48 vector thử, tổng 17280 lượt, và đo: độ dài đổi nhiều nhất 4.186913223156733e-16 xét theo tỉ lệ, tức chưa tới hai đơn vị cuối, và bằng nhau tới từng bit ở 8228 lượt. Nói cho chính xác thì đây là một khẳng định tới mức làm tròn, chứ không phải một đẳng thức số thực. Riêng bốn phép quay kéo tới được thì không đổi một bit nào, vì bốn số của chúng là 0±1.

Ở đây có một chỗ tôi đã sửa engine và phải nói rõ. Nút Xoay trước dùng 0.7071 làm cosin của 45 độ. Bốn chữ số thập phân nghe như đủ, nhưng định thức của ma trận đó là 0.9999808199999999, và nó co mọi độ dài đi 0.000009590045984744612. Tức là câu "phép quay giữ nguyên diện tích và độ dài" sai ngay trên preset của chính sim, sai ở chữ số thập phân thứ năm, tệ hơn khe lệch làm tròn mười một bậc độ lớn. Tam giác diện tích 3 dưới ma trận đó thành 2.9999424599999993. Điều làm chuyện này sống lâu là: mọi chuỗi trên màn hình của hai hằng số giống nhau y nguyên, cả bốn ô đều in 0.71-0.71, det đều in 1, số trong hình đều in 1. Nút giờ dùng Math.SQRT1_2, tức căn hai chia hai ở độ chính xác đầy đủ, và cổng kiểm giữ hằng số cũ lại làm phản ví dụ kèm khẳng định rằng màn hình không đổi một chữ nào.

Thứ tự nhân quan trọng

Hai phép biến hình làm liên tiếp cũng là một phép biến hình, và ma trận của nó là tích hai ma trận. Quy ước đọc: AB nghĩa là làm B trước rồi làm A. Lý do quy ước như vậy khớp với cách đọc cột: một cột của ABA tác động lên cột tương ứng của B.

Lấy S là phép trượt của trạng thái mở bài và K là phép co giãn [[1.5, 0], [0, 0.5]].

tíchlàm trướcma trậndet(1, 1) đi tới
SKK[[1.5, 0.5], [0, 0.5]]0.75(2, 0.5)
KSS[[1.5, 1.5], [0, 0.5]]0.75(3, 0.5)

Hai ma trận khác nhau, khác ở đúng một ô: góc trên phải là 0.5 hay 1.5. Và điểm mẫu (1, 1) đi tới hai chỗ khác nhau, nên khác biệt này nhìn thấy trên hình chứ không chỉ nằm trong bảng số.

Định thức thì không phân biệt được hai thứ tự: cả hai đều 0.75, và đó là det(S) nhân det(K). Nói cách khác, hệ số đổi diện tích của hai phép làm liên tiếp là tích hai hệ số, và tích số thì đổi chỗ được.

Hiếm hay không hiếm thì phải đếm. Cổng kiểm lấy 6 giá trị cho mỗi toạ độ, được 1296 ma trận, tức 1679616 cặp có thứ tự, và đếm: chỉ 29486 cặp cho AB bằng BA, tức 1.76 phần trăm. Trong đó 28190 cặp là hai ma trận khác nhau, phần còn lại là mỗi ma trận với chính nó. Và 12680 cặp giao hoán vì một lý do thật, tức không có cái nào là bội của ma trận đơn vị. Còn det(AB) bằng det(BA) trên cả 1679616 cặp, giống nhau tới từng bit.

Nghịch đảo: khi nào lấy lại được cái đã làm

Nếu định thức khác 0 thì phép biến hình có nghịch đảo, và nghịch đảo của [[a, c], [b, d]][[d, -c], [-b, a]] chia cho định thức. Phép trượt của trạng thái mở bài có nghịch đảo là

[ 1 -1 ]
[ 0 1 ]

tức là một phép trượt ngược lại, và nhân hai cái đó với nhau cho ma trận đơn vị, theo cả hai thứ tự. Định thức của nghịch đảo là một chia định thức: 0.75 có nghịch đảo với định thức 1.3333333333333333, và hai số nhân nhau ra 1, tức làm co diện tích còn 0.75 lần thì muốn về chỗ cũ phải phình lên 1.3333333333333333 lần, đúng bốn phần ba.

Cổng kiểm nhân ma trận với nghịch đảo của nó trên cả 1860976 cấu hình khả nghịch và đòi kết quả là ma trận đơn vị. Đây là chỗ không được ghim dấu bằng: chỉ 968576 cấu hình cho ma trận đơn vị đúng tới từng bit, phần còn lại lệch, nhiều nhất 1.1368683772161603e-13. Khe lệch lớn nhất nằm ở chỗ định thức nhỏ nhất, vì chia cho một số nhỏ thì mất mấy chữ số, và đó là lý do có thật chứ không phải một hằng số bí ẩn.

Mỗi tầng của mạng nơ-ron là một phép biến hình cộng một phép dịch

Một tầng dày của mạng nơ-ron làm đúng hai việc trước hàm kích hoạt: nhân đầu vào với một ma trận trọng số, rồi cộng một vector bias. Với trọng số [[1.5, 0], [0, 0.5]] và đầu vào (2, 4) thì phần ma trận cho (3, 2), cộng bias (1, -1) thì ra (4, 1). Phần thứ hai không ma trận nào làm thay được, vì ma trận luôn giữ gốc toạ độ, còn bias chính là cái dời gốc đi.

Từ đây rút ra hai câu đáng nhớ. Thứ nhất, hai tầng liên tiếp mà không có hàm kích hoạt thì chỉ là một ma trận: [[1.5, 0], [0, 0.5]] nhân [[2, 0], [0, 2]] cho [[3, 0], [0, 1]] với định thức 3. Xếp bao nhiêu tầng như vậy cũng vẫn được một phép biến hình tuyến tính, nên phi tuyến không phải trang trí, nó là thứ duy nhất làm nhiều tầng khác một tầng. Thứ hai, một tầng có định thức 0 là một tầng bóp phẳng, và cái nó bóp mất thì tầng sau không có cách nào lấy lại.

Bài nơ-ron và lan truyền xuôi đi vào đúng phép tính đó ở quy mô một mạng, còn bài vector và tích vô hướng kế bên nhìn cùng một bảng số theo góc khác: mỗi hàng của ma trận chấm điểm với đầu vào, và cả phép nhân ma trận là một bảng tích vô hướng.

Những con số trong bài được kiểm bằng gì

Mọi con số bạn vừa đọc đều bị một cổng kiểm khoá lại, hiện là 340 khẳng định, và cổng không tin phép tính của chính engine. Nó dựng lại định thức bằng ba đường độc lập đã kể ở mục trên, đo diện tích ảnh của một tam giác có diện tích tính bằng đầu, và quét toàn bộ 1874161 cấu hình kéo tới được thay vì vài điểm.

Cổng còn tự phá engine rồi đòi chính mình báo đỏ. Tám đột biến đã thử: đổi dấu trừ trong định thức thành dấu cộng, nới cửa sổ 0 từ 1e-9 lên 0.5, đổi preset mở bài, viết cờ "đã lật" thành det < 0, đổi thứ tự kẹp và làm tròn trong clampCoord, đổi thứ tự hai ma trận trong phép nhân, làm tròn màn hình về một chữ số thập phân, và hỏi "có phải phép quay" trước "có phải ma trận đơn vị". Cả tám đều làm cổng đỏ, và hoàn nguyên thì cổng xanh lại. Cổng cũng đỏ khi engine mất một hàm xuất, khi engine không biên dịch được, và khi chính cổng dừng giữa chừng mà không ném lỗi.

Cuối cùng, những gì bài này không chỉ ra. Trong sim không có học: hai cột do bạn kéo, không phải do mô hình nào tìm ra. Mục về mạng nơ-ron là cùng một phép tính ở số chiều lớn hơn, chứ không phải điều mà cổng kiểm chứng minh được, vì trong engine không có mạng nào, chỉ có hai cột trong mặt phẳng. Và mọi toạ độ ở đây bước 0.25 nên nó là một mô hình rất sạch của bài toán thật, nơi trọng số là số thực bất kỳ và những khe lệch đo được ở trên còn lớn hơn.

Điều rút ra

Hai cột của ma trận là ảnh của hai vector đơn vị, nên muốn biết một ma trận làm gì thì đọc thẳng hai cột của nó. Định thức a*d - b*c là hệ số đổi diện tích: tam giác diện tích 3 dưới ma trận [[1.5, 0], [0, 0.5]] thành 2.25, và 2.25 chia 3 bằng đúng 0.75 là định thức. Dấu âm nghĩa là mặt phẳng bị lật, det = -1 giữ nguyên độ lớn diện tích nhưng đảo chiều. Định thức bằng 0 là mốc phải nhớ: cả mặt phẳng bị bóp lên một đường thẳng, (2, 0)(0, 1) cùng đáp xuống (2, 1), và vì thế không có nghịch đảo, thông tin mất hẳn. Bốn số cũng nói luôn đây là phép gì: hai cột dài 1 và vuông nhau là quay hoặc phản chiếu, hai góc chéo phụ bằng 0 là co giãn theo trục, đường chéo 11 với một góc chéo phụ khác 0 là trượt. Còn thứ tự nhân thì quan trọng: [[1, 1], [0, 1]] với [[1.5, 0], [0, 0.5]] cho [[1.5, 0.5], [0, 0.5]] theo một thứ tự và [[1.5, 1.5], [0, 0.5]] theo thứ tự kia, tuy định thức của cả hai vẫn là 0.75.

Câu hỏi tự kiểm0/3 đúngchưa trả lời
  1. 1Bấm nút Bóp phẳng: cột 1 thành (1, 0.5), cột 2 thành (2, 1), và det in ra 0. Điều gì mất đi ở đó?
  2. 2Nút Xoay từng dùng 0.7071 làm cosin của 45 độ. Ô đọc kết quả in det = 1. Vậy có gì sai?
  3. 3S là phép trượt [[1, 1], [0, 1]], K là phép co giãn [[1.5, 0], [0, 0.5]]. So SK với KS thì sao?