Faza 03 · lecția 06

Optimizatori

Scopul lecției: Coborârea gradientului vă spune în ce direcție să vă deplasați. Nu spune nimic despre distanță sau viteză. SGD este o busolă. Adam este un GPS cu date despre trafic.

Versiunea curentă AlexBred.com: primele 100 de lecții ale programului în limba română.

Curs
AI Engineering from Scratch
Fază
Fundamentele învățării profunde
Lectură
23 min.
Verificat
Cuprinsul lecției
  1. Obiective de învățare
  2. Problema
  3. Conceptul
  4. Coborârea stocastică a gradientului — SGD
  5. Momentum
  6. RMSProp
  7. Adam: momentum plus RMSProp
  8. AdamW: decay al ponderilor decuplat
  9. Rata de învățare: un hiperparametru esențial
  10. Compararea optimizatorilor
  11. Când poate fi potrivit fiecare optimizator
  12. Construiți
  13. Pasul 1: SGD elementar
  14. Pasul 2: SGD cu momentum
  15. Pasul 3: Adam
  16. Pasul 4: AdamW
  17. Pasul 5: compararea antrenării
  18. Folosiți
  19. Livrați
  20. Exerciții
  21. Termeni-cheie
  22. Lecturi suplimentare

Coborârea gradientului vă spune în ce direcție să vă deplasați. Nu spune nimic despre distanță sau viteză. SGD este o busolă. Adam este un GPS cu date despre trafic.

Tip: Construire Limbaje: Python Cerințe preliminare: Lecția 03.05 — Funcții de pierdere Durată: ~75 de minute

Obiective de învățare

  • Să implementați de la zero în Python optimizatorii SGD, SGD cu momentum, Adam și AdamW.
  • Să explicați cum compensează corecția deplasării din Adam inițializarea cu zero a estimărilor momentelor în primii pași ai antrenării.
  • Să explicați diferența dintre AdamW și Adam cu regularizare L2 și să proiectați o comparație a generalizării pe aceeași sarcină.
  • Să selectați un optimizator și hiperparametri inițiali potriviți pentru transformatoare, CNN-uri, GAN-uri și ajustare fină.

Problema

Ați calculat gradienții. Știți că ponderea cu numărul 4721 are un gradient de 0.003, deci scăderea ei ar reduce local pierderea. Dar cu cât trebuie modificată efectiv? Cu ce factor scalați gradientul? Și trebuie să faceți aceeași deplasare la pasul 1 și la pasul 1000?

Notă tehnică a traducerii: Gradientul 0.003 indică o rată locală de variație, nu că ponderea „trebuie să scadă cu 0,003”, cum sugerează originalul. Actualizarea efectivă depinde de rata de învățare, optimizator, starea acestuia și eventualele transformări precum clipping-ul sau decay-ul.

Coborârea gradientului elementară aplică aceeași rată de învățare fiecărui parametru la fiecare pas: w = w - lr * gradient. În practică, această regulă simplă poate produce trei dificultăți în antrenarea rețelelor neurale.

Prima este oscilația. Peisajul pierderii rareori seamănă cu un bol neted; poate avea forma unei văi lungi și înguste. Gradientul indică puternic transversal văii — direcția abruptă — și mai slab de-a lungul ei — direcția puțin înclinată. Coborârea gradientului poate sări înainte și înapoi peste dimensiunea îngustă, progresând foarte puțin în direcția utilă. Ați putea vedea pierderea scăzând repede și apoi plafonându-se nu pentru că modelul a convergent, ci pentru că actualizările oscilează.

A doua este folosirea unei singure rate de învățare pentru toți parametrii. Unii parametri pot beneficia de actualizări mai mari, iar alții de actualizări mici. O rată potrivită primilor îi poate destabiliza pe ceilalți și invers. Metodele adaptive încearcă să normalizeze actualizările pe coordonate folosind istoricul gradienților.

A treia este prezența punctelor șa și a regiunilor plate. În dimensiuni mari, peisajul pierderii poate avea regiuni vaste în care gradientul este aproape zero. SGD înaintează lent prin ele. Zgomotul mini-loturilor, momentum și metodele adaptive pot ajuta, dar nu garantează ieșirea din orice regiune plată.

