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

Vector và tích vô hướng

Kéo thảTính lại thậtBa mốc đo đượcCổng kiểm 323 khẳng định

Vector và tích vô hướng

Một phép nhân, một phép cộng, và một con số nói hai mũi tên cùng hướng tới đâu. Kéo chúng và nhìn con số đó đổi.

Đây là bài đầu tiên của học phần, và nó chọn tích vô hướng làm cửa vào không phải vì phép tính khó. Phép tính dễ tới mức bạn làm nhẩm được: nhân từng cặp toạ độ rồi cộng lại. Nó ở đây vì nó là cùng một phép tính xuất hiện lại ở mọi chương sau. Một nơ-ron lấy tổng có trọng số của đầu vào: đó là tích vô hướng. Một phép nhân ma trận là một bảng tích vô hướng. Attention chấm điểm hai vector với nhau: cũng tích vô hướng. Học kỹ nó một lần thì bốn chương sau nhẹ đi.

Cái đáng học không nằm ở công thức mà nằm ở chỗ một con số duy nhất lại đo được góc. Sim dưới đây cho bạn kéo hai mũi tên và xem cả bốn ô đọc kết quả tính lại: tích vô hướng, cosine, góc, và độ dài bóng của b đổ lên a.

Vector và tích vô hướng · kéo hai mũi tên
a·b 6θ 53.1°cos θ 0.60|a| 3.2|b| 3.2chiếu 1.9
53.1°a (3, 1)b (1, 3)

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

Hai vector mặc định là a (3, 1)b (1, 3). Ô a·b đọc 6, và bạn kiểm lại được bằng đầu: 3 nhân 1 bằng 3, 1 nhân 3 bằng 3, cộng lại bằng 6. Không có bước nào khác.

Hai ô độ dài cùng đọc 3.2, vì (1, 3) chỉ là (3, 1) lật qua đường chéo nên hai độ dài bằng nhau tới từng bit: cả hai đúng bằng 3.1622776601683795, tức căn của 10. Ô θ đọc 53.1°, số đầy đủ là 53.130102354155994. Ô cos θ đọc 0.60. Ô chiếu đọc 1.9, số đầy đủ là 1.8973665961010275.

Ở đây có một chỗ đáng dừng lại ngay từ bài đầu, vì nó sẽ còn quay lại suốt học phần. Cosine đúng ra phải là 6 chia 10, tức 0.6 chằn chặn. Nhưng máy không tính 10: nó tính |a| rồi |b| rồi nhân hai số đó, và kết quả là 10.000000000000002 chứ không phải 10. Nên cosine mà engine trả về là 0.5999999999999999, lệch khỏi 0.6 đúng nửa đơn vị cuối. Ô đọc kết quả hiện 0.60 nên màn hình đang che một khe lệch có thật. Bài này sẽ nói rõ mỗi lần nó xảy ra, thay vì viết dấu bằng ở những chỗ chỉ đúng tới mức làm tròn.

Dải kéo được của mỗi toạ độ chạy từ -5.6 tới 5.6 theo bước 0.1, tức 113 giá trị cho mỗi toạ độ. Đó là toàn bộ không gian trạng thái mà bạn bấm tới được, và cũng là lưới mà cổng kiểm quét.

Tích vô hướng là nhân từng cặp rồi cộng

Với a có toạ độ (a_x, a_y)b(b_x, b_y), tích vô hướng là a_x * b_x + a_y * b_y. Hai phép nhân, một phép cộng, ra một số, không phải một vector. Vài ca nên tự tính lại bằng tay:

  • (1, 2) với (3, 4) cho 3 + 8 = 11.
  • Đổi dấu cả hai toạ độ của a thì đổi dấu kết quả: (-1, -2) với (3, 4) cho -11.
  • Một vector nhân với chính nó cho tổng bình phương: (3, 1) với (3, 1) cho 10.
  • Hai trục vuông nhau: (2, 0) với (0, 3) cho 0.
  • Hai đường chéo cũng vuông nhau: (1, 1) với (1, -1) cho 0.

