6.4 Momentum és adaptív optimizálók

6.4.1 Cél, előismeret és induló kérdés

A 6.3. Sztochasztikus és minibatch gradiens alfejezetben a minibatch-gradiens torzítatlanságáról és zajáról volt szó. Ott a lépés közvetlenül a becsült gradiens negatív irányába mutatott. A gyakorlatban az SGD azonban lassan haladhat olyan irányokban, ahol a gradiens kicsi, és erősen fluktuálhat olyan irányokban, ahol a gradiens nagy varianciájú. Ebben az egységben olyan frissítési szabályokat vizsgálunk, amelyek paraméteren kívül állapotváltozókat is tárolnak, és ezekből számítják a tényleges lépést. Az 5.4. Függő képek, seedek és resampling alfejezetből tudjuk, hogy a seed és a minta szerinti bizonytalanságot külön kell kezelni: az optimizer választása az algoritmikus bizonytalanságot befolyásolja, nem magát az adatmintát.

Induló becslés: miért lehet hasznos egy gradiens mozgóátlaga akkor is, ha az egyes gradiensbecslések torzítatlanok? Mit ront el, ha a súlycsökkentést egyszerűen hozzáadjuk a gradienshez egy adaptív normalizálás előtt?

6.4.2 Momentum mint állapotváltozó

Legyen a paramétervektor θt∈ℝd\theta_t\in\mathbb R^d, a gradiensbecslés gt∈ℝdg_t\in\mathbb R^d, a tanulási ráta η>0\eta>0, a momentum-együttható β∈[0,1)\beta\in[0,1). A PyTorch momentumos SGD-jének állapotváltozója mt∈ℝdm_t\in\mathbb R^d, alakja azonos θ\theta alakjával, és inicializálása m0=0m_0=0. A frissítés:

mt=βmt−1+gt,θt+1=θt−ηmt. m_t = \beta m_{t-1} + g_t, \qquad \theta_{t+1} = \theta_t - \eta\, m_t.

Ez nem normalizált exponenciális mozgóátlag: konstans gradiens gt≡gg_t\equiv g esetén mt=(1+β+⋯+βt−1)gm_t=(1+\beta+\cdots+\beta^{t-1})g, ami t→∞t\to\infty esetén g/(1−β)g/(1-\beta)-hoz tart. Ezért a momentum növeli az effektív lépésnagyságot egy konzisztens gradiensirányban; a tanulási rátát általában kisebbre kell választani, mint sima SGD-nél. A momentum célja heurisztikus: a konzisztens irányt simítja és gyorsítja, a nagy varianciájú, előjelváltó komponenseket részben kiátlagolja. Ez nem bizonyított konvergenciajavítás minden feladatra.

6.4.3 Adam: első és második momentum

Az Adam három állapotot tart nyilván a paraméter mellett. Legyenek β1,β2∈[0,1)\beta_1,\beta_2\in[0,1), ϵ>0\epsilon>0; a PyTorch-alapértelmezések szerint gyakran β1=0,9\beta_1=0{,}9, β2=0,999\beta_2=0{,}999, ϵ=10−8\epsilon=10^{-8}. A tt-edik lépésben a gtg_t gradiensbecslésből:

mt=β1mt−1+(1−β1)gt,vt=β2vt−1+(1−β2)gt2, m_t = \beta_1 m_{t-1} + (1-\beta_1)g_t, \qquad v_t = \beta_2 v_{t-1} + (1-\beta_2)g_t^2,

ahol gt2g_t^2 elemenkénti négyzet, m0=v0=0m_0=v_0=0, alakjuk azonos θ\theta alakjával. Mivel az inicializálás nulla, a kezdeti lépésekben mtm_t és vtv_t szisztematikusan kisebb, mint amit egy régóta futó mozgóátlagtól várnánk. A bias correction ezért:

m̂t=mt1−β1t,v̂t=vt1−β2t. \hat m_t = \frac{m_t}{1-\beta_1^t}, \qquad \hat v_t = \frac{v_t}{1-\beta_2^t}.

Az Adam-frissítés:

θt+1=θt−ηm̂tv̂t+ϵ. \theta_{t+1} = \theta_t - \eta\, \frac{\hat m_t}{\sqrt{\hat v_t} + \epsilon}.