Adam combină două medii mobile pentru fiecare parametru: media gradientului — momentum, utilă împotriva oscilației — și media pătratului gradientului — scalare adaptivă pentru coordonate cu magnitudini diferite. Împreună cu corecția deplasării inițiale, oferă un optimizator robust pentru numeroase probleme. În această lecție îl construiți de la zero, pentru a înțelege atât mecanismul, cât și limitele sale.

Notă tehnică a traducerii: Afirmațiile că Adam „rezolvă toate trei” problemele și funcționează implicit pentru exact 80% dintre sarcini sunt euristici fără garanție generală. SGD are deja zgomot stocastic care poate facilita traversarea unor regiuni, iar Adam poate la rândul lui stagna sau generaliza slab în anumite configurații.

Conceptul

Coborârea stocastică a gradientului — SGD

Cel mai simplu optimizator. Calculați gradientul pe un mini-lot și faceți un pas în direcția opusă.

w = w - lr * gradient

„Stocastică” înseamnă că folosiți un subansamblu aleator de date — un mini-lot — pentru a estima gradientul, nu întregul set de date. Zgomotul rezultat poate fi util pentru explorarea peisajului, dar produce și variație și oscilații.

Rata de învățare este singurul parametru al regulii elementare. Dacă este prea mare, pierderea poate diverge. Dacă este prea mică, antrenarea poate dura foarte mult. Valoarea potrivită depinde de arhitectură, date, dimensiunea lotului și etapa antrenării. Pentru unele rețele moderne antrenate cu SGD, valori precum 0,01–0,1 sunt puncte de pornire, însă chiar în cadrul aceleiași rulări poate fi utilă schimbarea ratei.

Notă tehnică a traducerii: Nu există un interval universal al ratei de învățare pentru SGD. Parametrizarea modelului, normalizarea, dimensiunea lotului, reducerea pierderii și programul ratei pot schimba scara potrivită cu multe ordine de mărime.

Momentum

Analogia bilei care se rostogolește la vale este folosită des, dar surprinde intuiția. În loc să faceți un pas numai după gradientul curent, mențineți o viteză care acumulează gradienți anteriori.

m_t = beta * m_{t-1} + gradient
w = w - lr * m_t

beta, de obicei 0,9 ca punct de pornire, controlează câtă istorie se păstrează. Pentru beta = 0.9, contribuțiile ultimilor aproximativ zece pași au o pondere importantă.

De ce poate reduce oscilația: gradienții orientați consecvent în aceeași direcție se acumulează. Componentele care își schimbă semnul tind să se anuleze. În valea îngustă, componenta transversală își poate schimba semnul la fiecare pas și este amortizată, în timp ce componenta longitudinală rămâne consecventă și se amplifică. Rezultatul poate fi o accelerare mai lină în direcția utilă.

Pe un peisaj prost condiționat, SGD simplu poate necesita 10.000 de pași într-un anumit experiment, iar SGD cu momentum poate necesita doar 3.000–5.000. Aceste numere ilustrează un posibil avantaj, nu o rată universală de accelerare.

Notă tehnică a traducerii: Formula afișată nu conține factorul (1 - beta), deci m_t este o sumă exponențial ponderată, nu media ultimilor zece gradienți; la gradient constant, masa sa tinde spre 1/(1-beta) = 10. O formulă de medie mobilă exponențială ar include (1-beta) * gradient, iar rata de învățare ar trebui ajustată corespunzător.

RMSProp

O metodă influentă cu rată de învățare adaptivă pe parametru, propusă de Hinton într-un curs Coursera și rămasă fără o publicație formală originală.

s_t = beta * s_{t-1} + (1 - beta) * gradient^2
w = w - lr * gradient / (sqrt(s_t) + epsilon)

s_t urmărește media mobilă a pătratelor gradienților. Parametrii cu gradienți constant mari sunt împărțiți la un număr mare — o actualizare efectivă mai mică. Parametrii cu gradienți mici sunt împărțiți la un număr mai mic — o actualizare relativ mai mare.