Ca thứ ba đáng để ý. a·a cho đúng 10, không sai một bit, còn |a| nhân |a| cho 10.000000000000002. Cùng một đại lượng toán học, hai con số khác nhau trên máy, vì đường thứ hai đi qua căn bậc hai rồi bình phương lại. Nếu bạn cần bình phương độ dài thì hãy lấy a·a, đừng lấy |a| nhân |a|.

Còn một điều nữa: a·b luôn bằng b·a. Đổi chỗ hai vector thì hai tích số bị đổi chỗ, mà phép nhân số thực đổi chỗ được chính xác, và thứ tự cộng dồn thì không đổi vì chỉ có một phép cộng. Cổng kiểm quét 28561 cấu hình và cả 28561 cho kết quả giống nhau tới từng bit. Nói thẳng luôn: đây là một khẳng định đã đo chứ không phải suy ra, vì phép cộng số thực nói chung không đổi thứ tự cộng dồn được, và nếu engine cộng dồn theo chiều khác thì kết luận có thể khác.

Ý nghĩa hình học: a·b = |a| · |b| · cos θ

Công thức trên chỉ là cách tính. Ý nghĩa nằm ở một cách viết khác: tích vô hướng bằng độ dài a nhân độ dài b nhân cosine của góc giữa chúng. Hai độ dài là hai số dương, nên dấu và độ lớn tương đối của a·b do một mình cos θ quyết định. Đó là lý do một con số duy nhất đo được góc.

Cách dễ thấy nhất là giữ nguyên hai độ dài rồi chỉ quay b. Cả sáu vector b dưới đây có độ dài đúng bằng độ dài của a, nên |a| · |b| bằng 10 cho suốt cả bảng, và a·b chỉ còn là 10 nhân cosine. Mỗi hàng đều kéo tới được từ trạng thái mở bài.

ba·bcos θθ
(3, 1)101.00
(3, -1)80.8036.9°
(1, 3)60.6053.1°
(-1, 3)00.0090°
(-3, 1)-8-0.80143.1°
(-3, -1)-10-1.00180°

Cột a·b đi xuống đơn điệu trong khi cột θ đi lên, và đó không phải nhận xét bằng mắt: cổng kiểm khẳng định thứ tự của cả sáu hàng theo cả hai chiều.

Hàng đầu và hàng cuối có một chỗ lệch đáng nói. Hai vector giống hệt nhau thì góc phải bằng 0, nhưng engine trả về 1.2074182697257333e-6 độ. Lỗi không nằm ở tích vô hướng: a·a vẫn đúng 10 không sai bit nào. Nó nằm ở acos. Cosine ở đó ra 0.9999999999999998, thiếu 1 một đơn vị cuối, và acos gần hai đầu mút thì rất phẳng nên nó phóng một bit thành 2.1073424255447017e-8 radian. Hàng cuối bị y như vậy theo chiều ngược lại: 179.99999879258175 độ thay vì 180. Ô đọc kết quả làm tròn tới một chữ số thập phân nên bạn thấy 180°, tức màn hình lại che một lỗi có thật, lần này là lỗi lớn hơn lần trước bốn bậc độ lớn.

Chuyện tệ hơn cũng xảy ra và cổng kiểm đã đo. Về mặt toán học |a·b| không bao giờ vượt |a| · |b|, đó là bất đẳng thức Cauchy-Schwarz. Trên số thực 64 bit thì nó hỏng: trong 28561 cấu hình của lưới có 56 cấu hình mà |a·b| lớn hơn |a| · |b|, nhiều nhất là 3.3975585069816727e-16 xét theo tỉ lệ. Ca cực đoan nhất là a bằng b bằng (-5.6, 0.1), ở đó cosine ra 1.0000000000000004. Nếu đưa thẳng số đó vào acos thì kết quả là NaN và ô góc sẽ hiện dấu gạch. Engine vì thế kẹp giá trị vào đoạn -1 tới 1 trước khi gọi acos, và đó là chỗ duy nhất trong phần tính có kẹp giá trị. Nó không phải cái kẹp dải nhập liệu, nó là miếng vá đúng ở biên.