A nevező műveletei elemenkéntiek, ϵ\epsilon hozzáadása a négyzetgyök után történik a PyTorch-konvenció szerint; más könyvtárak a v̂t+ϵ\sqrt{\hat v_t+\epsilon} alakot használhatják, ezért pontos numerikus reprodukció előtt az adott API-t ellenőrizni kell. Az ϵ\epsilon szerepe numerikus: ha v̂t\hat v_t valamely koordinátája nulla közelében van, az osztás instabillá válna.

Az Adam tehát két különböző normalizálást végez. Az első momentum a gradiens irányának simítása, a második momentum a gradienskomponensek négyzetes nagyságának simítása; az arányuk az egyes koordinátákra eltérő effektív lépésméretet ad.

6.4.4 AdamW és decoupled weight decay

A klasszikus L2-regularizálás a veszteséghez ad hozzá (λ/2)∥θ∥2(\lambda/2)\|\theta\|^2 tagot, így a gradiens gt+λθtg_t+\lambda\theta_t lesz. Az AdamW ehelyett a súlycsökkentést elkülönítve, a momentumoktól függetlenül alkalmazza:

$$ \theta_{t+1} = \theta_t - \eta\Bigl(\lambda\theta_t + \frac{\hat m_t}{\sqrt{\hat v_t}+\epsilon}\Bigr), $$

ahol λ≥0\lambda\ge0 a weight decay, m̂t,v̂t\hat m_t,\hat v_t továbbra is csak a gtg_t adatgradiensből számítódik. Ezt nevezzük decoupled decay-nek: a λθt\lambda\theta_t tag nincs benne sem mtm_t-ben, sem vtv_t-ben, és nincs osztva az adaptív nevezővel. A gondolat forrása [P02]; a PyTorch AdamW osztálya ezt az alakot valósítja meg, míg a torch.optim.Adam weight_decay argumentuma a hagyományos L2-stílusú gradienshozzáadást jelenti a jelen könyv által feltételezett 2.14 API-ban. Ez utóbbi pontos szakaszát a kézirat lektorálása előtt ellenőrizni kell [D06].

6.4.5 Két skalárfrissítés: miért más a decoupled decay, mint a naiv L2 Adam alatt?

Állítás (levezetéssel). Legyen θ∈ℝ\theta\in\mathbb R, adott gt∈ℝg_t\in\mathbb R adatgradiens és λ>0\lambda>0. Az AdamW frissítése

θt+1=θt−ηλθt−ηm̂tv̂t+ϵ, \theta_{t+1} = \theta_t - \eta\lambda\theta_t - \eta\frac{\hat m_t}{\sqrt{\hat v_t}+\epsilon},

ahol mt,vtm_t,v_t csak gtg_t-ből képződik. A naiv L2 Adam ezzel szemben a g̃t=gt+λθt\tilde g_t=g_t+\lambda\theta_t gradienst használja, ezért

m̃t=β1m̃t−1+(1−β1)g̃t,ṽt=β2ṽt−1+(1−β2)g̃t2, \tilde m_t=\beta_1\tilde m_{t-1}+(1-\beta_1)\tilde g_t, \qquad \tilde v_t=\beta_2\tilde v_{t-1}+(1-\beta_2)\tilde g_t^2,

és a frissítés

θt+1=θt−ηm̃t/(1−β1t)ṽt/(1−β2t)+ϵ. \theta_{t+1} = \theta_t - \eta \frac{\tilde m_t/(1-\beta_1^t)} {\sqrt{\tilde v_t/(1-\beta_2^t)}+\epsilon}.

A két szabály csak akkor lenne azonos, ha a λθt\lambda\theta_t tag az adaptív normalizálásból kiemelhető lenne. Nem emelhető ki, mert egyrészt m̂t\hat m_t és v̂t\hat v_t a korábbi θs\theta_s értékeket is tartalmazza, másrészt a L2-tag a nevezővel is osztódik. Ezért a L2 Adam alatti effektív decay nem ηλθt\eta\lambda\theta_t, hanem egy momentumokkal simított, adaptívan skálázott mennyiség.

6.4.5.1 Kétlépéses numerikus példa

Legyen θ0=2\theta_0=2, g1=g2=1g_1=g_2=1, η=0,1\eta=0{,}1, β1=β2=0,5\beta_1=\beta_2=0{,}5, λ=0,5\lambda=0{,}5, ϵ=0\epsilon=0. A ϵ=0\epsilon=0 választás a kézi számolást egyszerűsíti; a PyTorch-alapértelmezés nem nulla, de ebben a példában a nevezők nullától távol vannak, így a különbség csak numerikus apróság.

