Topik ini membahas pooling, yakni operasi peringkasan setiap jendela spasial menjadi satu nilai tanpa parameter yang dipelajari. Dua varian utamanya, max pooling dan average pooling, dibahas bersama efeknya terhadap shape serta perannya di dalam jaringan CNN.
Max pooling dan average pooling#
Max pooling memilih nilai tertinggi di dalam setiap jendela, sedangkan average pooling menghitung rata-ratanya. Keduanya dibuat dengan nn.MaxPool2d dan nn.AvgPool2d, dengan kernel_size dan stride sebagai argumen utamanya. Tidak ada bobot yang dipelajari di sini karena operasinya ditetapkan sepenuhnya oleh argumen tersebut, sebagaimana konvolusi menetapkan jendelanya, tetapi tanpa perkalian dengan bobot.
Contoh berikut memberikan tensor 4x4 yang isinya mudah diperiksa satu per satu kepada kedua layer, kemudian menguji efeknya pada tensor citra (2, 1, 28, 28).
import torch
import torch.nn as nn
# tensor 4x4 dengan nilai yang mudah diperiksa satu per satu
t = torch.arange(16, dtype=torch.float32).view(1, 1, 4, 4)
print("masukan 4x4:")
print(t[0, 0])
maks = nn.MaxPool2d(kernel_size=2, stride=2)
rata = nn.AvgPool2d(kernel_size=2, stride=2)
print("MaxPool2d 2x2:")
print(maks(t)[0, 0])
print("AvgPool2d 2x2:")
print(rata(t)[0, 0])
# efek pada shape: 28x28 menjadi 14x14
torch.manual_seed(0)
x = torch.rand(2, 1, 28, 28)
print("sebelum pooling :", tuple(x.shape))
print("sesudah MaxPool2d(2) :", tuple(maks(x).shape))
# pintu masuk arsitektur modern: rata-rata adaptif ke satu nilai per kanal
adaptif = nn.AdaptiveAvgPool2d((1, 1))
print("sesudah AdaptiveAvgPool2d :", tuple(adaptif(x).shape))masukan 4x4:
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.]])
MaxPool2d 2x2:
tensor([[ 5., 7.],
[13., 15.]])
AvgPool2d 2x2:
tensor([[ 2.5000, 4.5000],
[10.5000, 12.5000]])
sebelum pooling : (2, 1, 28, 28)
sesudah MaxPool2d(2) : (2, 1, 14, 14)
sesudah AdaptiveAvgPool2d : (2, 1, 1, 1)Jendela pertama pada bagian kiri atas memuat 0, 1, 4, dan 5, sehingga max pooling mengembalikan 5, sedangkan average pooling mengembalikan 2.5. Nilai 7, 13, dan 15 pada keluaran max pooling berasal dari tiga jendela lainnya. Diagram berikut memperlihatkan penyaringan yang sama secara visual.
Baris terakhir keluaran menunjukkan efek pada shape: tensor (2, 1, 28, 28) menjadi (2, 1, 14, 14) setelah MaxPool2d(2), sedangkan dimensi batch dan kanalnya tidak berubah.
Peran pooling pada jaringan CNN#
Peran pertama pooling adalah mengecilkan dimensi spasial. Layer konvolusi berikutnya menghitung jendelanya pada peta yang lebih kecil, sehingga komputasinya menurun, dan jumlah nilai yang dibawa ke head klasifikasi ikut mengecil. Pola ini memungkinkan jumlah kanal diperbesar setiap kali ukuran spasial membagi dua, misalnya 32 kanal pada 14x14 lalu 64 kanal pada 7x7, agar beban komputasi tetap terkendali.
Peran kedua adalah menambah toleransi terhadap geseran kecil. Karena hanya nilai maksimum jendela yang dibawa, pergeseran pola beberapa piksel sering kali tidak mengubah keluaran setiap jendela, sepanjang pola itu masih berada di dalam jendela yang sama. Sifat ini melengkapi kevarianan terhadap translasi yang dimiliki konvolusi.
Varian yang layak dikenal sejak dini adalah nn.AdaptiveAvgPool2d. Layer ini menghitung rata-rata hingga shape keluaran yang dituju, misalnya (1, 1) untuk satu nilai per kanal, tanpa perlu menghitung ukuran kernelnya sendiri. Keluaran (2, 1, 1, 1) pada program di atas adalah pintu masuk head klasifikasi yang tidak lagi bergantung pada ukuran citra masukan.
Kesalahan umum#
Kesalahan pertama adalah menganggap pooling menambah parameter. Kedua layer pooling tidak memiliki bobot maupun bias, sehingga penambahan pooling tidak mengubah jumlah parameter model sama sekali. Perhitungan sum(p.numel() for p in model.parameters()) memberikan angka yang sama dengan ataupun tanpa pooling.
Kesalahan kedua adalah menganggap pooling mengubah jumlah kanal. Kernel pooling bergerak pada setiap kanal secara terpisah, sehingga jumlah kanal keluaran selalu sama dengan jumlah kanal masukannya. Perubahan jumlah kanal adalah pekerjaan konvolusi, bukan pooling. Kesalahan ketiga yang berhubungan adalah mengharapkan pooling dengan kernel 3 dan stride 1 mempertahankan ukuran. Tanpa padding, 28x28 menjadi 26x26 karena rumus shape keluarannya sama dengan rumus konvolusi dua dimensi.
Ringkasan#
- Max pooling memilih nilai tertinggi setiap jendela, sedangkan average pooling menghitung rata-ratanya, dan keduanya tidak memiliki parameter.
MaxPool2d(2)membagi dua ukuran spasial, misalnya 28x28 menjadi 14x14, tanpa menyentuh dimensi batch dan kanal.- Pooling menurunkan komputasi layer berikutnya dan menambah toleransi terhadap geseran kecil.
AdaptiveAvgPool2d((1, 1))merangkas setiap kanal menjadi satu nilai dan menjadi pintu masuk head klasifikasi modern.
Referensi#
- torch.nn.MaxPool2d — PyTorch — Dokumentasi max pooling beserta nilai bawaan stride-nya.
- torch.nn.AvgPool2d — PyTorch — Dokumentasi average pooling dua dimensi.
- torch.nn.AdaptiveAvgPool2d — PyTorch — Dokumentasi pooling adaptif dengan bentuk keluaran yang ditentukan sendiri.