Ô chiếu: bóng của b đổ lên a

Trên hình có một vệt mờ nằm dọc theo a và một đường nét đứt hạ từ đầu b xuống vệt đó. Vệt mờ là bóng của b đổ lên hướng của a, và ô chiếu là độ dài có dấu của nó: a·b chia cho |a|. Ở trạng thái mở bài nó bằng 1.8973665961010275, in ra 1.9.

Đọc ngược lại thì đây là cách phân rã tích vô hướng thành hai phần dễ hình dung: a·b bằng |a| nhân với chiều dài bóng. Ở trạng thái mở bài, 3.1622776601683795 nhân 1.8973665961010275 cho đúng 6, không sai một bit. Cổng kiểm quét đẳng thức này trên 28392 cấu hình có a khác vector 0: 25868 cấu hình khớp tới từng bit, phần còn lại lệch nhiều nhất 2.0039169884763123e-16 so với cỡ |a| · |b|.

Ô chiếu nằm đúng giữa a·bcos θ về mức độ "sạch độ lớn": nó đã chia cho một độ dài, chứ không phải hai. Cụ thể, chiếu bằng |b| nhân cos θ, nên nó bỏ được ảnh hưởng của độ dài a mà vẫn giữ nguyên ảnh hưởng của độ dài b. Vì vậy dấu của nó luôn cùng dấu với a·b, và nó bằng 0 đúng tại mốc vuông góc.

Một chi tiết nhỏ đáng biết vì nó dạy đúng bài học của cả trang: cái bóng vẽ trên hình có đầu ở (1.7999999999999996, 0.5999999999999999), và độ dài của vector đó là 1.8973665961010273, tức thấp hơn con số vô hướng ở ô đọc kết quả hai đơn vị cuối. Hai đường tính khác nhau, hai kết quả khác nhau ở bit cuối, và cả hai đều làm tròn về 1.9 nên hình và số không bao giờ nói khác nhau trên màn hình.

Ba mốc đáng nhớ, và mốc vuông góc là mốc phải cẩn thận

Từ bảng trên rút ra ba mốc, và đây là ba câu nên nhớ suốt học phần:

  • Cùng hướng cho giá trị lớn nhất. Với hai độ dài đã cho, không xoay được kiểu nào cho ra số lớn hơn |a| · |b|.
  • Vuông góc cho đúng 0. Không phải nhỏ, mà bằng 0.
  • Ngược hướng cho giá trị âm nhỏ nhất, đúng bằng số đối của mốc đầu.

Mốc thứ hai là mốc dạy quan trọng nhất, vì nó là mốc duy nhất phát biểu được thành một đẳng thức. Nó cũng là mốc mà số thực gây rắc rối, nên đáng nói rõ ràng hơn ba dòng.

Kéo b tới (-1, 3) thì a·b bằng 0, cos θ bằng 0, và θ bằng đúng 90, cả ba không sai một bit nào. Nhưng đó là một ca may. Cổng kiểm tìm trên lưới 480 cặp vuông góc theo số học chính xác, và trong đó chỉ 472 cặp cho a·b bằng đúng 0. Còn lại 8 cặp cho một số khác 0, và bạn kéo tới được: giữ a (3, 1), kéo b tới (0.1, -0.3). Cặp đó vuông góc chằn chặn, vì 3 nhân 1 cộng 1 nhân -3 bằng 0 khi tính theo đơn vị một phần mười. Nhưng engine trả về 5.551115123125783e-17.

