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

Kênh và tích chập 1 × 1

Bộ lọc là khối 3 chiềuĐếm tham số thậtTách theo chiều sâuBóp rồi nở

Kênh và tích chập 1 × 1

Chiều mà sinh viên hay bỏ quên. Hiểu đúng chiều kênh thì phần lớn mẹo làm nhẹ mạng tự nhiên sáng ra.

Trong bài phép tích chập bạn đã trượt một nhân 3x3 trên một ảnh xám và thấy mỗi ô đầu ra sinh ra từ chín phép nhân rồi cộng. Ảnh xám chỉ có một kênh, nên ở đó bộ lọc đúng là một ô vuông phẳng. Từ lớp thứ hai trở đi thì không còn như vậy nữa: khối vào dày lên tới 64, 256, có khi cả nghìn kênh, và một bộ lọc phải dày đúng bằng khối vào.

Đây là chỗ hiểu sai phổ biến nhất. Một bộ lọc của lớp tích chập 3x3 trên khối vào 64 kênh không có 9 trọng số, nó có 3 x 3 x 64 = 576 trọng số. Nó là một khối ba chiều, trượt trên khối vào, ở mỗi vị trí nhân từng phần tử với cả 64 lát rồi cộng tất cả lại thành đúng một con số. Muốn 128 kênh ra thì cần 128 khối như thế. Sim dưới đây cho bạn đổi mọi con số trong câu vừa rồi và xem hoá đơn tham số tính lại ngay.

