Ana içeriğe geç

Orta10 dkA — Sinir Ağı Temelleri

Ağırlık ilklendirme

Önkoşul:Patlayan gradyan ve clipping

Kanca

  1. derste kaybolan, 19. derste patlayan gradyanı gördük — ikisinin de kökü genelde AYNI yerde: ağırlıkların BAŞLANGIÇ değerleri. Bu ders, eğitim başlamadan ÖNCE doğru kararı vermenin neden bu kadar önemli olduğunu gösteriyor.

Sezgi

Ağırlık ilklendirme, eğitim başlamadan önce ağırlıklara verilen İLK değerlerdir. İki soru var: (1) Tüm ağırlıklar AYNI değerle mi başlamalı? (2) Rastgele başlıyorsa, bu rastgeleliğin BÜYÜKLÜĞÜ ne olmalı?

Mekanizma

Önce ilk soruya bakalım: tüm ağırlıkları SIFIR yapsak ne olur?

Sıfır ilklendirmenin simetri sorunu

# Tüm ağırlıkları SIFIR ile başlatırsak ne olur? Bir katmandaki 4 nöronun gradyanına bakalım.
katman = nn.Linear(2, 4, bias=False)
with torch.no_grad():
    katman.weight.fill_(0.0)

x = torch.tensor([[1.0, 2.0]])
y = katman(x)
kayip = y.sum()
kayip.backward()

print("Sıfır ilklendirme ile 4 nöronun gradyanları:")
print(katman.weight.grad)
print(f"\nTüm satırlar birbirine EŞİT mi? {torch.allclose(katman.weight.grad[0], katman.weight.grad[1])}")
print("EVET -- 4 nöron da AYNI gradyanı alıyor, yani eğitim boyunca AYNI kalacaklar.")
print("Bu 'simetri kırılamaması' sorunu: sıfır ilklendirme, bir katmandaki nöronları birbirinden AYIRT EDİLEMEZ yapar.")
Sıfır ilklendirme ile 4 nöronun gradyanları:
tensor([[1., 2.],
        [1., 2.],
        [1., 2.],
        [1., 2.]])

Tüm satırlar birbirine EŞİT mi? True
EVET -- 4 nöron da AYNI gradyanı alıyor, yani eğitim boyunca AYNI kalacaklar.
Bu 'simetri kırılamaması' sorunu: sıfır ilklendirme, bir katmandaki nöronları birbirinden AYIRT EDİLEMEZ yapar.

4 nöronun da gradyanı BİREBİR AYNI ([1,2] her satırda). Çoğu kişi “sıfırdan başlamak nötr, güvenli bir seçim” sanır. Yanlış, çünkü aynı gradyanı alan nöronlar, aynı güncellemeyi alır — ve SONSUZA kadar birbirinin KOPYASI kalırlar. Ağın 4 nöronu varmış gibi görünse de, aslında TEK bir nöron gibi davranıyor.

Matematik

Xavier ve He ilklendirme formülleri
Xavier:   σ=1ngiris¸\text{Xavier: } \; \sigma = \sqrt{\frac{1}{n_{\text{giriş}}}}He:   σ=2ngiris¸\text{He: } \; \sigma = \sqrt{\frac{2}{n_{\text{giriş}}}}
SembolAnlamı
σ\sigmaAğırlıkların rastgele başlatılacağı normal dağılımın standart sapması
ngiris¸n_{\text{giriş}} (fan-in)O katmana giren bağlantı sayısı

Xavier (Glorot), sigmoid/tanh için; He (Kaiming), ReLU için tasarlanmıştır. Fark, ReLU’nun girdilerin YARISINI sıfırlaması — He’nin formülündeki ekstra “2” çarpanı, bu kaybı telafi eder.

Kod

Şimdi ikinci soru: rastgele ilklendirmenin BÜYÜKLÜĞÜ. 10 katmanlı bir ağda, sinyalin (tanh ile) katman katman nasıl değiştiğini üç ölçekte izleyelim:

Ölçek çok küçük, çok büyük, veya Xavier

# Rastgele ilklendirmenin BÜYÜKLÜĞÜ (std) de kritik. 10 katmanlı bir ağda, girdi sinyalinin
# (tanh aktivasyonuyla) katman katman nasıl değiştiğini üç farklı ölçekte izleyelim.
def sinyal_yayilimi(std, katman_sayisi=10, genislik=100, aktivasyon=torch.tanh):
    x = torch.randn(1, genislik)
    stdler = [x.std().item()]
    for _ in range(katman_sayisi):
        W = torch.randn(genislik, genislik) * std
        x = aktivasyon(x @ W)
        stdler.append(x.std().item())
    return stdler