Nguyên nhân gọn gàng: hai tích số phải triệt tiêu nhau là 3 * 0.11 * (-0.3). Trên máy, 3 * 0.1 cho 0.30000000000000004 còn 1 * (-0.3) cho đúng -0.3. Hai số đó lệch nhau một bit, nên tổng của chúng không phải 0 mà là một phần tư đơn vị cuối tại 1, tức 2 lũy thừa -54.

Vì vậy engine không hỏi a·b === 0. Nó hỏi |a·b| có nhỏ hơn 1e-9 hay không, tức nó dùng một cửa sổ, và ô đọc kết quả in ra 0 cho cả 472 cặp đúng và 8 cặp gần đúng. Cửa sổ đó rộng hơn khe lệch tệ nhất bảy bậc độ lớn, và hẹp hơn một bước lưới bảy bậc, nên nó không thể gán oan cho một cặp lệch thật. Đây là chỗ dễ mắc lỗi khi bạn tự viết phép kiểm: một phép kiểm đòi a·b bằng 0 tuyệt đối sẽ báo đỏ cho một cài đặt hoàn toàn đúng.

Ngược lại, cửa sổ mà nới rộng thì nó nói dối. Đó là lý do cổng kiểm khẳng định cả một bước lưới hai bên mốc. Từ b (-1, 3) lùi một bước thành (-0.9, 3) thì a·b thành 0.2999999999999998, in ra 0.3, và góc thành 88.3°. Tiến một bước thành (-1.1, 3) thì a·b thành -0.30000000000000027, in ra -0.3, và góc thành 91.7°. Cổng kiểm làm việc này cho 1232 cặp láng giềng một bước của mọi cặp vuông góc trên lưới, và không cặp nào còn nằm trong cửa sổ 0. Bước nhảy nhỏ nhất đo được là 0.009999999999999898, tức đúng 0.1 nhân với toạ độ khác 0 nhỏ nhất của lưới, và nó vẫn lớn hơn cửa sổ 0 tới mười triệu lần.

Nhân độ dài thì đổi tỉ lệ, không đổi góc

Kéo b xa ra dọc theo chính hướng của nó thì a·b lớn lên theo tỉ lệ mà góc không nhích. Ba trạng thái sau đều có b cùng hướng, chỉ khác độ dài, và cả ba kéo tới được:

b|b|a·bchiếucos θθ
(0.5, 1.5)1.630.90.6053.1°
(1, 3)3.261.90.6053.1°
(2, 6)6.3123.80.6053.1°

Nhân b với 2 thì a·b nhân 2, hình chiếu nhân 2, còn cosine và góc giữ nguyên tới từng bit. Nhân với số âm thì a·b đổi dấu, cosine đổi dấu, và góc lấy phần bù: a (3, 1) với (1, 3) cho 53.1°, còn với (-1, -3) cho 126.9°, hai số cộng lại đúng 180, và a·b từ 6 thành -6.

