Sıradaki

Adam adımı

Zorluk: Zor

optimizasyon

Adam, her parametre için adım boyutunu gradyanın geçmişine göre ayarlar. İki hareketli ortalama tutar: gradyanın ortalaması (birinci moment, m\mathbf{m}) ve gradyanın karesinin ortalaması (ikinci moment, v\mathbf{v}). adam_step(w, m, v, grad, t, lr=0.001, beta1=0.9, beta2=0.999, eps=1e-8) fonksiyonunu yaz. Fonksiyon, Adam’ın yanlılık düzeltmeli (bias correction) tek bir adımını yapar.

t adım numarasıdır ve 1’den başlar: ilk güncellemede t = 1. Önce momentleri güncelle:

m←β1 m+(1−β1) ∇Lv←β2 v+(1−β2) (∇L)2\mathbf{m} \leftarrow \beta_1\,\mathbf{m} + (1 - \beta_1)\,\nabla L \qquad \mathbf{v} \leftarrow \beta_2\,\mathbf{v} + (1 - \beta_2)\,(\nabla L)^2

Momentler sıfırdan başladığı için ilk adımlarda sıfıra doğru yanlıdır. Yanlılık düzeltmesi bunu giderir:

m^=m1−β1tv^=v1−β2t\hat{\mathbf{m}} = \frac{\mathbf{m}}{1 - \beta_1^t} \qquad \hat{\mathbf{v}} = \frac{\mathbf{v}}{1 - \beta_2^t}

Sonra parametreleri güncelle. Kare ve karekök eleman bazındadır (element-wise):

w←w−η m^v^+ϵ\mathbf{w} \leftarrow \mathbf{w} - \eta\,\frac{\hat{\mathbf{m}}}{\sqrt{\hat{\mathbf{v}}} + \epsilon}

Fonksiyon (w_yeni, m_yeni, v_yeni) üçlüsünü döndürür. Momentler düzeltilmemiş hâlleriyle döner. Çünkü bir sonraki adım onlardan devam eder.

Örnekler

Girdi: w = [1.0, -1.0], m = [0.0, 0.0], v = [0.0, 0.0], grad = [0.5, -3.0], t = 1, lr = 0.001
Çıktı: (array([ 0.999, -0.999]), array([ 0.05, -0.3 ]), array([0.00025, 0.009 ]))

Girdi: w = [0.2, 0.4, -0.6], m = [0.1, -0.2, 0.05], v = [0.01, 0.04, 0.0025], grad = [0.3, -0.1, 0.2], t = 5, lr = 0.01, beta1 = 0.8, beta2 = 0.99
Çıktı: (array([ 0.19556409, 0.4029747 , -0.60491289]), array([ 0.14, -0.18, 0.08]), array([0.0108 , 0.0397 , 0.002875]))

Girdi: w = [[1.0, -2.0], [0.0, 3.0]], m = [[-0.5, 0.5], [0.0, 1.0]], v = [[0.25, 0.25], [1.0, 4.0]], grad = [[-1.0, 1.0], [2.0, -2.0]], t = 20, lr = 0.1
Çıktı: (array([[ 1.0175992 , -2.0175992 ], [-0.00319986, 2.99439186]]), array([[-0.55, 0.55], [ 0.2 , 0.7 ]]), array([[0.25075, 0.25075], [1.003 , 4. ]]))

İpucu 1

m_yeni ve v_yeni’yi eski değerlerden hesapla. grad ** 2 eleman bazında karedir. Düzeltilmemiş değerleri sakla, çünkü fonksiyon onları döndürür.

İpucu 2

m_hat = m_yeni / (1 - beta1 ** t) ve v_hat için benzerini yaz. 1−βt1 - \beta^t, ilk adımda küçüktür ve t büyüdükçe 1’e yaklaşır.

İpucu 3

Paydada np.sqrt(v_hat) + eps kullan. İlk adımda m_hat = grad ve np.sqrt(v_hat) = |grad| olur. Parametre yaklaşık η\eta kadar, gradyanın tersi yönünde oynar.