Chiều kênh · một bộ lọc là một khối, và vì sao 1 × 1 lại rẻ đến thế
thường: 73.728 tham số · 1,00× so với thường
Khối giữa 64 → 128
Hình dạng hay gặp ở giữa mạng: bản đồ 56 × 56, số kênh nhân đôi. Số nhóm để sẵn là 4 nên bạn thấy được cả kiểu theo nhóm mà không phải gõ gì.
Bài này chỉ nói về chiều kênh. Kích thước bản đồ ra là thứ bạn tự đặt ở hai ô cuối, vì cách suy ra nó từ bước nhảy và đệm là nội dung của bài số học kích thước đầu ra, không phải bài này. Ở đây bản đồ ra đang có 3.136 vị trí.
1 · Một bộ lọc không phải hình vuông, nó là một khối
3 × 3 × 64× 128bộ lọc như thếtổng 73.728 trọng số
Sinh viên hay hình dung bộ lọc là một ô vuông k × k phẳng. Không phải. Một bộ lọc của lớp này là một khối ba chiều 3 × 3 × 64, tức 576 trọng số cho một bộ lọc. Nó trượt trên khối vào, ở mỗi vị trí nhân từng phần tử với cả 64 lát rồi cộng hết lại thành một số. Một bộ lọc cho ra một kênh, nên muốn 128 kênh ra thì cần 128 khối như vậy.
Hình chỉ vẽ 5 lát trong 64 lát của khối, vì trần vẽ của sim là 5 lát. Con số bên cạnh vẫn tính trên đủ 64 lát.
2 · Bốn kiểu lớp trên cùng một cấu hình
Kiểu lớpThành phầnTrọng sốBiasTổng tham sốPhép nhân cộngSo với thường
Tích chập thường k × k
tích chập thường k × k128 × 64 / 1 × 3 × 373.728
73.728073.728231,21 M1,00×bớt 0,0%
Tích chập 1 × 1
tích chập 1 × 1 (điểm)128 × 64 / 1 × 1 × 18.192
8.19208.19225,69 M9,00×bớt 88,9%
Tách theo chiều sâu
tích chập theo chiều sâu k × k64 × 64 / 64 × 3 × 3576
tích chập 1 × 1 (điểm)128 × 64 / 1 × 1 × 18.192
8.76808.76827,50 M8,41×bớt 88,1%
Theo nhóm
tích chập theo nhóm k × k128 × 64 / 4 × 3 × 318.432
18.432018.43257,80 M4,00×bớt 75,0%
trọng số = C_out × (C_in / g) × k × k, với g = 1 cho kiểu thườngphép nhân cộng = trọng số × 56 × 56 = trọng số × 3.136
Mỗi bộ lọc nhìn cả một vùng k × k trên toàn bộ C_in kênh. Đắt nhất, và là mốc để so mọi kiểu còn lại.
3 · Kênh nào nối với kênh nào
vào 8ra 8
chặng 1: tích chập thường k × k64 đường nối được vẽ
Hình là bản thu nhỏ giữ nguyên cấu trúc: đang vẽ 8 trong 64 kênh vào, 8 trong 128 kênh ra. Trần vẽ là 64 đường nối, quá số đó thì hình chỉ còn là một mảng xám. Mọi con số trong bảng vẫn tính trên kích thước thật.
4 · Luật tiết kiệm của tách theo chiều sâu
Tách sâu / thường = (C_in × k² + C_in × C_out) / (C_out × C_in × k²) = 1/C_out + 1/k²1/128 + 1/9 = 0,118924
Bội số tiết kiệm, lấy từ hai bộ đếm trọng số ở bảng trên8,41×
Cũng bội số đó, lấy từ nghịch đảo công thức đóng. Hai đường tính khác nhau nên chúng phải trùng nhau8,41×
Trần khi C_out lớn dần: 1/C_out tắt dần, còn lại k² = 99,00×
Con số này phụ thuộc k, nó không phải hằng số 8 hay 9 như nhiều bài viết nói gọn. Với k = 3 thì bội số chỉ chạm 8 lần khi C_out đạt 72, và dù C_out có lớn tới đâu nó cũng không vượt 9.
kThườngTách sâuBội số tiết kiệmTrần k²
18.1928.2560,99×1
373.7288.7688,41×9
5204.8009.79220,92×25
7401.40811.32835,44×49
9663.55213.37649,61×81
11991.23215.93662,20×121
Đọc dòng k = 1: bội số bằng 0,99×, tức nhỏ hơn 1. Khi nhân đã là 1 × 1 thì tách ra chỉ tổ thêm việc, vì phần theo chiều sâu không còn gì để tách. Tiết kiệm sinh ra từ chỗ lớn, không phải từ phép tách.
5 · Bóp kênh bằng 1 × 1, làm việc nặng, rồi nở lại
Bóp 64 kênh xuống 16 kênh, làm 3 × 3 ở đó, rồi nở lên 128 kênh.
BướcCông thứcTrọng số
Bóp bằng 1 × 116 × 64 × 1 × 11.024
Nhân k × k trên kênh đã bóp16 × 16 × 3 × 32.304
Nở lại bằng 1 × 1128 × 16 × 1 × 12.048
Cả khốicộng ba dòng trên5.376
Một lớp k × k thẳng, cùng vào cùng ra128 × 64 × 3 × 373.728
Khối rẻ hơn lớp thẳng73.728 / 5.37613,71×
Cả khối ba lớp tốn 5.376 trọng số so với 73.728 của một lớp 3 × 3 thẳng, tức rẻ hơn 13,71×. Phép nhân cộng cũng theo tỉ lệ đó: 16,86 M so với 231,21 M. Đây là lý do tích chập 1 × 1 có mặt gần như trong mọi mạng hiện đại: nó là cái van đổi số kênh với giá rẻ.
6 · Cộng theo kênh, tính thật trên khối 4 × 4 × 2
Khối vào · kênh 0
1234567891234567
Khối vào · kênh 1
1010010110100101
Bộ lọc A · lát 0
10-110-110-1
Bộ lọc A · lát 1
000010000
Kênh 0: 1·1 + -1·3 + 1·5 + -1·7 + 1·9 + -1·23
Kênh 1: 1·11
Cộng 2 kênh lại thành một số, ô (0, 0)3 + 1 = 4
Kênh ra 0 · Bộ lọc A
4-63-5
Kênh ra 1 · Bộ lọc B
111157
Hai bộ lọc, mỗi cái là một khối 3 × 3 × 2, nên lớp này có 36 trọng số và cho ra 2 kênh, mỗi kênh 2 × 2. Chú ý dòng cộng ở trên: hai kênh vào không được giữ riêng, chúng bị cộng thành một số duy nhất. Đó là lý do khối ra chỉ dày bằng số bộ lọc, không dày bằng số kênh vào nhân số bộ lọc.
Cũng khối đó, nhưng bằng một bộ lọc 1 × 1
Kênh ra của bộ lọc 1 × 1 · 4 × 4
14581011141517236891213
Bộ lọc này chỉ có 2 trọng số, đúng bằng số kênh vào, so với 18 của một bộ lọc 3 × 3 × 2. Ở ô (0, 0) nó tính 2·1 + -1·1 = 1. Bản đồ ra giữ nguyên 4 × 4 vì cửa sổ rộng đúng một điểm, và mỗi ô chỉ nhìn đúng cột kênh nằm dưới nó. Không thấy hàng xóm, chỉ trộn kênh. Đổi hai trọng số trên và nhìn cả bản đồ đổi theo.
Sim này không đo được cái gì. Nó đếm tham số phép nhân cộng, hai đại lượng số học thuần, và hai đại lượng đó đúng từng chữ số. Nhưng tiết kiệm phép tính không tự động thành chạy nhanh hơn. Tích chập tách theo chiều sâu có tỉ lệ phép tính trên byte bộ nhớ kém hơn tích chập thường: nó đọc và ghi gần như cùng lượng dữ liệu nhưng làm ít việc hơn trên mỗi byte, nên trên GPU nó thường không nhanh lên đúng bằng bội số tham số mà bảng trên gợi ý. Con số 8 hay 9 lần là chuyện của bộ đếm, không phải chuyện của đồng hồ. Muốn biết nhanh chậm thật thì phải đo trên đúng phần cứng, đúng thư viện, đúng kích thước lô.
Hai điều nữa. Thứ nhất, sim không nói được kiểu nào học tốt hơn: ít tham số có thể là chính quy hoá tốt, cũng có thể là mất khả năng biểu diễn, và chỉ thực nghiệm trên dữ liệu mới phân xử được. Thứ hai, cách đếm bias ở đây là một quy ước: tôi tính một hệ số cho mỗi kênh ra của từng tích chập trong chuỗi, nên tách theo chiều sâu phải trả C_in + C_out. Nhiều mã nguồn thật bỏ bias ở lớp theo chiều sâu vì phía sau đã có lớp chuẩn hoá, và khi đó con số bias sẽ khác. Số trọng số thì không đổi.