Ba câu vừa rồi nghe như ba đẳng thức, nhưng chỉ có câu đầu gần đúng như thế, và đây là chỗ đặc tả tôi được giao đã nói quá. Cổng kiểm quét 342732 mẫu, gồm cả nhân với số âm và nhân với 0:

  • a·(t*b) không luôn đúng bằng t nhân a·b. Nó bằng tới mức làm tròn, lệch nhiều nhất 3.9622495554669397e-16 so với cỡ của chính đại lượng, và chỉ 279768 trong 342732 mẫu là giống nhau tới từng bit. Phản ví dụ cụ thể: với a (-5.6, -5), b (-5, 5.6)t bằng -3, vế phải bằng đúng 0a·b bằng đúng 0, còn vế trái bằng -1.4210854715202004e-14. Nghĩa là một phép kiểm đo sai số tương đối ở chỗ đó sẽ ra một con số vô nghĩa, và bất biến này buộc phải phát biểu theo cỡ |t| · |a| · |b|.
  • Cosine cũng không giữ nguyên tới từng bit khi t dương. Nó giữ tới hai đơn vị cuối, 4.440892098500626e-16, và giống nhau bit-y-nguyên ở 120061 trong 169344 mẫu. Phản ví dụ: a (-5.6, -5.6) với b (3, 3) cho cosine -0.9999999999999996, nhân b với 2.5 thì nó thành đúng -1. Cả hai in ra -1.00, nên câu đúng là ô đọc kết quả không đổi, chứ không phải cái số thực bên dưới không đổi.
  • Với t âm, cosine đổi dấu, cũng tới hai đơn vị cuối, giống nhau bit-y-nguyên ở 91837 trong 141120 mẫu. Riêng t bằng -1 thì đổi dấu chính xác, vì phép đổi dấu của số thực là phép chính xác và độ dài của -b bằng độ dài của b không sai bit nào.
  • Góc bù thì lỏng nhất: lệch nhiều nhất 1.7075472840133443e-6 độ, và chỉ 53007 trong 141120 mẫu giống nhau tới từng bit. Vẫn là acos gây ra, và vì ô đọc kết quả làm tròn tới một phần mười độ nên bạn không thấy.
  • Nhân với 0 là ca riêng, và nó phải được nói ra thay vì gộp vào câu trên. Ở 28561 mẫu có t bằng 0, a·b bằng đúng 0, nhưng cosine và góc là NaN, không phải một con số: một vector độ dài 0 không có hướng nên không có góc nào để đo. Ô đọc kết quả hiện dấu gạch ngang chứ không hiện NaN.

Cosine similarity: bỏ độ lớn đi thì còn lại hướng

Bảng ở mục trên chính là lý do người ta hay dùng cosine chứ không dùng tích vô hướng để so hai đối tượng. Ba vector b cùng hướng cho ba tích vô hướng khác nhau, 3, 612, chỉ vì chúng dài khác nhau. Chia cho hai độ dài thì cả ba cho cùng một cosine 0.60, và trên máy là cùng một số thực 0.5999999999999999, không lệch một bit.

Đó là toàn bộ nội dung của cái tên cosine similarity: nó là tích vô hướng đã chia cho hai độ dài, nên nó chỉ còn nhìn hướng. Khi so hai văn bản, mỗi văn bản thành một vector đếm từ, và một văn bản dài gấp mười một văn bản khác thì mọi thành phần của nó lớn gấp khoảng mười lần. Tích vô hướng sẽ nói văn bản dài giống mọi thứ hơn, chỉ vì nó dài. Cosine bỏ được đúng ảnh hưởng đó.

Cổng kiểm quét bất biến này trên 30072 cặp đã đổi độ dài mà vẫn nằm trên lưới: 29424 cặp giữ cosine tới từng bit, phần còn lại lệch nhiều nhất 3.3306690738754696e-16. Nên phát biểu đúng là cosine bỏ được ảnh hưởng của độ lớn tới mức làm tròn.

Nói cho công bằng, sim này không có văn bản nào. Nó có hai mũi tên trong mặt phẳng, và mọi câu ở trên về văn bản là cùng một phép tính trên vector dài hơn, chứ không phải điều mà cổng kiểm chứng minh được. Cổng chỉ canh phép tính.

Nút "đặt b vuông a" từng nói dối, và cách chữa

Nút ⟂ Đặt b vuông a trong sim này có một chỗ hỏng thật, phát hiện trong lúc viết cổng kiểm, và nó minh hoạ rất đúng bài học "kẹp giá trị thì phải báo, đừng âm thầm sửa".

Bản cũ làm ba việc: quay a đi 90°, co giãn về đúng độ dài của b, rồi kẹp từng toạ độ một cho khỏi ra ngoài khung. Bước thứ ba là chỗ chết. Kẹp một toạ độ mà không kẹp toạ độ kia thì hướng đổi, và cái vector trả về không còn vuông với a nữa. Kéo a tới (1, 5.5)b tới (5.6, 5.6) rồi bấm nút: bản cũ trả về (-5.6, 1.4), và a·b ở đó bằng 2.0999999999999996, in ra 2.1. Tức là ô a·b đọc 2.1 ngay bên cạnh một cái nút vừa tuyên bố đã đặt vuông góc. Ca tệ nhất đo được là a (-5.5, -2.3) với b (-5.6, -5.6), ở đó a·b bằng -4.170000000000002. Trên 28392 cấu hình mà nút nhận, bản cũ không vuông góc ở 18572 cấu hình.

