Ana içeriğe geç

Orta11 dkA — Sinir Ağı Temelleri

Adam

Önkoşul:RMSprop ve Adadelta

Kanca

15-17. derste momentum (gürültüyü yumuşatan “hız”) ve RMSprop (kararlı bir uyarlanabilir öğrenme oranı) fikirlerini ayrı ayrı gördük. Adam, bu ikisini birleştiren ve bugün en yaygın kullanılan optimizer.

Sezgi

Adam, her ağırlık için iki ayrı hafıza tutar: gradyanın kendisinin ortalaması (momentum gibi) ve gradyanın karesinin ortalaması (RMSprop gibi). Ama bu iki hafıza sıfırdan başladığı için, ilk birkaç adımda “gerçek” değerlerinden sistematik olarak küçük kalırlar — Adam’ın en önemli (ve çoğu kişinin bilmediği) detayı bu sapmayı düzeltmesidir.

Optimizer yarışında Adam’ı (mor) izle — hem vadi hem eyer noktası senaryosunda genelde hızlı ve kararlı davranıyor.

Yüzey
Optimizerlar

Adım: 0

SGD'nin dar vadide nasıl zigzag çizdiğine, momentumun ise bu salınımı nasıl yumuşatıp hızlandırdığına dikkat et.

Mekanizma

Adam’ı, bias düzeltmesi olmadan uygularsak ne olur?

Adam, bias düzeltmesi olmadan

# Adam = Momentum (15. ders) fikri + RMSprop (17. ders) fikri birleştirilmiş.
# m: gradyanın üstel ortalaması (momentum'daki "hız" gibi)
# v: gradyan karesinin üstel ortalaması (RMSprop'taki "cache" gibi)
# Deney: basit bir vadi, L(w) = w²/2 (minimum w=0'da, gradyan g = w). Başlangıç w=5, lr=0.3.
# lr=0.3 demek: Adam'ın her adımı ~0.3 büyüklüğünde olmalı.
def adam_duzeltmesiz(adim_sayisi, lr=0.3, b1=0.9, b2=0.999):
    w, m, v = 5.0, 0.0, 0.0
    yol, adimlar = [w], []
    for t in range(1, adim_sayisi + 1):
        g = w  # L = w²/2 -> dL/dw = w
        m = b1 * m + (1 - b1) * g
        v = b2 * v + (1 - b2) * g ** 2
        adim = lr * m / (np.sqrt(v) + 1e-8)
        w -= adim
        yol.append(w)
        adimlar.append(adim)
    return yol, adimlar

yol_duzeltmesiz, adimlar_duzeltmesiz = adam_duzeltmesiz(30)
print("Bias düzeltmesi olmadan Adam, ilk 5 adımın büyüklüğü (hedef ~0.3):")
print("  " + ", ".join(f"{a:.2f}" for a in adimlar_duzeltmesiz[:5]))
print(f"\nw, minimumu (0) {np.argmax(np.array(yol_duzeltmesiz) < 0)}. adımda geçip {min(yol_duzeltmesiz):.2f} değerine kadar karşı tarafa savruluyor.")
Bias düzeltmesi olmadan Adam, ilk 5 adımın büyüklüğü (hedef ~0.3):
  0.95, 1.26, 1.42, 1.44, 1.28

w, minimumu (0) 4. adımda geçip -2.97 değerine kadar karşı tarafa savruluyor.

lr=0.3 seçtik, yani adımlar ~0.3 büyüklüğünde olmalı. Ama ilk adımlar 0.95, 1.26, 1.42… — 3-5 kat büyük. w, minimumu (0) 4. adımda geçip -2.97’ye kadar karşı tarafa savruluyor. Şimdi tek satırlık bir düzeltme ekleyelim:

Adam, bias düzeltmesiyle