Gereksinimler

  • Dönüş değeri üç array içeren bir demettir: (w_yeni, m_yeni, v_yeni). Üçü de w ile aynı shape’te olur.
  • m_yeni ve v_yeni düzeltmeden önceki değerlerdir. Yalnızca parametre adımında m^\hat{\mathbf{m}} ve v^\hat{\mathbf{v}} kullanılır.
  • eps, karekökten sonra paydaya eklenir: v^+ϵ\sqrt{\hat{\mathbf{v}}} + \epsilon. Karekökün içine girmez.
  • t 1 ya da daha büyük bir tam sayıdır. t = 0 verilmez.
  • Varsayılanlar lr=0.001, beta1=0.9, beta2=0.999 ve eps=1e-8’dir.
  • Gradyan sıfırken sonuç nan olmamalı. Girdileri yerinde değiştirme.

Adam, momentumu (momentum) ve adım boyutunu parametre başına uyarlamayı birleştirir. Birinci moment momentumun işini yapar: gradyanın yönünü düzler. İkinci moment adım boyutunu ayarlar: gradyanı sürekli büyük olan parametrenin adımı küçülür, küçük olanın adımı büyür.

Yanlılık düzeltmesi neden gerekli? m=v=0\mathbf{m} = \mathbf{v} = 0 ile başlarsan, ilk adımda m=0,1 ∇L\mathbf{m} = 0{,}1\,\nabla L olur. Gerçek ortalamanın onda biridir. β2=0,999\beta_2 = 0{,}999 için v\mathbf{v} ise gerçek değerin binde biri kadar olur. Düzeltme olmadan ilk adımlar yanlış ölçekte olur. 1−βt1 - \beta^t ile bölmek bu eksikliği tam olarak tamamlar.

İlk adımda m^/v^\hat{\mathbf{m}}/\sqrt{\hat{\mathbf{v}}} gradyanın işaretidir. Bu yüzden her parametre ilk adımda yaklaşık η\eta kadar oynar. ϵ\epsilon yalnızca sıfıra bölmeyi engeller.

Daha fazlası için Bir MLP eğitmek dersine bak.

Momentleri güncelle, düzelt ve parametre adımını at:

import numpy as npdef adam_step(w: np.ndarray, m: np.ndarray, v: np.ndarray, grad: np.ndarray, t: int,              lr: float = 0.001, beta1: float = 0.9, beta2: float = 0.999,              eps: float = 1e-8) -> tuple[np.ndarray, np.ndarray, np.ndarray]:    m_new = beta1 * m + (1 - beta1) * grad    v_new = beta2 * v + (1 - beta2) * grad ** 2    m_hat = m_new / (1 - beta1 ** t)    v_hat = v_new / (1 - beta2 ** t)    w_new = w - lr * m_hat / (np.sqrt(v_hat) + eps)    return w_new, m_new, v_new

Sık yapılan hata, düzeltilmiş momentleri geri döndürmektir. Bir sonraki adımda onları yeniden düzeltirsin ve moment ortalamaları bozulur. Düzeltme yalnızca parametre adımının içinde yapılır.

Bir başka hata, eps’i karekökün içine koymaktır (np.sqrt(v_hat + eps)). Gradyan çok küçükken adım boyutu belirgin biçimde değişir.

Bu problemde bir sorun mu var?

solution.py
import numpy as npdef adam_step(w: np.ndarray, m: np.ndarray, v: np.ndarray, grad: np.ndarray, t: int,              lr: float = 0.001, beta1: float = 0.9, beta2: float = 0.999,              eps: float = 1e-8) -> tuple[np.ndarray, np.ndarray, np.ndarray]:    """Adam'ın yanlılık düzeltmeli tek adımını yapar ve (yeni w, yeni m, yeni v) üçlüsünü döndürür."""    # Kodunu buraya yaz.    return w, m, v

İçindekiler

Geri bildirim

Tür