AdamW, 1. lépés. m1=0,5m_1=0{,}5, v1=0,5v_1=0{,}5, bias korrekció: 1−0,5=0,51-0{,}5=0{,}5, ezért m̂1=1\hat m_1=1, v̂1=1\hat v_1=1. Ekkor

θ1=2−0,1⋅0,5⋅2−0,1⋅11+0=2−0,1−0,1=1,8. \theta_1 = 2 - 0{,}1\cdot 0{,}5\cdot 2 - 0{,}1\cdot\frac{1}{1+0} =2-0{,}1-0{,}1=1{,}8.

AdamW, 2. lépés. m2=0,5⋅0,5+0,5⋅1=0,75m_2=0{,}5\cdot0{,}5+0{,}5\cdot1=0{,}75, v2=0,75v_2=0{,}75, bias korrekció: 1−0,52=0,751-0{,}5^2=0{,}75, ezért m̂2=v̂2=1\hat m_2=\hat v_2=1. Így

θ2=1,8−0,1⋅0,5⋅1,8−0,1=1,8−0,09−0,1=1,61. \theta_2 = 1{,}8 - 0{,}1\cdot0{,}5\cdot1{,}8 - 0{,}1 = 1{,}8-0{,}09-0{,}1=1{,}61.

Naiv L2 Adam, 1. lépés. g̃1=1+0,5⋅2=2\tilde g_1=1+0{,}5\cdot2=2. m1=1m_1=1, v1=2v_1=2, bias korrekcióval m̂1=2\hat m_1=2, v̂1=4\hat v_1=4, v̂1=2\sqrt{\hat v_1}=2. A frissítés:

θ1=2−0,1⋅22+0=2−0,1=1,9. \theta_1 = 2 - 0{,}1\cdot\frac{2}{2+0}=2-0{,}1=1{,}9.

Naiv L2 Adam, 2. lépés. g̃2=1+0,5⋅1,9=1,95\tilde g_2=1+0{,}5\cdot1{,}9=1{,}95. Ekkor m2=0,5⋅1+0,5⋅1,95=1,475m_2=0{,}5\cdot1+0{,}5\cdot1{,}95=1{,}475, v2=0,5⋅2+0,5⋅1,952=2,90125v_2=0{,}5\cdot2+0{,}5\cdot1{,}95^2=2{,}90125. A bias korrekció 0,750{,}75: m̂2≈1,9667\hat m_2\approx1{,}9667, v̂2≈3,8683\hat v_2\approx3{,}8683, v̂2≈1,9668\sqrt{\hat v_2}\approx1{,}9668. A hányados majdnem 1, így

θ2≈1,9−0,1=1,8. \theta_2 \approx 1{,}9-0{,}1=1{,}8.

A két lépés után AdamW θ2=1,61\theta_2=1{,}61, a L2 Adam θ2≈1,8\theta_2\approx1{,}8. A különbség oka látható: az AdamW-ben a decay tag ηλθt\eta\lambda\theta_t külön levonódik, a L2 Adam esetén viszont a decay bekerül a momentumokba, és az adaptív normalizálás részben elfedi a nagyságát. A példa nem állítja, hogy az egyik mindig jobb; csak azt mutatja, hogy a két frissítési szabály matematikailag nem azonos.

6.4.6 Labor: két optimizerlépés kézzel és NumPy-függvénnyel

Munkakönyvtár: lab/n024/. A kód csak CPU-t és NumPy-t használ; dtype=np.float64 a pontos összehasonlításhoz. A seed itt nem befolyásolja az eredményt, mert a gradiensértékeket explicit módon adjuk meg; ha később véletlen gradienst generálunk, használjuk a np.random.default_rng(20261020) generátort.

#!/usr/bin/env python3
# lab/n024/optim_steps.py
import numpy as np

def adamw_step_scalar(theta, m, v, g, lr, beta1, beta2, lam, t, eps):
    m = beta1 * m + (1.0 - beta1) * g
    v = beta2 * v + (1.0 - beta2) * g * g
    m_hat = m / (1.0 - beta1 ** t)
    v_hat = v / (1.0 - beta2 ** t)
    theta_new = (
        theta
        - lr * lam * theta
        - lr * m_hat / (np.sqrt(v_hat) + eps)
    )
    return theta_new, m, v