# Sorun: m ve v, sıfırdan başlıyor -- ilk adımlarda gerçek değerlerinden çok küçük kalıyorlar.
# Adam, bunu (1 - beta^t) ile bölerek düzeltir -- "bias correction".
def adam_duzeltmeli(adim_sayisi, lr=0.3, b1=0.9, b2=0.999):
    w, m, v = 5.0, 0.0, 0.0
    yol, adimlar = [w], []
    for t in range(1, adim_sayisi + 1):
        g = w
        m = b1 * m + (1 - b1) * g
        v = b2 * v + (1 - b2) * g ** 2
        m_hat = m / (1 - b1 ** t)
        v_hat = v / (1 - b2 ** t)
        adim = lr * m_hat / (np.sqrt(v_hat) + 1e-8)
        w -= adim
        yol.append(w)
        adimlar.append(adim)
    return yol, adimlar

yol_duzeltmeli, adimlar_duzeltmeli = adam_duzeltmeli(30)
print("Bias düzeltmesi ile Adam, ilk 5 adımın büyüklüğü (hedef ~0.3):")
print("  " + ", ".join(f"{a:.2f}" for a in adimlar_duzeltmeli[:5]))
print("\nw, ~0.3'lük adımlarla minimuma iniyor ve onun etrafında küçük salınımlarla kalıyor.")
print("Fark sadece (1-beta^t) ile bölme -- ama ilk adımlar 3-5 kat büyükten, tam olması gereken boyuta iniyor.")
Bias düzeltmesi ile Adam, ilk 5 adımın büyüklüğü (hedef ~0.3):
  0.30, 0.30, 0.30, 0.30, 0.29

w, ~0.3'lük adımlarla minimuma iniyor ve onun etrafında küçük salınımlarla kalıyor.
Fark sadece (1-beta^t) ile bölme -- ama ilk adımlar 3-5 kat büyükten, tam olması gereken boyuta iniyor.

Aynı ayarlarla, aynı vadide, adımlar artık tam 0.30 ve iniş düzgün. Çoğu kişi “küçük bir matematiksel detay, önemli olamaz” sanır. Yanlış, çünkü bu tek terim, eğitimin en kırılgan anında — ilk adımlarda — adımların planlanandan kat kat büyük olmasını engelliyor. Bu oyuncak vadide sadece savrulma görüyoruz; gerçek bir ağda bu kadar büyük ilk adımlar eğitimi kararsızlaştırıp ıraksatabilir (Kingma ve Ba, 2015).

Matematik

Adam güncelleme kuralı
mt=β1mt−1+(1−β1)gtm_t = \beta_1 m_{t-1} + (1-\beta_1) g_tvt=β2vt−1+(1−β2)gt2v_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2m^t=mt1−β1t\hat{m}_t = \frac{m_t}{1-\beta_1^t}v^t=vt1−β2t\hat{v}_t = \frac{v_t}{1-\beta_2^t}wt+1=wt−ηv^t+ϵ m^tw_{t+1} = w_t - \frac{\eta}{\sqrt{\hat{v}_t}+\epsilon}\,\hat{m}_t
SembolAnlamı
mtm_tBirinci moment — gradyanın kendisinin üstel ortalaması (momentum, 15. ders)
vtv_tİkinci moment — gradyan karesinin üstel ortalaması (RMSprop, 17. ders)
m^t,v^t\hat{m}_t, \hat{v}_tBias-düzeltilmiş versiyonlar — (1−βt)(1-\beta^t)‘ye bölünerek erken adımlardaki küçük-kalma sorunu giderilir

tt büyüdükçe βt→0\beta^t \to 0, yani (1−βt)→1(1-\beta^t) \to 1 — düzeltme yalnızca ilk adımlarda etkili, sonra otomatik olarak “kapanır”.

Kod

Neden özellikle ilk adım bu kadar riskli? vv‘nin başlangıçtaki değerine bakalım:

t=1'de v neden çok küçük?