Đọc bảng so sánh thế nào

Ở trạng thái mặc định, lớp đang xét là 64 kênh vào, 128 kênh ra, nhân 3x3, bản đồ ra 56 x 56. Bốn dòng trong bảng nói bốn chuyện khác nhau về cùng một nhiệm vụ: biến khối 64 kênh thành khối 128 kênh.

  • Tích chập thường tốn 128 x 64 x 3 x 3 = 73.728 trọng số. Mỗi kênh ra nhìn cả 64 kênh vào trên một vùng 3x3. Đây là mốc.
  • Tích chập 1 × 1 tốn 128 x 64 = 8.192 trọng số, đúng bằng một phần chín. Nó không nhìn hàng xóm nào cả, cửa sổ của nó rộng đúng một điểm. Việc duy nhất nó làm là trộn kênh.
  • Tách theo chiều sâu tốn 8.768 trọng số, gồm 64 x 9 = 576 cho phần chạy riêng từng kênh và 64 x 128 = 8.192 cho phần trộn kênh. Rẻ hơn 8,41 lần.
  • Theo nhóm với g = 4 tốn 18.432, đúng bằng một phần tư. Chia kênh thành bốn nhóm thì mỗi bộ lọc chỉ còn nhìn một phần tư số kênh vào.

Hai quan hệ đáng ghim vào đầu, và cả hai đều kiểm được ngay trên sim. Thứ nhất, đặt số nhóm về 1 thì dòng theo nhóm trùng khít dòng thường, từng chữ số. Thứ hai, đặt C_out = C_in rồi cho số nhóm bằng C_in thì tích chập theo nhóm chính là phần chạy riêng từng kênh của tách theo chiều sâu. Tích chập theo nhóm không phải một họ riêng, nó là cái thước trượt giữa hai đầu mút quen thuộc.

Bội số tiết kiệm không phải hằng số

Nhiều bài viết nói gọn rằng tách theo chiều sâu rẻ hơn khoảng tám tới chín lần. Con số đó có nguồn gốc rõ ràng, và nó phụ thuộc k:

(C_in x k² + C_in x C_out) / (C_out x C_in x k²) = 1/C_out + 1/k²

Nghịch đảo của tổng đó chính là bội số tiết kiệm. Khi C_out lớn dần thì 1/C_out tắt đi, chỉ còn 1/k², nên bội số tiến tới mà không bao giờ đạt tới. Với k = 3 trần đó là 9, và bội số đạt đúng 8 khi C_out bằng 72, và chỉ vượt 8 từ 73 trở lên. Hãy thử ca tính tay: chọn cấu hình mẫu lớp đầu 3 → 64, bạn sẽ thấy 64 x 3 x 3 x 3 = 1.728 trọng số cho tích chập thường, 27 + 192 = 219 cho tách theo chiều sâu, và bội số 7,89, tức chưa tới 8. Đổi k sang 5 rồi 7 và nhìn cột trần chạy theo. Ngược lại, đặt k = 1 thì bội số tụt xuống dưới 1: khi nhân đã là một điểm thì không còn gì để tách, tách ra chỉ tổ thêm việc. Tiết kiệm sinh ra từ chỗ lớn, không sinh ra từ phép tách.