Aceasta abordează diferențele de scară dintre coordonate. O coordonată care a primit gradienți mari este normalizată mai puternic, iar una cu gradienți mici mai puțin.

epsilon, adesea 1e-8, previne împărțirea la zero și îmbunătățește stabilitatea numerică atunci când istoricul pătratelor este foarte mic.

Notă tehnică a traducerii: Mărimea istorică a gradientului nu spune că un parametru este „aproape de țintă” sau „subantrenat”, așa cum afirmă originalul. RMSProp normalizează scara actualizărilor pe baza pătratelor gradienților; nu estimează distanța până la optim.

Adam: momentum plus RMSProp

Adam combină cele două idei. Menține două medii mobile exponențiale pentru fiecare parametru:

m_t = beta1 * m_{t-1} + (1 - beta1) * gradient        (primul moment: media)
v_t = beta2 * v_{t-1} + (1 - beta2) * gradient^2       (al doilea moment brut: media pătratelor)

Corecția deplasării este detaliul esențial pe care multe explicații îl omit. La pasul 1, m_1 = (1 - beta1) * gradient. Cu beta1 = 0.9, aceasta înseamnă 0.1 * gradient, de zece ori mai mic decât gradientul curent. Media mobilă nu s-a încălzit încă. Corecția compensează inițializarea cu zero:

m_hat = m_t / (1 - beta1^t)
v_hat = v_t / (1 - beta2^t)

La pasul 1 cu beta1 = 0.9, m_hat = m_1 / (1 - 0.9) = m_1 / 0.1, adică gradientul curent. La pasul 100, 1 - 0.9^100 este aproximativ 1, astfel încât această corecție a primului moment devine neglijabilă.

Notă tehnică a traducerii: v_t estimează momentul brut de ordinul al doilea E[g^2], nu varianța centrată E[(g-E[g])^2]. În plus, afirmația că întreaga corecție este irelevantă după aproximativ 50 de pași ignoră beta2=0.999: factorul 1-beta2^t se apropie lent de 1 și corecția celui de-al doilea moment rămâne substanțială sute sau mii de pași.

Actualizarea:

w = w - lr * m_hat / (sqrt(v_hat) + epsilon)

Valorile implicite consacrate pentru Adam sunt lr = 0.001, beta1 = 0.9, beta2 = 0.999 și epsilon = 1e-8. Sunt puncte de pornire utile pentru multe probleme. Dacă rezultatul este slab, rata de învățare este de obicei primul parametru de explorat, dar și ceilalți pot conta în funcție de zgomotul gradienților și arhitectură.

AdamW: decay al ponderilor decuplat

Regularizarea L2 adaugă un termen proporțional cu lambda * w^2 la pierdere. Pentru SGD standard, aceasta este echivalentă cu decay-ul ponderilor după o rescalare a coeficientului. În Adam, echivalența se pierde.

Ideea lui Loshchilov și Hutter: când adăugați L2 la pierdere și Adam prelucrează gradientul rezultat, factorul adaptiv scalează și termenul de regularizare. Parametrii cu istorii diferite ale pătratelor gradienților primesc intensități diferite ale efectului. Decay-ul decuplat urmărește o micșorare proporțională independentă de această precondiționare.

AdamW aplică decay-ul direct parametrului, separat de actualizarea Adam:

w = w - lr * m_hat / (sqrt(v_hat) + epsilon) - lr * lambda * w

Termenul de decay lr * lambda * w nu este împărțit la factorul adaptiv Adam. Fiecare parametru primește aceeași rată proporțională de micșorare, dacă aparține unui grup cu același coeficient.

AdamW a îmbunătățit performanța de generalizare față de Adam cu L2 în experimentele lucrării originale și a devenit o alegere frecventă pentru transformatoare și modele de difuzie. Totuși, avantajul și hiperparametrii potriviți depind de sarcină.

Notă tehnică a traducerii: Afirmația că AdamW produce soluții mai bune „pe aproape orice sarcină” și că toate modelele BERT, GPT, LLaMA și Stable Diffusion au fost antrenate astfel este prea generală pentru arhitecturi și versiuni diferite. AdamW este larg folosit, dar nu garantează cea mai bună generalizare, iar unele rețete exclud biasurile și parametrii de normalizare din decay.