# İlk adımda (t=1) m ve v'nin düzeltmesiz ve düzeltmeli hâllerini karşılaştıralım (g = 1 için).
b1, b2 = 0.9, 0.999
g = 1.0
m_ham, v_ham = (1 - b1) * g, (1 - b2) * g ** 2
m_hat, v_hat = m_ham / (1 - b1), v_ham / (1 - b2)
print(f"t=1'de m = {m_ham:.3f}  (gerçek değerin {g / m_ham:.0f} katı küçük)   ->  düzeltmeli m_hat = {m_hat:.3f}")
print(f"t=1'de v = {v_ham:.5f}  (gerçek değerin {g ** 2 / v_ham:.0f} katı küçük) ->  düzeltmeli v_hat = {v_hat:.3f}")
print(f"\nAdım ∝ m/√v: düzeltmesiz {m_ham / np.sqrt(v_ham):.2f}, düzeltmeli {m_hat / np.sqrt(v_hat):.2f}")
print("m 10 kat küçük ama √v ~32 kat küçük: payda (√v) paydan (m) daha çok küçüldüğü için adım ~3 kat büyüyor.")
t=1'de m = 0.100  (gerçek değerin 10 katı küçük)   ->  düzeltmeli m_hat = 1.000
t=1'de v = 0.00100  (gerçek değerin 1000 katı küçük) ->  düzeltmeli v_hat = 1.000

Adım ∝ m/√v: düzeltmesiz 3.16, düzeltmeli 1.00
m 10 kat küçük ama √v ~32 kat küçük: payda (√v) paydan (m) daha çok küçüldüğü için adım ~3 kat büyüyor.

t=1’de düzeltmesiz mm gerçek değerinin 10 katı, vv ise 1000 katı küçük. Adım m/vm/\sqrt{v} ile orantılı: mm 10 kat küçülürken v\sqrt{v} ~32 kat küçüldüğü için adım ~3 kat büyüyor. Düzeltme, ikisini de gerçek değerine (1.0) taşıyor.

PyTorch ile doğrulama

# PyTorch'un torch.optim.Adam'ı, bias düzeltmesini içinde otomatik yapar.
w_t = torch.tensor(5.0, requires_grad=True)
optimizer = torch.optim.Adam([w_t], lr=0.3, betas=(0.9, 0.999))
for t in range(30):
    optimizer.zero_grad()
    kayip = w_t ** 2 / 2
    kayip.backward()
    optimizer.step()
print(f"\nPyTorch Adam, 30 adım sonra: w={w_t.item():.4f}")
print(f"Elle yazdığımız (düzeltmeli) Adam: w={yol_duzeltmeli[-1]:.4f}  -- birebir aynı.")

PyTorch Adam, 30 adım sonra: w=-0.8329
Elle yazdığımız (düzeltmeli) Adam: w=-0.8329  -- birebir aynı.

PyTorch’un torch.optim.Adam’ı bu düzeltmeyi otomatik yapar — sonuç (w=-0.8329) elle yazdığımız versiyonla birebir aynı.

Solda L = w²/2 vadisinde ağırlığın yolu: bias düzeltmesi olmayan çizgi minimumu aşıp -2.97'ye savrulurken düzeltmeli çizgi düzgünce iniyor. Sağda ilk 8 adımın büyüklüğü: düzeltmesiz adımlar 1.4'e kadar çıkarken düzeltmeli adımlar 0.3'te sabit.(grafiği tam boyutta, yeni sekmede aç)
Aynı vadi, aynı hiperparametreler -- sadece bias düzeltmesinin varlığı/yokluğu: düzeltmesiz ilk adımlar planlanandan (lr=0.3) 3-5 kat büyük olduğu için ağırlık minimumu aşıp karşı tarafa savruluyor.

Nerede işe yarar

Adam, günümüzde derin öğrenmenin varsayılan optimizer’ıdır:

  • Çoğu modern model (transformer’lar dahil, NLP kategorisinde göreceğiz) Adam veya türevleriyle (AdamW gibi) eğitilir.
  • Varsayılan hiperparametreler (β1=0.9\beta_1=0.9, β2=0.999\beta_2=0.999, η=0.001\eta=0.001) çoğu problemde iyi çalışır — bu, Adam’ın popülerliğinin bir nedeni.
  • Momentum + uyarlanabilir öğrenme oranı birleşimi, hem gürültüye hem de kötü ölçeklenmiş gradyanlara karşı dayanıklı yapıyor.

