Topik ini membahas mekanika nn.Conv2d, yaitu argumen-argumen utamanya, rumus shape keluaran, dan bentuk bobot yang tersimpan di dalamnya. Setelah membacanya, shape keluaran sebuah layer konvolusi dapat diprediksi tanpa menjalankan program, dan ketidakcocokan shape antara layer dapat dihindari sejak penulisan kelas.
Argumen utama Conv2d#
Layer konvolusi dua dimensi dibuat dengan nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding). Tabel berikut merangkum arti setiap argumen beserta nilai yang umum digunakan.
| Argumen | Arti | Nilai yang umum |
|---|---|---|
in_channels | jumlah kanal masukan | 1 untuk grayscale, 3 untuk RGB, atau kanal keluaran layer sebelumnya |
out_channels | jumlah filter, sekaligus jumlah kanal keluaran | 16, 32, 64, dan seterusnya, naik per blok |
kernel_size | ukuran sisi kernel | 3 atau 5 |
stride | jarak pergeseran jendela per langkah | 1 atau 2 |
padding | jumlah baris dan kolom nol di setiap sisi | 0 atau 1 |
Argumen stride menentukan seberapa jauh jendela melompat setiap langkahnya, sedangkan padding menambahkan bingkai nol di tepi citra agar shape keluaran dapat dijaga. kernel_size, stride, dan padding menerima satu bilangan untuk kedua dimensi spasial maupun pasangan bilangan untuk tinggi dan lebar yang berbeda. Pemanggilan nn.Conv2d(1, 16, 3) tanpa argumen lain sama dengan nn.Conv2d(1, 16, kernel_size=3, stride=1, padding=0) karena nilai bawaan stride adalah 1 dan padding adalah 0.
Rumus shape keluaran#
Shape keluaran konvolusi mengikuti satu rumus yang berlaku untuk dimensi tinggi maupun lebar. Dengan ukuran masukan, ukuran kernel, stride, dan padding, ukuran keluarannya adalah:
Tanda lantai berarti pembulatan ke bawah. Jendela yang tidak muat penuh di akhir baris tidak dihitung, karena kernel hanya ditempatkan pada posisi yang seluruh isinya tersedia. Untuk citra 28x28 dengan kernel 3, stride 1, dan padding 1, hitungannya , sehingga shape-nya dipertahankan. Mengganti stride menjadi 2 memberikan , yaitu tepat setengah ukuran awal.
Verifikasi numerik dengan Conv2d#
Rumus tersebut dapat diverifikasi dengan memberikan tensor nol 28x28 kepada beberapa kombinasi layer, kemudian membandingkan shape aktualnya dengan prediksi rumus.
import torch
import torch.nn as nn
def prediksi(h_in, k, s, p):
# rumus shape keluaran Conv2d pada satu dimensi spasial
return (h_in + 2 * p - k) // s + 1
# satu citra grayscale 28x28, tanpa perhitungan acak
x = torch.zeros(1, 1, 28, 28)
print(f"masukan: {tuple(x.shape)}")
kombinasi = [
("kernel 3, stride 1, padding 1", 3, 1, 1),
("kernel 3, stride 2, padding 1", 3, 2, 1),
("kernel 5, stride 1, padding 0", 5, 1, 0),
("kernel 5, stride 2, padding 2", 5, 2, 2),
]
for label, k, s, p in kombinasi:
conv = nn.Conv2d(1, 8, kernel_size=k, stride=s, padding=p)
y = conv(x)
print(f"{label}: aktual {tuple(y.shape)}, rumus {prediksi(28, k, s, p)}")
# bentuk bobot dan bias sebuah layer konvolusi
conv = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, padding=1)
print("bobot (out, in, k, k):", tuple(conv.weight.shape))
print("bias :", tuple(conv.bias.shape))
print("jumlah parameter :", sum(p.numel() for p in conv.parameters()))masukan: (1, 1, 28, 28)
kernel 3, stride 1, padding 1: aktual (1, 8, 28, 28), rumus 28
kernel 3, stride 2, padding 1: aktual (1, 8, 14, 14), rumus 14
kernel 5, stride 1, padding 0: aktual (1, 8, 24, 24), rumus 24
kernel 5, stride 2, padding 2: aktual (1, 8, 14, 14), rumus 14
bobot (out, in, k, k): (16, 3, 3, 3)
bias : (16,)
jumlah parameter : 448Keempat baris pertama menunjukkan kecocokan penuh antara rumus dan Conv2d. Kombinasi kernel 3 dan padding 1 menjaga 28x28 dengan stride 1, sedangkan stride 2 membagi dua menjadi 14x14. Kernel 5 tanpa padding menggerus dua piksel pada setiap tepi, sehingga 28x28 menjadi 24x24, dan kombinasi kernel 5, stride 2, padding 2 menghasilkan 14x14. Perhatikan bahwa jumlah kanal keluaran selalu 8 sesuai argumen kedua, karena rumus spasial tidak menyentuh dimensi kanal.
Bentuk bobot dan bias#
Bobot layer konvolusi berbentuk (out_channels, in_channels, k, k), yaitu satu kernel untuk setiap pasangan kanal masukan dan kanal keluaran, sedangkan bias menambah satu angka per filter. Untuk nn.Conv2d(3, 16, 3), jumlah parameternya adalah , sebagaimana dicetak program di atas.
Angka 448 tidak memuat ukuran citra sama sekali. Jumlah parameter konvolusi hanya bergantung pada konfigurasi layer, sehingga layer yang sama dapat menerima citra 28x28 maupun citra 224x224 tanpa mengubah satu bobot pun. Inilah konsekuensi langsung dari pembagian bobot yang dibahas pada topik tentang alasan konvolusi.
Kesalahan umum#
Kesalahan yang paling sering adalah menghitung shape keluaran dengan saja, lalu melupakan pembagian stride dan pembulatannya. Untuk kombinasi 28x28, kernel 3, stride 2, dan padding 1, hitungan tanpa pembulatan memberi , sedangkan jawaban yang benar adalah 14 karena pembulatan ke bawah dilakukan sebelum menambah satu. Rumus lengkap dengan lantainya perlu digunakan setiap kali stride lebih besar dari 1.
Kesalahan kedua adalah menautkan in_channels secara keliru. Layer yang menerima keluaran layer sebelumnya harus mendeklarasikan kanal masukan yang sama dengan kanal keluaran layer sebelumnya. Ketidakcocokan seperti menyambungkan layer dengan 8 kanal keluaran ke layer yang menuntut 32 kanal masukan tidak terdeteksi saat penulisan kelas, melainkan baru muncul sebagai RuntimeError pada forward pertama. Kebiasaan mencetak shape setelah setiap layer pada saat pengembangan mempercepat penemuan ketidakcocokan semacam ini.
Ringkasan#
nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)menentukan jumlah filter, ukuran jendela, langkah pergeseran, dan bingkai nol.- Rumus berlaku untuk tinggi maupun lebar, dengan pembulatan ke bawah sebelum menambah satu.
- Padding 1 pada kernel 3 menjaga shape saat stride 1, sedangkan stride 2 membagi dua ukuran spasial.
- Bobot berbentuk
(out_channels, in_channels, k, k)dengan satu bias per filter, sehingga jumlah parameter tidak bergantung pada ukuran citra.
Referensi#
- torch.nn.Conv2d — PyTorch — Dokumentasi argumen, bentuk masukan dan keluaran, serta bentuk bobot Conv2d.
- torch.nn — PyTorch
— Indeks layer pada
torch.nnuntuk varian konvolusi lain sepertiConv1ddanConv3d.