genislik = 100
xavier_std = (1 / genislik) ** 0.5

cok_kucuk = sinyal_yayilimi(0.01, genislik=genislik)
cok_buyuk = sinyal_yayilimi(1.0, genislik=genislik)
xavier = sinyal_yayilimi(xavier_std, genislik=genislik)

print(f"\n{'Katman':<8} {'std=0.01 (çok küçük)':<22} {'std=1.0 (çok büyük)':<22} {'Xavier (1/√fan_in)':<20}")
for k in [0, 2, 5, 8, 10]:
    print(f"{k:<8} {cok_kucuk[k]:<22.4f} {cok_buyuk[k]:<22.4f} {xavier[k]:<20.4f}")

print("\nÇok küçük ölçek: sinyal 5. katmanda pratikte SIFIRA iniyor (kaybolan gradyan, 5. ders).")
print("Çok büyük ölçek: sinyal tanh'ın DOYGUNLUK bölgesine kilitleniyor (std~1'de takılı kalıyor).")
print("Xavier: sinyal daha YUMUŞAK azalıyor -- ne aniden sıfırlanıyor ne doygunluğa kilitleniyor.")

Katman   std=0.01 (çok küçük)   std=1.0 (çok büyük)    Xavier (1/√fan_in)  
0        0.9389                 1.0206                 1.0069              
2        0.0097                 0.9581                 0.5380              
5        0.0000                 0.9695                 0.3450              
8        0.0000                 0.9714                 0.3509              
10       0.0000                 0.9512                 0.2493              

Çok küçük ölçek: sinyal 5. katmanda pratikte SIFIRA iniyor (kaybolan gradyan, 5. ders).
Çok büyük ölçek: sinyal tanh'ın DOYGUNLUK bölgesine kilitleniyor (std~1'de takılı kalıyor).
Xavier: sinyal daha YUMUŞAK azalıyor -- ne aniden sıfırlanıyor ne doygunluğa kilitleniyor.

Çok küçük ölçek (std=0.01), sinyali 5. katmanda pratikte SIFIRA indiriyor — 5. dersteki kaybolan gradyanın kökeni. Çok büyük ölçek (std=1.0), sinyali tanh’ın doygunluk bölgesine kilitliyor. Xavier, ikisi arasında çok daha yumuşak bir azalma sağlıyor.

ReLU ile Xavier yetersiz kalıyor

# Xavier, tanh/sigmoid için tasarlandı. ReLU ile ne olur? He ilklendirmesi neden var?
he_std = (2 / genislik) ** 0.5

xavier_relu = sinyal_yayilimi(xavier_std, genislik=genislik, aktivasyon=torch.relu)
he_relu = sinyal_yayilimi(he_std, genislik=genislik, aktivasyon=torch.relu)

print(f"\n{'Katman':<8} {'Xavier + ReLU':<18} {'He + ReLU':<18}")
for k in [0, 2, 5, 8, 10]:
    print(f"{k:<8} {xavier_relu[k]:<18.4f} {he_relu[k]:<18.4f}")

print("\nReLU ile Xavier kullanmak sinyali YİNE küçültüyor (10. katmanda 0.02 -- ReLU'nun yarı-sıfırlama etkisini hesaba katmıyor).")
print("He ilklendirmesi (√(2/fan_in)), bu etkiyi telafi edip sinyali ~1.0 civarında STABİL tutuyor.")

Katman   Xavier + ReLU      He + ReLU         
0        1.0036             0.9423            
2        0.4146             0.7642            
5        0.1749             0.9006            
8        0.0647             0.6195            
10       0.0274             0.5663            