def adam_l2_step_scalar(theta, m, v, g, lr, beta1, beta2, lam, t, eps):
    grad = g + lam * theta
    m = beta1 * m + (1.0 - beta1) * grad
    v = beta2 * v + (1.0 - beta2) * grad * grad
    m_hat = m / (1.0 - beta1 ** t)
    v_hat = v / (1.0 - beta2 ** t)
    theta_new = theta - lr * m_hat / (np.sqrt(v_hat) + eps)
    return theta_new, m, v

def main():
    np.set_printoptions(precision=12, floatmode="fixed")
    theta0 = np.float64(2.0)
    g = np.float64(1.0)
    lr = np.float64(0.1)
    beta1 = np.float64(0.5)
    beta2 = np.float64(0.5)
    lam = np.float64(0.5)
    eps = np.float64(0.0)

    # AdamW két lépés
    theta = theta0
    m = np.float64(0.0)
    v = np.float64(0.0)
    for t in (1, 2):
        theta, m, v = adamw_step_scalar(
            theta, m, v, g, lr, beta1, beta2, lam, t, eps
        )
        print(f"AdamW step {t}: theta={theta}, m={m}, v={v}")

    # Naiv L2 Adam két lépés
    theta = theta0
    m = np.float64(0.0)
    v = np.float64(0.0)
    for t in (1, 2):
        theta, m, v = adam_l2_step_scalar(
            theta, m, v, g, lr, beta1, beta2, lam, t, eps
        )
        print(f"L2 Adam step {t}: theta={theta}, m={m}, v={v}")

if __name__ == "__main__":
    main()

Futtatási parancs a lab/n024/ könyvtárból:

python optim_steps.py

A kézi levezetésből várt kimenet:

AdamW step 1: theta=1.800..., m=0.5, v=0.5
AdamW step 2: theta=1.610..., m=0.75, v=0.75
L2 Adam step 1: theta=1.900..., m=1.0, v=2.0
L2 Adam step 2: theta=1.800..., m=1.475, v=2.90125

Az egyezést rtol=1e-12 mellett érdemes ellenőrizni np.allclose-zal a kézzel számolt értékekre. A megadott kimenet levezetett számérték; az ellenőrző kód önállóan futtatható.

6.4.7 Feladatok

6.4.7.1 F1 fogalmi, nehézség 1

Magyarázza el, mi a különbség az Adam első és második momentuma között, és miért szükséges a bias correction. Térjen ki arra, hogy m0=v0=0m_0=v_0=0 miért torzítja lefelé az első lépéseket. Elvárt eredmény: legfeljebb fél oldal saját magyarázat, benne a 1−βt1-\beta^t tag szerepe.

6.4.7.2 F2 levezetési, nehézség 2

Igazolja, hogy ha egy dd-dimenziós feladatban az első tt gradiens mindegyike ugyanaz a c∈ℝdc\in\mathbb R^d vektor, akkor az Adam bias-korrigált első momentuma m̂t=c\hat m_t=c, és a második momentum v̂t=c2\hat v_t=c^2, ahol c2c^2 elemenkénti négyzet. Mondja ki, hogy ez az állítás milyen feltétel mellett érvényes, és mutasson ellenpéldát arra, amikor a gradiensek nem egyenlők, de a bias correction mégsem adja vissza az utolsó gradienst.

6.4.7.3 F3 implementációs, nehézség 1

A lab/n024/optim_steps.py mellé írjon egy sgd_momentum_step(theta, buf, g, lr, beta) függvényt a PyTorch momentumos SGD képlete alapján. Bemenet: θ0=0,5\theta_0=0{,}5, g1=g2=0,2g_1=g_2=0{,}2, η=0,1\eta=0{,}1, β=0,9\beta=0{,}9, dtype=np.float64. Adja meg θ2\theta_2-t és ellenőrizze, hogy θ2=0,442\theta_2=0{,}442 legyen. Elvárt átadandó eredmény: teljes függvénykód, futtatási parancs és a kapott theta érték.

6.4.7.4 F4 hibakeresési, nehézség 2

Az alábbi Adam-implementáció hibás:

def rossz_adam(theta, m, v, g, t, lr, beta1, beta2, eps):
    m = beta1 * m + (1-beta1) * g
    v = beta2 * v + (1-beta2) * g * g
    m_hat = m / (1 - beta1 ** t)
    theta = theta - lr * m_hat / (np.sqrt(v) + eps)
    return theta, m, v

Azonosítsa a hibát, magyarázza el a következményét a második lépésben, és javítsa a kódot. Igazolja a javítást a szakasz kézi példáján. Elvárt eredmény: hibaleírás, javított kód és a javított változat θ2\theta_2 értéke.

