Faza 03 · lecția 07
Regularizare
Scopul lecției: Modelul obține 99% pe datele de antrenare și 60% pe cele de testare. A memorat în loc să învețe. Regularizarea este taxa impusă complexității pentru a favoriza generalizarea.
Versiunea curentă AlexBred.com: primele 100 de lecții ale programului în limba română.
Cuprinsul lecției
- Obiective de învățare
- Problema
- Conceptul
- Spectrul supraînvățării
- Dropout
- Decay-ul ponderilor — regularizare L2
- Normalizarea pe lot — BatchNorm
- Normalizarea pe strat — LayerNorm
- RMSNorm
- Compararea normalizărilor
- Augmentarea datelor ca regularizare
- Oprirea timpurie
- Ce să aplicați și când
- Construiți
- Pasul 1: dropout — modurile antrenare și evaluare
- Pasul 2: decay L2 al ponderilor
- Pasul 3: normalizarea pe lot
- Pasul 4: normalizarea pe strat
- Pasul 5: RMSNorm
- Pasul 6: antrenarea cu și fără regularizare
- Folosiți
- Livrați
- Exerciții
- Termeni-cheie
- Lecturi suplimentare
Modelul obține 99% pe datele de antrenare și 60% pe cele de testare. A memorat în loc să învețe. Regularizarea este taxa impusă complexității pentru a favoriza generalizarea.
Tip: Construire Limbaje: Python Cerințe preliminare: Lecția 03.06 — Optimizatori Durată: ~75 de minute
Obiective de învățare
- Să implementați de la zero dropout cu scalare inversă, decay L2 al ponderilor, normalizarea pe lot, normalizarea pe strat și RMSNorm.
- Să măsurați diferența de acuratețe dintre antrenare și testare și să diagnosticați supraînvățarea prin experimente de regularizare.
- Să explicați de ce transformatoarele folosesc de obicei LayerNorm în loc de BatchNorm și de ce multe LLM-uri moderne folosesc RMSNorm.
- Să aplicați o combinație potrivită de tehnici de regularizare în funcție de severitatea supraînvățării.
Problema
O rețea neurală suficient de expresivă poate memora seturi de date finite. Zhang și colaboratorii au demonstrat experimental în 2017 că arhitecturi standard pot potrivi etichete aleatoare pe seturi de imagini precum CIFAR-10 și ImageNet, ajungând la eroare de antrenare aproape zero fără un tipar generalizabil în etichete. Performanța pe datele de antrenare a ajuns aproape de perfecțiune, iar cea de testare a rămas la nivelul hazardului.
Notă tehnică a traducerii: Lucrarea nu „dovedește” prin acel experiment că orice rețea cu destui parametri memorează orice set; ea demonstrează empiric potrivirea etichetelor aleatoare pentru arhitecturile și seturile studiate și oferă separat o construcție teoretică de expresivitate finită. Pentru etichete aleatoare, acuratețea de testare este în medie la nivelul ghicirii, nu literalmente zero.
Aceasta este problema supraînvățării, iar capacitatea mai mare poate amplifica riscul. GPT-3 are 175 de miliarde de parametri și a fost antrenat pe sute de miliarde de tokenuri. O asemenea capacitate permite memorarea unor fragmente ale datelor de antrenare, pe lângă învățarea tiparelor generalizabile. Regularizarea, curățarea datelor și obiectivul de antrenare influențează echilibrul dintre aceste comportamente.
Notă tehnică a traducerii: Numărul parametrilor și numărul tokenurilor nu pot fi comparați direct pentru a deduce cât text va fi memorat, iar memorarea nu implică automat că modelul doar reproduce date. Lucrarea GPT-3 raportează un corpus filtrat de aproximativ 499 de miliarde de tokenuri, din care au fost prelevați 300 de miliarde de tokenuri în timpul antrenării.
Diferența dintre performanța la antrenare și cea pe date independente este decalajul de generalizare. Fiecare tehnică din această lecție îl abordează dintr-un unghi diferit. Dropout împiedică rețeaua să se bazeze permanent pe aceeași configurație de unități. Decay-ul ponderilor limitează creșterea normelor parametrilor. BatchNorm, LayerNorm și RMSNorm stabilizează scările activărilor și pot schimba dinamica optimizării; uneori produc și efecte de regularizare. Augmentarea diversifică exemplele, iar oprirea timpurie limitează numărul pașilor de adaptare la datele de antrenare.
Notă tehnică a traducerii: Normalizarea nu este doar „aceeași regularizare” aplicată în altă direcție, iar explicațiile originale — minime mai plate, funcționare identică între metode și RMSNorm exact cu 10% mai rapid — sunt simplificări. Efectele asupra optimizării și generalizării diferă după arhitectură și implementare.
Conceptul
Spectrul supraînvățării
Fiecare model se află undeva pe un spectru de la subînvățare — prea simplu pentru a surprinde tiparul — la supraînvățare — suficient de flexibil încât să surprindă și zgomotul. Regiunea potrivită este între ele, iar regularizarea poate deplasa un model dinspre supraînvățare către o complexitate efectivă mai adecvată.
Dropout
O tehnică de regularizare simplă, cu o interpretare elegantă. În timpul antrenării, setați aleator la zero ieșirea fiecărui neuron cu probabilitatea p.
ieșire = activare(z) * mască unde mască[i] ~ Bernoulli(1 - p)
Cu p = 0.5, aproximativ jumătate dintre neuroni sunt aduși la zero la fiecare propagare înainte. Rețeaua trebuie să învețe reprezentări redundante, deoarece nu poate prezice ce neuroni vor fi disponibili. Astfel se reduce coadaptarea, adică dependența strictă a unor neuroni de prezența altora.
Interpretarea de ansamblu: o rețea cu N unități supuse dropoutului definește până la 2^N măști și subrețele posibile. Antrenarea cu dropout eșantionează aceste configurații pe mini-loturi diferite. La testare folosiți toate unitățile, fără dropout, iar în convenția clasică scalați ieșirile cu (1 - p) pentru a potrivi valoarea așteptată din timpul antrenării. Aceasta aproximează agregarea mai multor subrețele cu parametri partajați.
Notă tehnică a traducerii: Dropout nu antrenează explicit toate cele
2^Nsubrețele și nu este exact echivalent cu media predicțiilor lor, deoarece parametrii sunt partajați, numai o fracțiune de măști este eșantionată, iar neliniaritățile împiedică în general schimbarea exactă dintre mediere și propagare înainte.
În practică, scalarea este aplicată în timpul antrenării, nu la testare — dropout inversat:
În timpul antrenării: ieșire = activare(z) * mască / (1 - p)
În timpul testării: ieșire = activare(z) (nu este necesară nicio schimbare)
Puncte de pornire întâlnite sunt p = 0.1 pentru unele transformatoare, p = 0.5 pentru unele MLP-uri și p = 0.2–0.3 pentru unele CNN-uri. Un dropout mai mare înseamnă regularizare mai puternică și risc mai mare de subînvățare, dar valorile optime depind de model și date.
Decay-ul ponderilor — regularizare L2
Adăugați la pierdere pătratul magnitudinii tuturor ponderilor:
total_loss = task_loss + (lambda / 2) * sum(w_i^2)
Gradientul termenului de regularizare este lambda * w. La fiecare pas SGD, acest termen micșorează fiecare pondere spre zero cu o cantitate proporțională cu magnitudinea ei. Ponderile mari sunt penalizate mai mult, favorizând soluții cu normă mai mică.
De ce poate ajuta generalizarea: limitarea normei poate reduce sensibilitatea anumitor modele și poate introduce o preferință inductivă pentru soluții mai simple în parametrizarea dată. Aceasta poate împiedica adaptarea excesivă la particularitățile setului de antrenare.
Notă tehnică a traducerii: Nu este adevărat universal că modelele supraînvățate au ponderi mari sau că ponderile mici limitează direct capacitatea. Rețelele cu activări omogene și normalizare admit rescalări ale parametrilor care păstrează funcția. Efectul decay-ului depinde de parametrizare și optimizator.
Hiperparametrul lambda controlează intensitatea. Exemple de puncte de pornire:
0.01pentru AdamW în unele transformatoare.1e-4pentru SGD în unele CNN-uri.0.1în anumite modele puternic supraînvățate, numai după validare.
După cum s-a discutat în lecția 06, decay-ul ponderilor și regularizarea L2 sunt echivalente, cu o rescalare a coeficientului, în SGD standard, dar nu în Adam. Când doriți decay decuplat împreună cu Adam, folosiți AdamW.
Normalizarea pe lot — BatchNorm
Normalizați ieșirea fiecărui strat pe mini-lot, pentru fiecare caracteristică, înainte de a o transmite stratului următor.
Pentru un mini-lot de activări la un anumit strat:
mu = (1/B) * sum(x_i) (media lotului)
sigma^2 = (1/B) * sum((x_i - mu)^2) (varianța lotului)
x_hat = (x_i - mu) / sqrt(sigma^2 + eps) (normalizare)
y = gamma * x_hat + beta (scalare și deplasare)
gamma și beta sunt parametri antrenabili care permit rețelei să ajusteze scara și deplasarea, inclusiv să contracareze normalizarea când aceasta este utilă.
Diferența dintre antrenare și inferență: în timpul antrenării, mu și sigma provin din mini-lotul curent. În timpul inferenței folosiți statistici mobile acumulate la antrenare. În convenția PyTorch, momentum = 0.1 înseamnă 90% din vechea estimare plus 10% din observația nouă.
Mecanismul exact prin care BatchNorm ajută rămâne discutat. Lucrarea originală a motivat metoda prin reducerea „deplasării covariatelor interne” — schimbarea distribuției intrărilor straturilor pe măsură ce straturile anterioare se actualizează. Santurkar și colaboratorii au arătat în 2018 că stabilitatea acestor distribuții explică slab succesul BatchNorm și au propus drept explicație netezirea geometriei optimizării și gradienți mai predictibili.
Notă tehnică a traducerii: Rezultatul lui Santurkar și colaboratorii contestă explicația prin deplasarea covariatelor interne, dar nu închide definitiv dezbaterea și nu demonstrează că „adevăratul motiv” unic este netezirea. BatchNorm modifică parametrizarea, scara gradienților, zgomotul dependent de lot și invariantențele modelului.
BatchNorm depinde de statisticile lotului. La dimensiunea lotului 1, varianța pe lot este degenerată în forma elementară. Cu loturi mici, estimările pot fi zgomotoase și pot afecta performanța, mai ales în detecția obiectelor, unde memoria limitează lotul. Nu există însă un prag universal de 32; metode precum statisticile sincronizate, înghețarea lor sau alte normalizări pot funcționa în regimuri mici.
Normalizarea pe strat — LayerNorm
Normalizați pe caracteristici, nu pe lot. Pentru un singur exemplu:
mu = (1/D) * sum(x_j) (media caracteristicilor)
sigma^2 = (1/D) * sum((x_j - mu)^2) (varianța caracteristicilor)
x_hat = (x_j - mu) / sqrt(sigma^2 + eps)
y = gamma * x_hat + beta
D este dimensiunea caracteristicilor. Fiecare exemplu este normalizat independent, fără dependență de dimensiunea lotului. Acesta este un motiv central pentru folosirea LayerNorm în transformatoare: secvențele pot avea lungimi diferite, loturile se schimbă, iar generarea poate folosi un singur exemplu; calculul normalizării rămâne același la antrenare și inferență.
În transformatoare, LayerNorm poate fi aplicată după fiecare bloc de autoatenție și feed-forward — Post-LN — sau înaintea subnivelurilor — Pre-LN, o configurație care adesea stabilizează antrenarea rețelelor profunde.
RMSNorm
LayerNorm fără scăderea mediei, propusă de Zhang și Sennrich în 2019:
rms = sqrt((1/D) * sum(x_j^2))
y = gamma * x / rms
Aceasta este forma de bază. Nu calculează media și nu are parametrul beta în formularea originală. Ipoteza autorilor este că invarianta la recentrare oferită de scăderea mediei contribuie puțin în sarcinile evaluate, dar are un cost de calcul. Eliminarea ei a păstrat o performanță comparabilă și a redus timpul de rulare în experimentele lucrării.
Notă tehnică a traducerii: Lucrarea RMSNorm raportează reduceri ale timpului între 7% și 64% pentru modelele și implementările evaluate, nu un câștig universal exact de 10%. Acuratețea comparabilă cu LayerNorm este un rezultat empiric, nu o garanție pentru orice arhitectură sau hardware.
LLaMA, LLaMA 2, LLaMA 3 și Mistral sunt exemple de familii care folosesc RMSNorm. La scara miliardelor de parametri și a multor tokenuri, reducerea operațiilor poate deveni importantă, însă nu toate LLM-urile moderne folosesc aceeași normalizare.
Compararea normalizărilor
Augmentarea datelor ca regularizare
Nu este o modificare a modelului, ci a datelor. Transformați intrările de antrenare încercând să păstrați etichetele:
- Imagini: decupare, oglindire și rotire aleatoare, modificarea culorilor, cutout.
- Text: înlocuirea sinonimelor, retrotraducere, ștergere aleatoare.
- Audio: întindere temporală, schimbarea înălțimii sunetului, adăugarea zgomotului.
Efectul este asemănător regularizării: diversifică distribuția de antrenare și îngreunează memorarea formei exacte a fiecărui exemplu. Un model care vede mai multe variante valide ale unei imagini este încurajat să învețe structuri invariante față de transformările aplicate.
Notă tehnică a traducerii: Augmentarea nu mărește automat „dimensiunea efectivă” cu numărul variantelor și nu este identică matematic cu o penalizare. Transformările trebuie să păstreze semantica sarcinii; rotația unei cifre, înlocuirea unui cuvânt sau schimbarea tonalității pot altera eticheta în anumite aplicații.
Oprirea timpurie
Un regularizator procedural simplu: opriți antrenarea când pierderea de validare nu mai scade. În practică, măsurați pierderea pe un set de validare la fiecare epocă, salvați cel mai bun model și continuați pentru o fereastră de răbdare — adesea 5–20 de epoci. Dacă nu apare nicio îmbunătățire în fereastră, opriți și încărcați cea mai bună stare salvată.
Notă tehnică a traducerii: Setul de testare trebuie păstrat pentru evaluarea finală, nu folosit pentru oprire timpurie sau alegerea epocii. Utilizarea repetată a pierderii de testare pentru decizii transformă testul într-un set de validare și produce estimări optimiste.
Ce să aplicați și când
Notă tehnică a traducerii: Pragurile de 5 și 10 puncte și intensitățile recomandate sunt euristici, nu reguli. Un decalaj mic poate ascunde subînvățare, schimbare de distribuție sau scurgere de date, iar o acuratețe agregată poate ascunde probleme pe subgrupuri. Tehnica și intensitatea trebuie alese pe setul de validare și pe metrica sarcinii.
l2-regularization
Construiți
Pasul 1: dropout — modurile antrenare și evaluare
import random
import math
class Dropout:
def __init__(self, p=0.5):
self.p = p
self.training = True
self.mask = None
def forward(self, x):
if not self.training:
return list(x)
self.mask = []
output = []
for val in x:
if random.random() < self.p:
self.mask.append(0)
output.append(0.0)
else:
self.mask.append(1)
output.append(val / (1 - self.p))
return output
def backward(self, grad_output):
grads = []
for g, m in zip(grad_output, self.mask):
if m == 0:
grads.append(0.0)
else:
grads.append(g / (1 - self.p))
return grads
Notă tehnică a traducerii: Clasa nu validează
0 <= p < 1; lap = 1apare împărțirea la zero. De asemenea,backwardpresupune o propagare înainte în modul de antrenare și o mască existentă. O implementare completă trebuie să gestioneze explicit modul de evaluare și starea fiecărei propagări înainte.
Pasul 2: decay L2 al ponderilor
def l2_regularization(weights, lambda_reg):
penalty = 0.0
for w in weights:
penalty += w * w
return lambda_reg * 0.5 * penalty
def l2_gradient(weights, lambda_reg):
return [lambda_reg * w for w in weights]
Pasul 3: normalizarea pe lot
class BatchNorm:
def __init__(self, num_features, momentum=0.1, eps=1e-5):
self.gamma = [1.0] * num_features
self.beta = [0.0] * num_features
self.eps = eps
self.momentum = momentum
self.running_mean = [0.0] * num_features
self.running_var = [1.0] * num_features
self.training = True
self.num_features = num_features
def forward(self, batch):
batch_size = len(batch)
if self.training:
mean = [0.0] * self.num_features
for sample in batch:
for j in range(self.num_features):
mean[j] += sample[j]
mean = [m / batch_size for m in mean]
var = [0.0] * self.num_features
for sample in batch:
for j in range(self.num_features):
var[j] += (sample[j] - mean[j]) ** 2
var = [v / batch_size for v in var]
for j in range(self.num_features):
self.running_mean[j] = (1 - self.momentum) * self.running_mean[j] + self.momentum * mean[j]
self.running_var[j] = (1 - self.momentum) * self.running_var[j] + self.momentum * var[j]
else:
mean = list(self.running_mean)
var = list(self.running_var)
self.x_hat = []
output = []
for sample in batch:
normalized = []
out_sample = []
for j in range(self.num_features):
x_h = (sample[j] - mean[j]) / math.sqrt(var[j] + self.eps)
normalized.append(x_h)
out_sample.append(self.gamma[j] * x_h + self.beta[j])
self.x_hat.append(normalized)
output.append(out_sample)
return output
Notă tehnică a traducerii: Această clasă implementează numai propagarea înainte. Nu calculează gradienții pentru intrări,
gammasaubeta, deci parametrii declarați antrenabili nu pot fi învățați cu codul prezentat. În plus, PyTorch folosește varianța biased pentru normalizarea lotului curent, dar actualizeazărunning_varcu estimatorul unbiased; codul folosește aceeași varianță biased în ambele locuri.
Pasul 4: normalizarea pe strat
class LayerNorm:
def __init__(self, num_features, eps=1e-5):
self.gamma = [1.0] * num_features
self.beta = [0.0] * num_features
self.eps = eps
self.num_features = num_features
def forward(self, x):
mean = sum(x) / len(x)
var = sum((xi - mean) ** 2 for xi in x) / len(x)
self.x_hat = []
output = []
for j in range(self.num_features):
x_h = (x[j] - mean) / math.sqrt(var + self.eps)
self.x_hat.append(x_h)
output.append(self.gamma[j] * x_h + self.beta[j])
return output
Pasul 5: RMSNorm
class RMSNorm:
def __init__(self, num_features, eps=1e-6):
self.gamma = [1.0] * num_features
self.eps = eps
self.num_features = num_features
def forward(self, x):
rms = math.sqrt(sum(xi * xi for xi in x) / len(x) + self.eps)
output = []
for j in range(self.num_features):
output.append(self.gamma[j] * x[j] / rms)
return output
Notă tehnică a traducerii: La fel ca BatchNorm, clasele
LayerNormșiRMSNormimplementează numaiforward; lipsesc propagarea înapoi și actualizarea parametrilorgammașibeta. Ele ilustrează formulele, dar nu constituie straturi antrenabile complete.
Pasul 6: antrenarea cu și fără regularizare
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 RegularizedNetwork:
def __init__(self, hidden_size=16, lr=0.05, dropout_p=0.0, weight_decay=0.0):
random.seed(0)
self.hidden_size = hidden_size
self.lr = lr
self.dropout_p = dropout_p
self.weight_decay = weight_decay
self.dropout = Dropout(p=dropout_p) if dropout_p > 0 else None
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 forward(self, x, training=True):
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))
if self.dropout and training:
self.dropout.training = True
self.h = self.dropout.forward(self.h)
elif self.dropout:
self.dropout.training = False
self.h = self.dropout.forward(self.h)
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 backward(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
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
self.w2[i] -= self.lr * (d_out * self.h[i] + self.weight_decay * self.w2[i])
for j in range(2):
self.w1[i][j] -= self.lr * (d_h * self.x[j] + self.weight_decay * self.w1[i][j])
self.b1[i] -= self.lr * d_h
self.b2 -= self.lr * d_out
def evaluate(self, data):
correct = 0
total_loss = 0.0
for x, y in data:
pred = self.forward(x, training=False)
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
return total_loss / len(data), correct / len(data) * 100
def train_model(self, train_data, test_data, epochs=300):
history = []
for epoch in range(epochs):
total_loss = 0.0
correct = 0
for x, y in train_data:
pred = self.forward(x, training=True)
self.backward(y)
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
train_loss = total_loss / len(train_data)
train_acc = correct / len(train_data) * 100
test_loss, test_acc = self.evaluate(test_data)
history.append((train_loss, train_acc, test_loss, test_acc))
if epoch % 75 == 0 or epoch == epochs - 1:
gap = train_acc - test_acc
print(f" Epoch {epoch:3d}: train_acc={train_acc:.1f}%, test_acc={test_acc:.1f}%, gap={gap:.1f}%")
return history
Notă tehnică a traducerii: Propagarea înainte aplică masca dropout ieșirilor ascunse, dar
backwardnu apeleazăself.dropout.backward. Prin urmare, primul strat primește gradienți și pentru unitățile mascate și nu primește scalarea inversă corectă; experimentul nu implementează corect retropropagarea prin dropout. În plus, parametrul numittest_dataeste evaluat la fiecare epocă și trebuie tratat ca validare, păstrând un test separat pentru raportarea finală.
Folosiți
PyTorch oferă normalizările și regularizările sub formă de module:
import torch
import torch.nn as nn
model = nn.Sequential(
nn.Linear(784, 256),
nn.BatchNorm1d(256),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(256, 128),
nn.BatchNorm1d(128),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(128, 10),
)
model.train()
out_train = model(torch.randn(32, 784))
model.eval()
out_test = model(torch.randn(1, 784))
Comutarea model.train() / model.eval() este esențială. Ea activează sau dezactivează dropout și îi spune BatchNorm să folosească statisticile lotului ori statisticile mobile. Dacă uitați model.eval() înaintea inferenței, rezultatele pot fluctua deoarece dropout rămâne activ, iar BatchNorm continuă să folosească și să actualizeze statisticile mini-lotului.
Pentru transformatoare, tiparul este diferit:
class TransformerBlock(nn.Module):
def __init__(self, d_model=512, nhead=8, dropout=0.1):
super().__init__()
self.attention = nn.MultiheadAttention(d_model, nhead, dropout=dropout)
self.norm1 = nn.LayerNorm(d_model)
self.ff = nn.Sequential(
nn.Linear(d_model, d_model * 4),
nn.GELU(),
nn.Linear(d_model * 4, d_model),
nn.Dropout(dropout),
)
self.norm2 = nn.LayerNorm(d_model)
self.dropout = nn.Dropout(dropout)
def forward(self, x):
attended, _ = self.attention(x, x, x)
x = self.norm1(x + self.dropout(attended))
x = self.norm2(x + self.ff(x))
return x
LayerNorm, nu BatchNorm. Dropout p=0.1, nu p=0.5, este un punct de pornire comun pentru configurația prezentată. Valorile nu sunt însă implicite universale: arhitecturile moderne pot folosi RMSNorm, Pre-LN și dropout zero sau alte rate.
Livrați
Această lecție produce:
outputs/prompt-regularization-advisor.md— un prompt care diagnostichează supraînvățarea și recomandă o strategie de regularizare.
Exerciții
-
Implementați dropout spațial pentru date bidimensionale: în loc să eliminați neuroni individuali, eliminați canale întregi de caracteristici. Simulați-l tratând grupuri consecutive de caracteristici drept canale și eliminând grupuri complete. Comparați decalajul antrenare–testare cu dropout standard pe setul circular cu
hidden_size=32. -
Combinați netezirea etichetelor din lecția 05 cu dropout din această lecție. Antrenați patru configurații: niciuna, numai dropout, numai netezirea etichetelor și ambele. Măsurați decalajul final de acuratețe dintre antrenare și validare pentru fiecare. Ce combinație produce cel mai mic decalaj fără să reducă excesiv performanța de validare?
-
Adăugați un strat BatchNorm între stratul ascuns și activare în rețeaua pentru setul circular. Antrenați cu și fără BatchNorm la ratele 0,01, 0,05 și 0,1. Verificați experimental dacă BatchNorm permite antrenare stabilă la rate mai mari; rezultatul nu este garantat pentru orice seed sau implementare.
-
Implementați oprirea timpurie: urmăriți pierderea de validare la fiecare epocă, salvați cele mai bune ponderi și opriți dacă aceasta nu s-a îmbunătățit timp de 20 de epoci. Rulați rețeaua regularizată cel mult 1000 de epoci. Raportați epoca aleasă pe validare, apoi evaluați o singură dată acuratețea pe un set de testare separat și calculați câte epoci ați economisit.
-
Comparați LayerNorm cu RMSNorm într-o rețea cu patru straturi, nu doar două. Inițializați ambele cu aceleași ponderi. Antrenați 200 de epoci și comparați acuratețea finală, viteza — timpul pe epocă — și amplitudinea gradienților din primul strat. Verificați dacă RMSNorm este mai rapidă și păstrează acuratețea în această configurație, fără a presupune rezultatul.
Termeni-cheie
| Termen | Ce spun oamenii | Ce înseamnă de fapt |
|---|---|---|
| Supraînvățare | „Modelul a memorat datele” | Performanța de antrenare depășește substanțial performanța pe date independente, ceea ce poate indica adaptarea la zgomot sau particularități nereprezentative |
| Regularizare | „Prevenirea supraînvățării” | Tehnici care introduc preferințe, zgomot, constrângeri sau criterii de oprire pentru a îmbunătăți generalizarea |
| Dropout | „Ștergerea aleatoare a neuronilor” | Aducerea aleatoare la zero a unor activări în timpul antrenării cu probabilitatea p, folosind de obicei scalare inversă |
| Decay al ponderilor | „Penalizare L2” | Micșorarea parametrilor proporțional cu valoarea lor; este echivalentă cu L2 numai în anumite condiții ale optimizatorului |
| Normalizare pe lot | „Normalizare pe mini-lot” | Normalizarea caracteristicilor folosind statisticile lotului la antrenare și statistici mobile la inferență |
| Normalizare pe strat | „Normalizare pe exemplu” | Normalizarea pe caracteristici în interiorul fiecărui exemplu, independent de lot, folosită frecvent în transformatoare |
| RMSNorm | „LayerNorm fără medie” | Normalizare prin rădăcina mediei pătratelor, care omite scăderea mediei și poate reduce costul de calcul |
| Oprire timpurie | „Opriți înaintea supraînvățării” | Oprirea antrenării când metrica de validare nu se mai îmbunătățește, cu restaurarea celei mai bune stări |
| Augmentarea datelor | „Mai multe date din mai puține” | Eșantionarea unor transformări ale intrărilor care ar trebui să păstreze eticheta și să inducă invariantențe utile |
| Decalaj de generalizare | „Diferența antrenare–testare” | Diferența dintre performanța pe datele de antrenare și pe date independente; interpretarea depinde de metrică și distribuție |
Lecturi suplimentare
- Srivastava și colaboratorii, „Dropout: A Simple Way to Prevent Neural Networks from Overfitting” (2014) — lucrarea originală despre dropout, interpretarea de ansamblu și experimente extinse.
- Ioffe și Szegedy, „Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift” (2015) — a introdus BatchNorm și procedura sa de antrenare.
- Zhang și Sennrich, „Root Mean Square Layer Normalization” (2019) — a arătat o performanță comparabilă cu LayerNorm și cost redus în experimente; RMSNorm a fost adoptată ulterior de LLaMA și Mistral.
- Zhang și colaboratorii, „Understanding Deep Learning Requires Rethinking Generalization” (2017) — lucrarea reper care arată că rețelele neurale pot potrivi etichete aleatoare și contestă explicațiile tradiționale ale generalizării.
Sursă: Originalul în limba engleză
Navigare: ← Lecția 03.06 — Optimizatori · Faza 3 — Fundamentele învățării profunde · Catalog complet · Lecția 03.08 — Inițializarea ponderilor și stabilitatea antrenării →