ReLU ile Xavier kullanmak sinyali YİNE küçültüyor (10. katmanda 0.02 -- ReLU'nun yarı-sıfırlama etkisini hesaba katmıyor).
He ilklendirmesi (√(2/fan_in)), bu etkiyi telafi edip sinyali ~1.0 civarında STABİL tutuyor.

ReLU ile Xavier kullanmak sinyali yine küçültüyor (10. katmanda 0.027); He ilklendirmesi sinyali 0.57 civarında çok daha STABİL tutuyor.

Solda üç farklı ilklendirme ölçeğinde TanH sinyalinin katman katman değişimi; sağda Xavier ve He ilklendirmesinin ReLU ile karşılaştırması.
Sol: ölçek çok küçükse sinyal kaybolur, çok büyükse doygunluğa kilitlenir. Sağ: ReLU'ya özel tasarlanan He, Xavier'den çok daha stabil bir sinyal koruyor.

Nerede işe yarar

Modern derin öğrenme kütüphaneleri (PyTorch dahil) çoğu katman için MAKUL varsayılan ilklendirmeler kullanır, ama bunu bilmek hâlâ önemlidir:

  • PyTorch’ta nn.init.xavier_uniform_ / nn.init.kaiming_uniform_ (He’nin diğer adı) fonksiyonlarıyla elle ayarlanabilir.
  • Aktivasyon fonksiyonuna göre doğru şemayı seç: sigmoid/tanh → Xavier, ReLU/GELU (6-10. ders) → He.
  • Çok derin ağlarda (CNN’lerin çoğu katmanı gibi) doğru ilklendirme, eğitimin BAŞLAYIP başlamayacağını bile belirleyebilir.

Bu 3 hatayı yaparsın:

  1. Tüm ağırlıkları sıfır (veya aynı sabit değer) ile başlatmak — simetri hiç kırılmaz, nöronlar birbirinin kopyası kalır.
  2. ReLU kullanırken Xavier ilklendirmeyi kullanmaya devam etmek — sinyal, derin ağlarda yavaşça sönümlenir.
  3. “Model öğrenmiyor” diye mimariyi değiştirmeye başlamak, ama sorunun aslında kötü ilklendirmeden kaynaklandığını fark etmemek.

Kendini test et

1. Notebook'ta tüm ağırlıklar sıfırla başlatıldığında 4 nöron neden birbirinden hiç AYRIŞAMADI?
  1. Kod hatalıydı
  2. Sıfır ağırlıklarla tüm nöronlar AYNI gradyanı aldığı için, her güncellemede AYNI şekilde değişmeye devam ettiler -- simetri hiç kırılmadı (doğru cevap)
  3. PyTorch sıfır ilklendirmeyi desteklemiyor
  4. Öğrenme oranı çok küçüktü

Neden: Tüm ağırlıklar sıfırken her nöronun çıktısı ve dolayısıyla gradyanı özdeştir; bu simetri, güncellemeler devam ettikçe de KIRILMAZ -- nöronlar sonsuza kadar birbirinin kopyası kalır.

2. Ağırlık ilklendirme ölçeği ÇOK KÜÇÜK seçilirse (örn. std=0.01) derin bir ağda ne olur?
  1. Hiçbir etkisi olmaz
  2. Sinyal, katman katman küçülerek birkaç katman içinde pratikte sıfıra iner (kaybolan gradyanla aynı kök neden) (doğru cevap)
  3. Eğitim daha hızlı olur
  4. Sadece ilk katmanı etkiler

Neden: Notebook'ta std=0.01 ile sinyal 5. katmanda pratikte sıfıra iniyor (0.0000) -- bu, 5. dersteki kaybolan gradyan probleminin başlangıç noktasıdır.

3. He ilklendirmesi neden özellikle ReLU için tasarlanmıştır?
  1. He, Xavier ile tamamen aynıdır
  2. ReLU, negatif girdileri sıfırlayarak sinyalin yaklaşık YARISINI söndürür; He'nin formülündeki ekstra '2' çarpanı bu kaybı telafi eder (doğru cevap)
  3. He sadece sigmoid için çalışır
  4. He ilklendirme rastgelelik içermez

Neden: ReLU çıktıların yaklaşık yarısını sıfırladığı için sinyal varyansı yarıya iner; He'nin √(2/n) formülündeki '2' çarpanı bu kaybı telafi ederek sinyali stabil tutar -- notebook'ta Xavier+ReLU 10. katmanda 0.027'ye düşerken He+ReLU 0.57'de kalıyor.

Özet

Özet

  • Tüm ağırlıkları aynı değerle (örn. sıfır) başlatmak, nöronlar arasındaki simetriyi asla kırmaz.
  • Rastgele ilklendirmenin ÖLÇEĞİ kritiktir: çok küçük sinyali söndürür, çok büyük doygunluğa kilitler.
  • Xavier ilklendirme (√(1/fan_in)), sigmoid/tanh aktivasyonları için tasarlanmıştır.
  • He ilklendirme (√(2/fan_in)), ReLU'nun yarı-sıfırlama etkisini telafi eder.
  • Doğru ilklendirme seçimi, derin bir ağın eğitilebilir olup olmadığını doğrudan etkiler.
Sonraki adım: L1/L2 düzenlileştirme →