Bản hiện tại dựng hướng bằng số nguyên nên không có bước làm tròn nào. Với toạ độ đo theo bước 0.1, vector (-a_y, a_x) chia cho ước chung lớn nhất của a_xa_yvector lưới ngắn nhất vuông chính xác với a, và mọi vector lưới vuông với a đều là một bội nguyên của nó. Nút chỉ việc chọn bội số nào có độ dài gần |b| nhất mà vẫn nằm trong khung. Kết quả: trên cả 28392 cấu hình, a·b bằng 0 theo số học chính xác, 25936 cấu hình cho 0 bằng đúng số thực, và phần còn lại lệch nhiều nhất 7.105427357601002e-15, vẫn nằm sâu trong cửa sổ 0.

Còn hai chỗ nút này từ chối làm im lặng. Nếu a đang là vector 0 thì nó không có hướng nào, nên không có hướng nào vuông với nó: nút giữ nguyên b và hiện một dòng nói lý do. Nếu độ dài của b không lọt trong khung theo hướng vuông đó thì nút rút ngắn b, nhưng hiện một dòng nói đã rút về bao nhiêu, thay vì lặng lẽ đổi một thứ mà bạn không yêu cầu đổi. Ở ca a (1, 5.5) với b (5.6, 5.6) bản mới trả về (-5.5, 1) kèm dòng thông báo đó, và a·b bằng đúng 0.

Tích vô hướng chính là phép tính của một nơ-ron

Một nơ-ron làm đúng một việc trước khi đi qua hàm kích hoạt: lấy tổng có trọng số của đầu vào. Với trọng số w và đầu vào x, tổng đó là w_1 x_1 + w_2 x_2 + ..., mà đó chính là w·x. Không có phép tính mới nào, chỉ có tên gọi mới.

Lấy w (2, -1)x (3, 1) thì nơ-ron tính 2 * 3 + (-1) * 1 = 5. Đổi đầu vào sang x (1, 2) thì nó tính ra 0, và (1, 2) đúng là vector vuông với (2, -1). Nói cách khác, tập đầu vào làm nơ-ron ra đúng 0 chính là đường thẳng vuông với vector trọng số, và đó là biên quyết định của nơ-ron đó. Lệch một bước lưới sang một bên thì tổng dương, sang bên kia thì âm.

Ba mốc ở mục trên vì thế đọc lại được bằng ngôn ngữ học máy: trọng số cùng hướng với đầu vào thì nơ-ron kêu to nhất, vuông góc thì nó im, ngược hướng thì nó kêu về phía âm. Khi tới bài nơ-ron và lan truyền xuôi bạn sẽ thấy đúng phép tính này chạy trong từng ô của mạng, còn bài ma trận là phép biến hình kế bên nhìn cùng một bảng số theo góc khác: không phải chấm điểm, mà là dời cả mặt phẳ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à 323 khẳng định, và cổng không tin phép tính của chính engine. Nó dựng lại kết quả bằng ba đường độc lập.

Đường thứ nhất tính |a| · |b| · cos(θ_a - θ_b), với mỗi góc lấy từ atan2 của từng vector. Đường này không dựng một tích số toạ độ nào, nên nó không thể thừa hưởng sai sót của cách kia. Trên 28561 cấu hình, hai đường lệch nhau nhiều nhất 3.907985046680551e-14 xét tuyệt đối, và 1.020676881648482e-15 xét theo cỡ |a| · |b|. Chúng giống nhau tới từng bit ở 7385 cấu hình, tức khoảng một phần tư, và một con số 0 ở chỗ này mới là điều đáng lo: nó sẽ có nghĩa hai đường thật ra là một đường.