Rata de învățare: un hiperparametru esențial

Диаграмма к уроку «Optimizatori»

Dacă reglați un singur hiperparametru al optimizării, începeți cu rata de învățare. O schimbare de zece ori poate avea un efect major. Puncte de pornire întâlnite frecvent:

  • SGD: lr = 0.01 până la 0.1.
  • Adam/AdamW: lr = 1e-4 până la 3e-4 pentru multe modele profunde, deși valoarea implicită Adam este 1e-3.
  • Ajustarea fină a modelelor preantrenate: lr = 1e-5 până la 5e-5 în unele rețete.
  • Încălzirea ratei de învățare: rampă liniară pe o fracțiune inițială a pașilor, adesea între 1% și 10%.

Notă tehnică a traducerii: Pragurile absolute lr > 0.01 și lr < 0.00001 din diagrama originală nu pot defini universal „prea mare” sau „prea mic”. Nici afirmația că o schimbare de zece ori contează mai mult decât orice decizie arhitecturală nu este o lege; toate valorile de mai sus sunt euristici dependente de configurație.

Compararea optimizatorilor

Диаграмма к уроку «Optimizatori»

Notă tehnică a traducerii: Săgețile nu reprezintă o ierarhie universală. AdamW nu este întotdeauna mai rapid sau mai bun decât Adam, iar afirmațiile că SGD găsește neapărat minime mai plate și AdamW oferă cea mai bună generalizare depind de problemă, programul ratei și regularizare.

Când poate fi potrivit fiecare optimizator

Диаграмма к уроку «Optimizatori»

Notă tehnică a traducerii: Arborele oferă valori inițiale, nu configurații garantate. De exemplu, rata potrivită pentru un LLM variază cu dimensiunea modelului, lotul global, programul ratei, durata și parametrizarea, iar decay-ul nu se aplică obligatoriu tuturor parametrilor.

optimizer-trajectory

Construiți

Pasul 1: SGD elementar

class SGD:
    def __init__(self, lr=0.01):
        self.lr = lr

    def step(self, params, grads):
        for i in range(len(params)):
            params[i] -= self.lr * grads[i]

Pasul 2: SGD cu momentum

class SGDMomentum:
    def __init__(self, lr=0.01, beta=0.9):
        self.lr = lr
        self.beta = beta
        self.velocities = None

    def step(self, params, grads):
        if self.velocities is None:
            self.velocities = [0.0] * len(params)
        for i in range(len(params)):
            self.velocities[i] = self.beta * self.velocities[i] + grads[i]
            params[i] -= self.lr * self.velocities[i]

Pasul 3: Adam

import math

class Adam:
    def __init__(self, lr=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8):
        self.lr = lr
        self.beta1 = beta1
        self.beta2 = beta2
        self.epsilon = epsilon
        self.m = None
        self.v = None
        self.t = 0

    def step(self, params, grads):
        if self.m is None:
            self.m = [0.0] * len(params)
            self.v = [0.0] * len(params)

        self.t += 1

        for i in range(len(params)):
            self.m[i] = self.beta1 * self.m[i] + (1 - self.beta1) * grads[i]
            self.v[i] = self.beta2 * self.v[i] + (1 - self.beta2) * grads[i] ** 2

            m_hat = self.m[i] / (1 - self.beta1 ** self.t)
            v_hat = self.v[i] / (1 - self.beta2 ** self.t)

            params[i] -= self.lr * m_hat / (math.sqrt(v_hat) + self.epsilon)

Pasul 4: AdamW

class AdamW:
    def __init__(self, lr=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8, weight_decay=0.01):
        self.lr = lr
        self.beta1 = beta1
        self.beta2 = beta2
        self.epsilon = epsilon
        self.weight_decay = weight_decay
        self.m = None
        self.v = None
        self.t = 0

    def step(self, params, grads):
        if self.m is None:
            self.m = [0.0] * len(params)
            self.v = [0.0] * len(params)

        self.t += 1

        for i in range(len(params)):
            self.m[i] = self.beta1 * self.m[i] + (1 - self.beta1) * grads[i]
            self.v[i] = self.beta2 * self.v[i] + (1 - self.beta2) * grads[i] ** 2

            m_hat = self.m[i] / (1 - self.beta1 ** self.t)
            v_hat = self.v[i] / (1 - self.beta2 ** self.t)

            params[i] -= self.lr * m_hat / (math.sqrt(v_hat) + self.epsilon)
            params[i] -= self.lr * self.weight_decay * params[i]