Bu 3 hatayı yaparsın:

  1. Kendi optimizer’ını yazarken bias düzeltmesini unutmak — bu notebook’ta gördüğümüz gibi, ilk adımlar sessizce (hata mesajı vermeden) planlanandan kat kat büyük olur.
  2. Adam’ın “her zaman en iyi” olduğunu sanmak — bazı problemlerde (özellikle görüntü sınıflandırmada, ör. ResNet eğitimleri) düzgün ayarlanmış SGD+momentum daha iyi genelleme verebilir; büyük dil modelleri ise neredeyse her zaman Adam’ın bir türeviyle (AdamW) eğitilir.
  3. β2\beta_2‘yi (genelde 0.999) çok düşük ayarlayıp vv‘nin çok hızlı değişmesine, dolayısıyla adımların kararsızlaşmasına neden olmak.

Kendini test et

1. Notebook'ta bias düzeltmesi olmadan Adam'ın ilk adımları neden 3-5 kat büyük çıktı (w minimumu aşıp -2.97'ye savruldu)?
  1. Öğrenme oranı çok küçüktü
  2. v (ikinci moment), ilk adımlarda gerçek değerinden çok küçük kaldığı için payda küçüldü ve adım boyutu büyüdü (doğru cevap)
  3. Gradyan yanlış hesaplandı
  4. Momentum kullanılmadı

Neden: t=1'de düzeltmesiz v sadece 0.001 (gerçek değerden 1000 kat küçük); m ise yalnızca 10 kat küçük. w -= lr*m/sqrt(v) formülünde payda paydan daha çok küçüldüğü için adım ~3 kat büyüyor.

2. Adam, hangi iki fikri birleştirir?
  1. Sadece SGD ve Adagrad
  2. Momentum (gradyanın ortalaması) ve RMSprop (gradyan karesinin ortalaması) (doğru cevap)
  3. Sadece L1 ve L2 düzenlileştirme
  4. Batch normalization ve dropout

Neden: Adam, momentumdan gradyanın üstel ortalamasını (m_t, birinci moment) ve RMSprop'tan gradyan karesinin üstel ortalamasını (v_t, ikinci moment) alıp birleştirir.

3. Bias düzeltmesi (m_t değerini (1-β₁^t) ile bölmek gibi) neden sadece ilk adımlarda etkilidir?
  1. Her zaman aynı etkiye sahiptir
  2. t büyüdükçe β üzeri t sıfıra yaklaşır, bu yüzden (1-β üzeri t) 1'e yaklaşır ve bölme işlemi etkisiz hale gelir (doğru cevap)
  3. Düzeltme sadece son adımda uygulanır
  4. Düzeltme, öğrenme oranını değiştirir

Neden: β1 ve β2, 1'den küçük olduğu için üsleri (β^t) adım sayısı arttıkça sıfıra yaklaşır; bu da (1-β^t) payını 1'e yaklaştırıp düzeltmeyi kademeli olarak "kapatır" -- düzeltme sadece erken adımlarda büyük bir fark yaratır.

Özet

Özet

  • Adam, momentum (birinci moment) ve RMSprop (ikinci moment) fikirlerini birleştirir.
  • m ve v, sıfırdan başladığı için ilk adımlarda gerçek değerlerinden sistematik olarak küçük kalır -- bias.
  • Bias düzeltmesi ((1-beta^t)'ye bölme), bu erken-adım sapmasını giderir; düzeltme olmadan ilk adımlar kat kat büyük olur ve eğitim kararsızlaşabilir.
  • Adam, günümüzde derin öğrenmenin en yaygın kullanılan varsayılan optimizer'ıdır.
  • Varsayılan hiperparametreler (β1=0.9, β2=0.999) çoğu problemde iyi bir başlangıç noktasıdır.
Sonraki adım: Patlayan gradyan ve clipping →