7. ünite / 10
Evrişimli sinir ağları (CNN)
Evrişim katmanı, çekirdek, adım, dolgu, genişleme; havuzlama; alıcı alan; öznitelik haritaları; küçük bir MNIST CNN'i.
Bu ünitenin sonunda
- Conv2d çıkış boyunu formülle hesaplamak
- Evrişimin tam bağlı katmana göre neden çok daha az parametreyle görüntüde iyi çalıştığını açıklamak
- Havuzlama ve derinliğin alıcı alanı nasıl büyüttüğünü göstermek
- Eğitilmiş bir ağın öznitelik haritalarını kancayla çıkarıp yorumlamak
Ders notları
OpenCV dersinde çekirdekleri elle seçtik (Sobel, Gauss). CNN'de çekirdeklerin sayıları öğrenilir. Bir Conv2d(cin, cout, k) katmanı cout tane k×k×cin çekirdek içerir; her biri tüm görüntü üstünde kayar ve bir öznitelik haritası üretir.
n giriş boyu, k çekirdek, s adım (stride), p dolgu (padding), d genişleme (dilation). 3×3 çekirdek ve p = 1 boyu korur; s = 2 yarıya indirir.
Neden evrişim?
- Ağırlık paylaşımı: aynı çekirdek her konumda kullanılır; 28×28 bir görüntüde 3×3 çekirdek 9 ağırlıktır, tam bağlı bir nöron 784.
- Yerellik: komşu pikseller ilişkilidir; çekirdek yerel desenleri (kenar, köşe) yakalar.
- Kaymaya eşdeğerlik: nesne kayarsa öznitelik haritası da kayar.
Havuzlama ve derinlik
MaxPool2d(2) her 2×2 bölgeden en büyüğünü alır: boy yarıya iner, küçük kaymalara dayanıklılık artar. Katmanlar derinleştikçe bir nöronun gördüğü girdi bölgesi (alıcı alan) büyür: ilk katman kenar, sonrakiler kenar birleşimleri (köşe, eğri), en sonuncular parça ve nesne desenleri öğrenir. Bu derste eğittiğimiz küçük ağ (9 098 parametre) MNIST'te %98,6 doğruluğa ulaşır.
Görselleştiriciler
Evrişim aritmetiği: çekirdek, adım, dolgu, genişleme
Giriş boyu, çekirdek, adım (stride), dolgu (padding) ve genişlemeyi (dilation) değiştir: çekirdek giriş üstünde kayar, çıkış boyu formülle ve ızgarada birlikte görünür. Havuzlama da aynı formülü kullanır.
Öznitelik haritaları: eğitilmiş CNN'in içi
Bir rakam çiz. MNIST'te eğitilmiş küçük CNN'in (bitirme defteriyle eğitildi) ilk evrişim katmanının 8 çekirdeği, 8 öznitelik haritası ve havuzlamadan sonraki 16 harita gösterilir. Hesap tarayıcıda, aynı ağırlıklarla.
CNN katmanları 3B
Bir rakam çiz: girdi, conv1 (8 harita), pool1, conv2 (16 harita) ve pool2 derinlik boyunca art arda dizilir. Haritalar küçülürken sayıları artar; ağ uzamsal bilgiyi kanallara taşır. Hesap tarayıcıda, eğitilmiş ağırlıklarla.
Kendin dene
Evrişim aritmetiği aracında n = 7, k = 3 ile başla; adımı 2, dolguyu 1 yap ve çıkış boyunu önce formülle hesapla. Genişlemeyi 2 yap: çekirdek girdi üstünde nasıl seyreldi? Öznitelik haritaları aracında 1, 7 ve 0 çiz: ilk katmanın hangi haritaları yatay, hangileri dikey kenarlara tepki veriyor? Rakamı kutunun köşesine çizince tahmin değişiyor mu?
Kod
import torch
from torch import nn
class KucukCNN(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 8, 3, padding=1) # 28×28 → 28×28 (padding=1)
self.conv2 = nn.Conv2d(8, 16, 3, padding=1)
self.pool = nn.MaxPool2d(2) # boyu yarıya indirir
self.fc = nn.Linear(16 * 7 * 7, 10)
def forward(self, x):
x = self.pool(torch.relu(self.conv1(x))) # (N, 8, 14, 14)
x = self.pool(torch.relu(self.conv2(x))) # (N, 16, 7, 7)
return self.fc(x.flatten(1)) # (N, 10)
model = KucukCNN()
print(sum(p.numel() for p in model.parameters())) # 80 + 1168 + 7850 = 9098
# öznitelik haritası: ara katmanın çıktısını kanca (hook) ile yakala
maps = {}
model.conv1.register_forward_hook(lambda m, i, o: maps.__setitem__('conv1', o.detach()))
model(torch.randn(1, 1, 28, 28))
print(maps['conv1'].shape) # torch.Size([1, 8, 28, 28])Colab defteri
PyTorch tarayıcıda çalışmaz; gerçek kodu Google Colab'da (ücretsiz GPU ile) çalıştır. Defteri indir, colab.research.google.com adresinde "Dosya → Not defteri yükle" ile aç, "Çalışma zamanı → Çalışma zamanı türünü değiştir → T4 GPU" seç ve hücreleri sırayla çalıştır.
Defteri indir (.ipynb)Sık yapılan hatalar
- Girdiyi (N, H, W, C) sırasıyla vermek: PyTorch (N, C, H, W) ister; NumPy/PIL'den gelen görüntüde permute(0, 3, 1, 2) gerekir.
- Tek görüntüyü yığın boyutu olmadan vermek: x.unsqueeze(0) ile (1, C, H, W) yap.
- Eğitimdeki normalleştirmeyi (ortalama, std) çıkarımda unutmak: tahminler anlamsızlaşır.
- Havuzlamayla boyu tek sayıya düşürüp sonraki katmanın boyunu yanlış hesaplamak: 7 → MaxPool2d(2) → 3 (taban alınır).
Yazılım mühendisliği bağlantısı
CNN mimarisi de kod gibi gözden geçirilmelidir: her katmanın neden orada olduğu ve çıkış şekli belgelenmelidir.
- Modelin özetini (torchinfo) ve parametre sayısını deney kaydına ekle; beklenmedik bir artış hataya işarettir.
- Öznitelik haritalarını ve yanlış sınıflanan örnekleri görselleştirmek, modeli "kara kutu" olmaktan çıkarır ve hata ayıklamayı hızlandırır.
Kendini sına
32×32 girişe Conv2d(k=5, s=1, p=0) uygulanırsa çıkış boyu nedir?
Conv2d(1, 8, 3) ile 28×28 görüntüde çalışan, tam bağlı bir katmana göre temel üstünlük nedir?
MaxPool2d(2) 14×14 bir haritayı hangi boya indirir?
Ağ derinleştikçe sondaki katmanların nöronları için ne doğrudur?