Notă tehnică a traducerii: Codul aplică mai întâi pasul Adam, apoi calculează decay-ul folosind parametrul deja actualizat. Astfel micșorează ușor și pasul Adam printr-un termen suplimentar de ordinul lr^2 * weight_decay. Formula AdamW standard aplică factorul (1 - lr * weight_decay) parametrului de la începutul pasului, separat de actualizarea adaptivă. Blocul rămâne neschimbat față de sursă.

Pasul 5: compararea antrenării

Antrenați aceeași rețea cu două straturi pe setul de date circular din lecția 05 folosind toți cei patru optimizatori. Comparați convergența.

import random

def sigmoid(x):
    x = max(-500, min(500, x))
    return 1.0 / (1.0 + math.exp(-x))

def make_circle_data(n=200, seed=42):
    random.seed(seed)
    data = []
    for _ in range(n):
        x = random.uniform(-2, 2)
        y = random.uniform(-2, 2)
        label = 1.0 if x * x + y * y < 1.5 else 0.0
        data.append(([x, y], label))
    return data


class OptimizerTestNetwork:
    def __init__(self, optimizer, hidden_size=8):
        random.seed(0)
        self.hidden_size = hidden_size
        self.optimizer = optimizer

        self.w1 = [[random.gauss(0, 0.5) for _ in range(2)] for _ in range(hidden_size)]
        self.b1 = [0.0] * hidden_size
        self.w2 = [random.gauss(0, 0.5) for _ in range(hidden_size)]
        self.b2 = 0.0

    def get_params(self):
        params = []
        for row in self.w1:
            params.extend(row)
        params.extend(self.b1)
        params.extend(self.w2)
        params.append(self.b2)
        return params

    def set_params(self, params):
        idx = 0
        for i in range(self.hidden_size):
            for j in range(2):
                self.w1[i][j] = params[idx]
                idx += 1
        for i in range(self.hidden_size):
            self.b1[i] = params[idx]
            idx += 1
        for i in range(self.hidden_size):
            self.w2[i] = params[idx]
            idx += 1
        self.b2 = params[idx]

    def forward(self, x):
        self.x = x
        self.z1 = []
        self.h = []
        for i in range(self.hidden_size):
            z = self.w1[i][0] * x[0] + self.w1[i][1] * x[1] + self.b1[i]
            self.z1.append(z)
            self.h.append(max(0.0, z))

        self.z2 = sum(self.w2[i] * self.h[i] for i in range(self.hidden_size)) + self.b2
        self.out = sigmoid(self.z2)
        return self.out

    def compute_grads(self, target):
        eps = 1e-15
        p = max(eps, min(1 - eps, self.out))
        d_loss = -(target / p) + (1 - target) / (1 - p)
        d_sigmoid = self.out * (1 - self.out)
        d_out = d_loss * d_sigmoid

        grads = [0.0] * (self.hidden_size * 2 + self.hidden_size + self.hidden_size + 1)
        idx = 0
        for i in range(self.hidden_size):
            d_relu = 1.0 if self.z1[i] > 0 else 0.0
            d_h = d_out * self.w2[i] * d_relu
            grads[idx] = d_h * self.x[0]
            grads[idx + 1] = d_h * self.x[1]
            idx += 2

        for i in range(self.hidden_size):
            d_relu = 1.0 if self.z1[i] > 0 else 0.0
            grads[idx] = d_out * self.w2[i] * d_relu
            idx += 1

        for i in range(self.hidden_size):
            grads[idx] = d_out * self.h[i]
            idx += 1

        grads[idx] = d_out
        return grads

    def train(self, data, epochs=300):
        losses = []
        for epoch in range(epochs):
            total_loss = 0.0
            correct = 0
            for x, y in data:
                pred = self.forward(x)
                grads = self.compute_grads(y)
                params = self.get_params()
                self.optimizer.step(params, grads)
                self.set_params(params)

                eps = 1e-15
                p = max(eps, min(1 - eps, pred))
                total_loss += -(y * math.log(p) + (1 - y) * math.log(1 - p))
                if (pred >= 0.5) == (y >= 0.5):
                    correct += 1
            avg_loss = total_loss / len(data)
            accuracy = correct / len(data) * 100
            losses.append((avg_loss, accuracy))
            if epoch % 75 == 0 or epoch == epochs - 1:
                print(f"    Epoch {epoch:3d}: loss={avg_loss:.4f}, accuracy={accuracy:.1f}%")
        return losses