Vì sao 1 × 1 lại có mặt ở khắp nơi

Một lớp 1x1 không nhìn thấy không gian, nghe qua thì có vẻ vô dụng. Nhưng nó đổi được số kênh với giá rẻ, và đó là thứ các kiến trúc hiện đại cần liên tục. Mẹo chuẩn là bóp rồi nở: dùng một 1x1 kéo 64 kênh xuống 16 kênh, làm phép 3x3 đắt tiền trên khối đã hẹp, rồi dùng một 1x1 nữa nở lên 128 kênh. Ở trạng thái mặc định của sim, cả khối ba lớp đó tốn 5.376 trọng số so với 73.728 của một lớp 3x3 thẳng, tức rẻ hơn 13,71 lần.

Hãy kéo tỉ lệ bóp về 1 để thấy chuyện gì xảy ra khi không bóp gì, và kéo lên bằng C_in để bóp xuống còn đúng một kênh. Đầu mút thứ nhất không cho một bài học một chiều, và đó mới là chỗ thú vị: ở cấu hình mặc định 64 vào 128 ra, tỉ lệ bóp 1 vẫn rẻ hơn 1,5 lần vì hai lớp 1x1 gánh việc đổi kênh; nhưng đổi sang cấu hình mẫu tầng sâu 256 → 256 rồi đặt tỉ lệ bóp về 1 thì khối ba lớp đắt hơn lớp thẳng và sim báo lỗ. Đầu mút thứ hai thì rõ một chiều: bóp xuống một kênh rẻ tới mức vô lý, nhưng khối giữa gần như không còn chỗ chứa thông tin. Sim đếm được cái giá, nhưng không đếm được cái mất, và đó là ranh giới cần nhớ.

Cộng theo kênh, nhìn tận mắt

Mục cuối của sim tính thật trên một khối 4 x 4 x 2 với hai bộ lọc cố định. Chọn một vị trí đầu ra và bạn thấy hai dòng riêng, mỗi dòng là tổng của chín tích trên một kênh, rồi một dòng cuối cộng hai dòng đó lại. Chính bước cộng cuối cùng là lý do khối ra chỉ dày bằng số bộ lọc, chứ không dày bằng số kênh vào nhân số bộ lọc. Hai kênh vào không được giữ riêng, chúng bị gộp mất.

Ngay dưới đó là cùng khối ấy nhưng qua một bộ lọc 1x1 chỉ có hai trọng số. Đổi hai trọng số và cả bản đồ 4 x 4 đổi theo, trong khi kích thước bản đồ không hề suy suyển. Đó là toàn bộ tính cách của 1x1: không thấy hàng xóm, chỉ trộn kênh.

Điều rút ra

Một bộ lọc là khối k x k x C_in và có C_out khối như thế, nên số trọng số là C_out x C_in x k². Tích chập 1x1 bỏ hẳn chiều không gian nên rẻ hơn đúng lần và trở thành cái van đổi số kênh; tách theo chiều sâu rẻ hơn 1/(1/C_out + 1/k²) lần, một con số tiến tới chứ không phải hằng số 8. Chỉ có điều tiết kiệm phép tính không tự động thành chạy nhanh hơn.

Sim đếm được gì và không đếm được gì

Số tham số và số phép nhân cộng trong sim là số học thuần, đúng từng chữ số. Nhưng tách theo chiều sâu có tỉ lệ phép tính trên byte bộ nhớ kém hơn tích chập thường, nên trên GPU nó thường không nhanh lên đúng bằng bội số tham số. Và không có con số nào ở đây nói được kiểu nào học tốt hơn: ít tham số vừa có thể là chính quy hoá tốt, vừa có thể là mất khả năng biểu diễn.

Kiểm tra nhanh0/3 đúngchưa trả lời
  1. 1Một lớp tích chập nhân 3 × 3 nhận khối vào dày 64 kênh. MỘT bộ lọc của lớp đó có bao nhiêu trọng số?
  2. 2Với k = 3, bội số tiết kiệm của tách theo chiều sâu so với tích chập thường sẽ ra sao khi C_out lớn dần?
  3. 3Điều gì là quan trọng nhất khi phân biệt tích chập 1 × 1 với tích chập 3 × 3?