Multilayer perceptron dari section Dasar Neural Network berhasil pada data tabular: beberapa fitur angka yang sudah diringkas manusia. Gambar adalah kasus berbeda karena ukurannya besar dan strukturnya spasial: makna sebuah piksel sangat bergantung pada piksel di sekitarnya. Convolutional Neural Network (CNN) adalah arsitektur yang dirancang khusus untuk memanfaatkan struktur lokal tersebut. Pada chapter ini kita bedah dua kelemahan fully connected layer pada gambar, lalu ukur sendiri perbedaan jumlah parameternya lewat demo NumPy.

Mengapa Fully Connected Gagal pada Gambar #

Fully connected layer menerima input berupa vektor datar. Sebelum gambar masuk ke layer jenis ini, gambar 64x64 piksel harus diratakan (flatten) menjadi 4.096 angka. Proses perataan tersebut menimbulkan dua masalah serius.

Pertama, jumlah parameter meningkat tajam seiring ukuran gambar. Setiap neuron hidden layer dihubungkan ke seluruh piksel, sehingga bobot yang harus dipelajari adalah jumlah_piksel x jumlah_neuron. Gambar 64x64 sudah menghasilkan jutaan parameter hanya untuk satu layer, padahal foto asli beresolusi jauh lebih besar.

Kedua, struktur spasial hilang. Setelah diratakan, layer tidak lagi tahu bahwa piksel pada baris 3 kolom 4 bersebelahan dengan piksel baris 3 kolom 5 — bagi layer tersebut, urutan fitur hanyalah urutan angka pada vektor. Padahal deteksi pola visual justru bergantung pada hubungan antar tetangga piksel. CNN menjawab kedua masalah ini dengan tiga ide kunci berikut.

Tiga Ide Kunci Convolution #

  • Koneksi lokal: setiap neuron hanya mengamati patch kecil pada gambar (misalnya area 3x3 piksel), bukan seluruh gambar. Pola visual seperti garis dan sudut memang bersifat lokal.
  • Weight sharing: satu kumpulan bobot kecil (kernel) digeser ke seluruh posisi gambar. Bobot yang sama mendeteksi pola yang sama di mana pun pola tersebut berada, sehingga jumlah parameter tidak lagi tergantung pada ukuran gambar dan model memperoleh sifat translation invariance.
  • Hierarki fitur visual: layer awal mendeteksi tepi dan bercak warna, layer tengah menggabungkannya menjadi tekstur dan bagian objek, layer akhir mengenali objek utuh. Hierarki ini dibedah mendalam pada chapter Feature Map .

Ketiga ide tersebut disusun menjadi arsitektur berulang berikut:

Blok Convolution + ReLU menghasilkan feature map, blok Pooling mengecilkan resolusinya, dan pasangan blok tersebut diulang beberapa kali sebelum fitur diratakan untuk klasifikasi akhir. Setiap komponen dibahas satu per satu pada chapter-chapter berikutnya di section ini.

Demo NumPy: Menghitung Parameter Kedua Gaya Layer #

Berkas param_fc_vs_conv.py membandingkan jumlah parameter kedua gaya layer pada input yang sama. Skrip ini murni aritmetika NumPy tanpa pelatihan model apa pun, sehingga selesai dalam hitungan detik:

python
"""Perbandingan jumlah parameter: fully connected vs convolution pada gambar 64x64."""

import numpy as np

np.random.seed(42)

H, W = 64, 64

# ===== Layer fully connected =====
# Setiap piksel dihubungkan ke setiap neuron: bobot = input x neuron.
jumlah_input = H * W
jumlah_neuron = 1000

bobot_fc = jumlah_input * jumlah_neuron
param_fc = bobot_fc + jumlah_neuron
print("=== Fully connected: 64x64 grayscale -> 1000 neuron ===")
print(f"bobot  : {jumlah_input} x {jumlah_neuron} = {bobot_fc:,}")
print(f"bias   : {jumlah_neuron}")
print(f"total  : {param_fc:,} parameter")

# Alokasi nyata agar ukurannya terasa
w_fc = np.zeros((jumlah_neuron, jumlah_input), dtype=np.float32)
print(f"memori : {w_fc.nbytes / 1e6:.1f} MB (float32)")

# ===== Layer convolution =====
# 32 filter berukuran 5x5; satu set bobot dipakai ulang di seluruh posisi.
jumlah_filter = 32
K = 5