6.4.7.5 F5 kísérleti/transzfer, nehézség 3

Tervezzen egy kis CPU-s protokollt, amely ugyanazon a rögzített modellen és adathalmazon hasonlítja össze az SGD-t, a momentumos SGD-t, az Adamet és az AdamW-t. Határozza meg: a modellt, a veszteséget, a splitet, a metrikát, a tanítási költségkeretet, a seedkezelést és a hiperparaméter-keresést. Az értékelés végén mondja meg, milyen következtetést nem szabad levonni egyetlen futtatásból. Elvárt eredmény: protokollterv és a lehetséges érvényességi korlátok indoklása, futás nélkül.

6.4.8 Megoldások és indoklás

6.4.8.1 F1 megoldás

Az mtm_t a gradiensvektor mozgóátlaga, ezért elsősorban az irányt simítja; a vtv_t a gradiens elemenkénti négyzetének mozgóátlaga, ezért a négyzetes nagyságot becsli. A nevezőbeli v̂t\sqrt{\hat v_t} koordinátánként eltérő léptéket ad. Az inicializálás m0=v0=0m_0=v_0=0: az első lépésben m1=(1−β1)g1m_1=(1-\beta_1)g_1, tehát a g1g_1 érték helyett annak csak (1−β1)(1-\beta_1)-szeresét tároljuk. A tt-edik lépésig a mozgóátlag súlyainak összege 1−β1t1-\beta_1^t, ezért osztunk ezzel. Hasonlóan vtv_t esetén 1−β2t1-\beta_2^t. A bias correction tehát nem a gradiens torzítását javítja, hanem a nulla kezdőállapotból adódó skálázást.

6.4.8.2 F2 megoldás

Ha gs=cg_s=c minden s=1,…,ts=1,\dots,t esetén, akkor a rekurziót kibontva:

mt=(1−β1)∑s=1tβ1t−sc=(1−β1)1−β1t1−β1c=(1−β1t)c. m_t = (1-\beta_1)\sum_{s=1}^{t}\beta_1^{t-s}c = (1-\beta_1)\frac{1-\beta_1^t}{1-\beta_1}c = (1-\beta_1^t)c.

Ezért m̂t=mt/(1−β1t)=c\hat m_t=m_t/(1-\beta_1^t)=c. Ugyanígy vt=(1−β2t)c2v_t=(1-\beta_2^t)c^2, tehát v̂t=c2\hat v_t=c^2. A feltétel az, hogy a gradiensek determinisztikusan azonosak legyenek. Ha például g1=1g_1=1 és g2=−1g_2=-1 skalár esetén t=2t=2 és β1=0,5\beta_1=0{,}5, akkor m2=0m_2=0, míg az utolsó gradiens −1-1, tehát m̂2=0≠g2\hat m_2=0\neq g_2; a bias correction nem reprodukálja az időben változó gradienst.

6.4.8.3 F3 megoldás

import numpy as np

def sgd_momentum_step(theta, buf, g, lr, beta):
    buf = beta * buf + g
    theta = theta - lr * buf
    return theta, buf

theta = np.float64(0.5)
buf = np.float64(0.0)
g = np.float64(0.2)
lr = np.float64(0.1)
beta = np.float64(0.9)

for _ in range(2):
    theta, buf = sgd_momentum_step(theta, buf, g, lr, beta)

print(theta)  # 0.442

Ellenőrzés: 1. lépésben buf=0,2buf=0{,}2, θ=0,48\theta=0{,}48; 2. lépésben buf=0,38buf=0{,}38, θ=0,48−0,038=0,442\theta=0{,}48-0{,}038=0{,}442.

6.4.8.4 F4 megoldás

A kód a második momentumot nem korrigálja a 1−β2t1-\beta_2^t tényezővel. Emiatt v̂t\hat v_t alulbecsült marad, ami túl kicsi nevezőt és túl nagy adaptív lépést okozhat, különösen a kezdeti lépésekben. A javítás:

v_hat = v / (1 - beta2 ** t)
theta = theta - lr * m_hat / (np.sqrt(v_hat) + eps)

A szakasz példáján β1=β2=0,5\beta_1=\beta_2=0{,}5, g1=1g_1=1 esetén v1=0,5v_1=0{,}5, a hibás kód v1≈0,707\sqrt{v_1}\approx0{,}707, a javított v̂1=1\sqrt{\hat v_1}=1 nevezőt ad. A helyes érték θ1=1,9\theta_1=1{,}9 a L2 Adam példában; a hibás kód ettől eltérő, nagyobb lépést adna.