Đường thứ hai là đường chính xác. Mọi toạ độ kéo tới được đều là một số nguyên lần 0.1, nên cổng đổi toạ độ thành số nguyên, nhân và cộng trong số nguyên, rồi chia cho 100 đúng một lần ở cuối. Đường này không có một phép tính dấu phẩy động nào trên toạ độ, nên nó là đường duy nhất nói được rằng một đáp án số thực đúng chứ không chỉ là khớp với một đáp án số thực khác. Kết quả đo: engine cho đúng giá trị chính xác ở 19762 trong 28561 cấu hình, và sai một bước làm tròn ở 8799 cấu hình còn lại, nhiều nhất là 7.105427357601002e-15.

Đường thứ ba dùng đẳng thức (|a+b|² - |a|² - |b|²) / 2. Nó mất độ chính xác ở chỗ khác hai đường trên, vì nó trừ hai số lớn cho nhau, và đo được là nó lệch nhiều nhất 7.401709227938762e-15 theo cỡ |a| · |b|, tức gấp bảy lần đường thứ nhất.

Cổng còn tự phá engine rồi đòi chính mình báo đỏ. Năm đột biến đã thử: đổi dấu cộng trong tích vô hướng thành dấu trừ, nới cửa sổ 0 từ 1e-9 lên 0.5, đổi một toạ độ mặc định, bỏ miếng vá miền của acos, và bỏ bước chia cho ước chung lớn nhất trong nút đặt vuông góc. Cả năm đều làm cổng đỏ, và hoàn nguyên thì cổng xanh 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 vector do bạn kéo, không phải do mô hình nào tìm ra. Không câu nào ở đây nói rằng tích vô hướng là độ đo giống nhau tốt cho một bài toán cụ thể, vì đó là chuyện của dữ liệu chứ không phải của phép tính. Và các số thực trong sim chỉ có một chữ số thập phân nên nó là một mô hình rất sạch của bài toán thật, nơi toạ độ 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

Tích vô hướng là nhân từng cặp toạ độ rồi cộng, và nó bằng |a| · |b| · cos θ, nên với hai độ dài đã cho nó đo đúng một thứ: hai vector cùng hướng tới đâu. Ba mốc: cùng hướng cho giá trị lớn nhất, vuông góc cho 0, ngược hướng cho số đối của mốc đầu. Trên số thực thì mốc 0 cần một cửa sổ chứ không cần dấu bằng: trong 480 cặp vuông góc trên lưới, 472 cặp cho đúng 0 còn 8 cặp cho 5.551115123125783e-17, và a (3, 1) với b (0.1, -0.3) là một trong tám cặp đó. Nhân b với số dương thì a·b đổi theo tỉ lệ mà góc không đổi, nên chia cho hai độ dài sẽ được cosine similarity: b (0.5, 1.5), (1, 3)(2, 6) cho a·b bằng 3, 612 nhưng cosine đều là 0.60. Và đây là phép tính của một nơ-ron: w (2, -1) với x (3, 1) cho 5, còn đầu vào cho 0 là đầu vào nằm trên biên quyết định.

Câu hỏi tự kiểm0/3 đúngchưa trả lời
  1. 1Giữ a (3, 1) rồi kéo b tới (0.1, -0.3). Cặp này vuông góc chằn chặn: 3 nhân 0,1 cộng 1 nhân trừ 0,3 bằng 0. Engine trả về gì cho a·b?
  2. 2Ba vector b là (0.5, 1.5), (1, 3) và (2, 6) đều cùng hướng, chỉ khác độ dài. Với a (3, 1) thì hai đại lượng a·b và cos θ hành xử thế nào?
  3. 3Nút "đặt b vuông a" bản cũ quay a đi 90 độ, co giãn về độ dài của b, rồi kẹp từng toạ độ cho khỏi ra ngoài khung. Bước kẹp đó gây ra chuyện gì?