Notă tehnică a traducerii: Blocul definește rețeaua și metoda de antrenare, dar nu instanțiază și nu rulează cei patru optimizatori, deci nu produce singur comparația promisă. Limitările din sigmoidă și BCE modifică funcția, însă compute_grads nu aplică derivatele limitărilor; pentru predicții saturate și greșite, aceasta poate da un gradient foarte mic sau zero în locul formei stabile p - y a BCE pe logiți. O comparație corectă trebuie să aleagă separat rate potrivite, să folosească aceleași inițializări și ordine a datelor, să repete mai multe seeduri și să evalueze după epocă un model fix pe un set separat; aici acuratețea agregă predicții realizate înaintea unor actualizări succesive.

Folosiți

Optimizatorii PyTorch gestionează grupuri de parametri, clipping-ul gradienților și programele ratei de învățare:

import torch
import torch.optim as optim

model = torch.nn.Sequential(
    torch.nn.Linear(784, 256),
    torch.nn.ReLU(),
    torch.nn.Linear(256, 10),
)

optimizer = optim.AdamW(model.parameters(), lr=3e-4, weight_decay=0.01)

scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100)

for epoch in range(100):
    optimizer.zero_grad()
    output = model(torch.randn(32, 784))
    loss = torch.nn.functional.cross_entropy(output, torch.randint(0, 10, (32,)))
    loss.backward()
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
    optimizer.step()
    scheduler.step()

În bucla simplă de mai sus, ordinea este: zero_grad, propagare înainte, pierdere, backward, opțional clipping, step, apoi scheduler.step. Rețineți această ordine pentru acest tip de program. Apelarea scheduler.step() înainte de optimizer.step() este o sursă frecventă de erori în versiunile moderne PyTorch.

Notă tehnică a traducerii: Ordinea nu este literalmente „întotdeauna” aceeași. Acumularea gradienților, precizia mixtă, optimizatorii cu closure și planificatoare precum ReduceLROnPlateau introduc pași sau momente de apel diferite. Documentația fiecărui scheduler stabilește dacă este actualizat pe lot, pe epocă ori după metrica de validare.

Pentru CNN-uri, mulți practicieni folosesc încă SGD cu momentum — de exemplu lr=0.1, momentum=0.9, weight_decay=1e-4 — și un program în trepte sau cosinus. Pentru transformatoare și LLM-uri, AdamW cu încălzire și descreștere este un punct de pornire foarte răspândit. Tratați consensul drept ipoteză inițială și schimbați-o pe baza măsurătorilor.

Livrați

Această lecție produce:

  • outputs/prompt-optimizer-selector.md — un prompt decizional pentru alegerea optimizatorului și a ratei de învățare potrivite oricărei arhitecturi.

Exerciții

  1. Implementați momentum Nesterov, în care calculați gradientul în poziția de anticipare w - lr * beta * v, nu în poziția curentă. Comparați convergența cu momentum standard pe setul de date circular.

  2. Implementați un program de încălzire a ratei de învățare: rampă liniară de la 0 la max_lr în primii 10% dintre pașii de antrenare, apoi descreștere cosinus până la 0. Antrenați cu Adam plus încălzire și cu Adam fără încălzire. Măsurați câte epoci sunt necesare pentru a ajunge la o acuratețe de 90% pe setul circular.

  3. Urmăriți rata efectivă pentru fiecare parametru în timpul antrenării cu Adam. Actualizarea este lr * m_hat / (sqrt(v_hat) + eps). Reprezentați distribuția actualizărilor după 10, 50 și 200 de pași. Sunt toți parametrii actualizați cu aceeași viteză?