6.4.8.5 F5 megoldásminta

Modell: lineáris logisztikus regresszió a GlyphLab-példa 24×2424\times24 képének előre kivett hisztogram-jellemzőin, vagy egy kis MLP. Veszteség: cross-entropy. Adat: a GlyphLab data/ könyvtár train/val/test splitje, csoportosítás scene_id szerint. Metrika: valószínűségi AUC vagy log loss a validációs halmazon, a végső jelentés a test halmazon. Költségkeret: legfeljebb például 50 epoch CPU-n, rögzített batch méret. Seedkezelés: minden optimizerhez legalább három különböző seed, és a kezdeti súlyok azonos seedű inicializálása. Keresés: minden optimizer tanulási rátájára kis logaritmikus rács, a validációs metrika alapján választva. Nem szabad levonni, hogy egyetlen legjobb seed alapján az egyik optimizer általánosan jobb; a seedek közötti szórás az algoritmikus bizonytalanság része, és a kis toy feladat nem reprezentálja a valós CNN-feladatokat.

6.4.9 Tipikus tévedés ellenpéldával

Gyakori hiba azt hinni, hogy egy optimizer neve önmagában garantál jobb pontosságot vagy konvergenciát. Tekintsük az f(θ)=12θ2f(\theta)=\frac12\theta^2 függvényt, gradiens gt=θtg_t=\theta_t, θ0=10\theta_0=10. Sima SGD η=0,1\eta=0{,}1 esetén θt=10⋅0,9t\theta_t=10\cdot0{,}9^t, tehát monoton csökken és 100100 lépés után θ100≈2,6⋅10−5\theta_{100}\approx2{,}6\cdot10^{-5}. Ha Adamet használunk β1=β2=0\beta_1=\beta_2=0, η=0,1\eta=0{,}1, ϵ=0\epsilon=0 mellett, akkor a frissítés −η⋅sign(θ)-\eta\cdot\mathrm{sign}(\theta): minden lépés 0,10{,}1 nagyságú, így 100100 lépés kell a nullához, és a pálya lényegesen lassabb. Ez a mesterséges ellenpélda nem bizonyítja, hogy az SGD mindig jobb; azt mutatja, hogy az Adam normalizált lépése bizonyos skálázású feladatoknál elveszítheti a gradiens nagyságából származó előnyt.

6.4.10 Önellenőrzés és visszahívás

Önellenőrzés: írja fel az AdamW frissítést skalár esetben, majd ellenőrizze, hogy a decay tag valóban kívül van-e a nevezőn. Ha a frissítésben λθt\lambda\theta_t az adaptív nevezőn belül szerepel, akkor az L2 Adam, nem AdamW. Visszahívás a 6.3. Sztochasztikus és minibatch gradiens alfejezetből: a minibatch-gradiens torzítatlan becslése a momentum és az Adam állapotváltozóiba kerül, így az ott levezetett variancia csökkenése a lépés zaját, nem feltétlenül az optimizer teljes pályájának stabilizálását írja le. A 2.4. Kis tudományos szoftverprojekt alfejezetből pedig az következik, hogy az optimizer kódját ugyanúgy kis fixture-ökön kell tesztelni, mint bármely más modult.

6.4.11 Rövid összefoglaló

A momentumos SGD a gradiens rekurzív mozgóátlagát tárolja, és ezzel csökkenti a lépés irányának fluktuációját. Az Adam két állapotot tart: az első momentum a gradiens irányát, a második momentum a koordinátánkénti négyzetes nagyságot becsli; a bias correction a nulla kezdőállapot miatti kezdeti lefelé torzítást korrigálja. Az AdamW a súlycsökkentést elkülönítve alkalmazza: a λθt\lambda\theta_t tag nem kerül a momentumokba, ezért matematikailag nem azonos a naiv L2 Adam-mel. A kézi kétlépéses skalárpélda numerikusan is mutatja az eltérést. Az optimizer neve azonban nem garancia, a választást mindig a feladaton és a seedismétléseken kell ellenőrizni.

6.4.12 Következő alkalmazás

A 7.1. Entrópia, cross-entropy és KL alfejezetben az entrópia, a cross-entropy és a KL-divergencia következik. Ott a veszteségfüggvény pontos valószínűségi értelmezését építjük fel; az itt tárgyalt frissítési szabályokat ezután konkrét célfüggvények gradiensére alkalmazzuk.

6.4.13 Források