bobot_conv = jumlah_filter * K * K
param_conv = bobot_conv + jumlah_filter
print()
print("=== Convolution: 32 filter 5x5 ===")
print(f"bobot  : {jumlah_filter} x {K}x{K} = {bobot_conv}")
print(f"bias   : {jumlah_filter}")
print(f"total  : {param_conv} parameter")

w_conv = np.zeros((jumlah_filter, K, K), dtype=np.float32)
print(f"memori : {w_conv.nbytes / 1e3:.1f} KB (float32)")

# ===== Ukuran spasial keluaran convolution =====
H_out = (H - K) + 1
W_out = (W - K) + 1
print(f"feature map keluaran: {jumlah_filter} x {H_out} x {W_out} "
      f"(tinggi x lebar tetap besar, parameter tetap kecil)")

# ===== Variasi input: RGB 64x64 dan RGB 224x224 =====
print()
print("=== Variasi input (FC: 1000 neuron, conv: 32 filter 5x5) ===")
variasi = [("RGB 64x64 ", 3, 64, 64), ("RGB 224x224", 3, 224, 224)]
for label, C, Hi, Wi in variasi:
    input_fc = C * Hi * Wi
    fc = input_fc * jumlah_neuron + jumlah_neuron
    cv = jumlah_filter * (C * K * K) + jumlah_filter
    rasio = fc / cv
    print(f"{label}: FC = {fc:>12,} | conv = {cv:>6,} | rasio = {rasio:,.0f}x")

Output yang Dihasilkan:

text
=== Fully connected: 64x64 grayscale -> 1000 neuron ===
bobot  : 4096 x 1000 = 4,096,000
bias   : 1000
total  : 4,097,000 parameter
memori : 16.4 MB (float32)

=== Convolution: 32 filter 5x5 ===
bobot  : 32 x 5x5 = 800
bias   : 32
total  : 832 parameter
memori : 3.2 KB (float32)
feature map keluaran: 32 x 60 x 60 (tinggi x lebar tetap besar, parameter tetap kecil)

=== Variasi input (FC: 1000 neuron, conv: 32 filter 5x5) ===
RGB 64x64 : FC =   12,289,000 | conv =  2,432 | rasio = 5,053x
RGB 224x224: FC =  150,529,000 | conv =  2,432 | rasio = 61,895x

Mari kita telaah kode di atas baris per baris:

  1. Baris 7 (H, W = 64, 64): ukuran gambar contoh dipatok 64x64 piksel grayscale — cukup kecil untuk diinspeksi, cukup besar untuk menunjukkan polanya.
  2. Baris 11-15: layer fully connected membutuhkan bobot 4096 x 1000 ditambah 1 bias per neuron, total 4.097.000 parameter hanya untuk satu layer transisi.
  3. Baris 22-23: alokasi array nyata np.zeros((1000, 4096)) memperlihatkan biaya memorinya: 16.4 MB untuk bobot satu layer, sebelum optimizer menyimpan state tambahan berukuran serupa.
  4. Baris 27-31: layer convolution dengan 32 filter 5x5 hanya membutuhkan 32 x 5 x 5 = 800 bobot ditambah 32 bias, total 832 parameter — angka ini tidak berubah sebesar apa pun ukuran gambar yang diproses.
  5. Baris 42-45: keluaran spasial convolution tetap besar (32 x 60 x 60), artinya CNN memang menukar parameter raksasa dengan komputasi geser pada seluruh posisi gambar.
  6. Baris 50-56: pada input RGB 224x224 (ukuran ImageNet), fully connected membutuhkan 150.529.000 parameter sedangkan convolution tetap 2.432 — rasio hampir 62.000x.

Rangkuman Perbandingan #

AspekFully connectedConvolution
Parameter (64x64, konfigurasi demo)4.097.000832
Struktur spasialhilang setelah flattendipertahankan
Bobot antar posisitiap posisi punya bobot sendiridibagi ke seluruh posisi
Ukuran input berubahparameter ikut berubahparameter tetap
Objek bergeserpola harus dipelajari ulangterdeteksi kernel yang sama

Dokumentasi resmi seluruh layer CNN di PyTorch tersedia di docs.pytorch.org/docs/stable/nn.html , sedangkan materi visual paling lengkap untuk pendalaman adalah catatan kuliah CS231n Stanford . Sebelum menyentuh layer convolution di PyTorch, kita perlu berkenalan dulu dengan objek yang diprosesnya: gambar sebagai tensor berdimensi tiga — pembahasan itu menjadi fokus chapter Representasi Gambar .