Notă tehnică a traducerii: Expresia din exercițiu este mărimea actualizării semnate, nu „rata efectivă de învățare”. Precondiționatorul pe coordonată este lr / (sqrt(v_hat) + eps), iar actualizarea rezultă după înmulțirea lui cu m_hat.

  1. Implementați clipping-ul gradientului după norma globală. Stabiliți norma maximă la 1,0. Antrenați cu și fără clipping folosind o rată mare — lr=0.01 pentru Adam. Numărați câte rulări diverg, cu pierderea devenită NaN, în fiecare variantă pe zece seeduri aleatoare.

  2. Implementați Adam cu regularizare L2 în gradient, adăugând lambda * w înaintea actualizării Adam, și comparați-l cu AdamW într-o rețea cu ponderi mari. Inițializați toate ponderile cu valori aleatoare din [-5, 5], mult mai mari decât în mod normal. Antrenați 200 de epoci cu lambda=0.1 și weight_decay=0.1, apoi reprezentați norma L2 a ponderilor și evaluați ambele variante pe un set păstrat separat. Verificați experimental dacă AdamW produce o micșorare mai rapidă sau o generalizare mai bună în această configurație.

Termeni-cheie

Termen Ce spun oamenii Ce înseamnă de fapt
Rată de învățare „Mărimea pasului” Multiplicatorul scalar de bază al actualizării; un hiperparametru cu impact major asupra antrenării
SGD „Coborârea de bază a gradientului” Coborâre stocastică a gradientului: actualizează ponderile scăzând lr * gradient, estimat pe un mini-lot
Momentum „Analogia bilei care se rostogolește” Sumă sau medie mobilă exponențial ponderată a gradienților anteriori, care amortizează oscilația și accelerează direcțiile consecvente
RMSProp „Rată de învățare adaptivă” Împarte gradientul fiecărui parametru la RMS-ul mobil al gradienților săi recenți, normalizând scările coordonatelor
Adam „Optimizatorul implicit” Combină primul moment cu momentul brut de ordinul al doilea și aplică o corecție pentru inițializarea cu zero
AdamW „Adam făcut corect” Adam cu decay decuplat al ponderilor, aplicat parametrilor separat de gradientul pierderii
Corecția deplasării „Încălzire pentru mediile mobile” Împărțirea la 1 - beta^t pentru a compensa inițializarea cu zero a estimărilor momentelor Adam
Decay al ponderilor „Micșorați ponderile” Reducerea proporțională a parametrilor la fiecare pas; efectul său diferă de regularizarea L2 în optimizatorii adaptivi
Programul ratei de învățare „Schimbarea ratei în timp” Funcție care ajustează rata în timpul antrenării; încălzirea urmată de descreștere cosinus este o opțiune modernă frecventă
Clipping al gradientului „Plafonarea normei gradientului” Rescalarea vectorului gradient când norma depășește un prag, pentru a limita actualizările explozive

Lecturi suplimentare

  • Kingma și Ba, „Adam: A Method for Stochastic Optimization” (2014) — lucrarea originală despre Adam, cu analiza convergenței și deducerea corecției deplasării.
  • Loshchilov și Hutter, „Decoupled Weight Decay Regularization” (2017) — a arătat că regularizarea L2 și decay-ul ponderilor nu sunt echivalente în Adam și a propus AdamW.
  • Smith, „Cyclical Learning Rates for Training Neural Networks” (2017) — a introdus testul intervalului ratei și programele ciclice care reduc nevoia unei rate fixe.
  • Ruder, „An Overview of Gradient Descent Optimization Algorithms” (2016) — sinteză amplă a variantelor de optimizatori, cu comparații și intuiții clare.

Sursă: Originalul în limba engleză

Navigare: ← Lecția 03.05 — Funcții de pierdere · Faza 3 — Fundamentele învățării profunde · Catalog complet