Faza 03 · lecția 05

Funcții de pierdere

Scopul lecției: Rețeaua dumneavoastră face o predicție, iar adevărul de referință spune altceva. Cât de greșită este predicția? Numărul care răspunde este pierderea. Alegeți o funcție de pierdere nepotrivită, iar modelul va optimiza cu totul altceva…

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ă
24 min.
Verificat
Cuprinsul lecției
  1. Obiective de învățare
  2. Problema
  3. Conceptul
  4. Eroarea pătratică medie — MSE
  5. Pierderea prin entropie încrucișată
  6. De ce MSE poate fi nepotrivită pentru clasificare
  7. Netezirea etichetelor
  8. Pierderea contrastivă
  9. Focal loss
  10. Arbore decizional pentru funcția de pierdere
  11. Peisajul pierderii
  12. Construiți
  13. Pasul 1: MSE și gradientul ei
  14. Pasul 2: entropia încrucișată binară
  15. Pasul 3: entropie încrucișată categorială cu softmax
  16. Pasul 4: netezirea etichetelor
  17. Pasul 5: pierdere contrastivă — InfoNCE simplificată
  18. Pasul 6: MSE față de entropia încrucișată în clasificare
  19. Folosiți
  20. Livrați
  21. Exerciții
  22. Termeni-cheie
  23. Lecturi suplimentare

Rețeaua dumneavoastră face o predicție, iar adevărul de referință spune altceva. Cât de greșită este predicția? Numărul care răspunde este pierderea. Alegeți o funcție de pierdere nepotrivită, iar modelul va optimiza cu totul altceva decât intenționați.

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

Obiective de învățare

  • Să implementați de la zero MSE, entropia încrucișată binară, entropia încrucișată categorială și pierderea contrastivă InfoNCE; să derivați gradienții pentru pierderile de clasificare și să identificați gradientul lipsă al implementării InfoNCE.
  • Să explicați limitele MSE în clasificare prin demonstrarea modului de eșec „preziceți 0,5 pentru orice”.
  • Să aplicați netezirea etichetelor entropiei încrucișate și să descrieți cum poate reduce predicțiile excesiv de încrezătoare.
  • Să alegeți funcția de pierdere potrivită pentru regresie, clasificare binară, clasificare cu mai multe clase și învățarea embeddingurilor.

Problema

Un model care minimizează MSE într-o problemă de clasificare poate ajunge să prezică 0,5 pentru orice. Minimizează pierderea pentru un predictor constant pe clase echilibrate, dar rămâne inutil ca discriminator.

Funcția de pierdere este semnalul principal pe care îl optimizează modelul. Nu acuratețea, nu scorul F1 și nici metrica raportată managerului, dacă acestea nu sunt incluse în obiectiv. Optimizatorul folosește gradientul obiectivului și ajustează ponderile pentru a-i micșora valoarea. Dacă funcția de pierdere nu surprinde ceea ce vă interesează, modelul poate găsi o cale matematic ieftină de a o satisface, fără să obțină comportamentul dorit.

Iată un exemplu concret. Aveți o sarcină de clasificare binară, cu două clase împărțite 50/50. Folosiți MSE ca pierdere și limitați modelul la aceeași predicție pentru toate intrările. Predicția 0,5 produce o MSE medie de 0,25, minimul posibil pentru acel predictor constant. Modelul nu are nicio capacitate de discriminare, deși și-a minimizat pierderea în familia restrânsă. Cu entropia încrucișată, predicțiile corecte și încrezătoare primesc pierderi mai mici: -log(0.5) = 0.693, iar -log(0.99) = 0.01. Alegerea funcției de pierdere poate face diferența dintre un model care învață semnalul relevant și unul care exploatează o nepotrivire a obiectivului.

Notă tehnică a traducerii: Afirmația originală că un model de clasificare antrenat cu MSE „va prezice” 0,5 este falsă în general. Valoarea 0,5 este optimă numai pentru un predictor constant pe etichete binare echilibrate sau, condiționat de intrare, acolo unde probabilitatea clasei este 0,5. Dacă intrările conțin semnal, MSE poate învăța clasificarea; entropia încrucișată are însă de regulă gradienți și o geometrie mai potrivite când este combinată cu logiți.

Situația devine și mai delicată în învățarea autosupravegheată, unde nu există etichete explicite. Pierderea contrastivă definește întregul semnal de învățare: ce este similar, ce este diferit și cât de puternic trebuie separate reprezentările. O funcție contrastivă formulată greșit poate permite colapsul embeddingurilor într-un singur punct, astfel încât fiecare intrare să fie mapată la același vector.

Notă tehnică a traducerii: Pentru InfoNCE standard cu un exemplu pozitiv și K exemple negative incluse în numitor, embeddingurile identice produc probabilitatea 1/(K+1) și pierderea log(K+1), nu pierdere zero. Colapsul cu pierdere zero poate apărea la alte obiective insuficient constrânse, dar nu descrie formula InfoNCE corectă.

Conceptul

Eroarea pătratică medie — MSE

Opțiunea clasică pentru regresie. Calculați pătratul diferenței dintre predicție și țintă, apoi media pe toate exemplele.

MSE = (1/n) * sum((y_pred - y_true)^2)

De ce contează ridicarea la pătrat: erorile mari sunt penalizate pătratic. O eroare de 2 costă de patru ori mai mult decât una de 1. O eroare de 10 costă de 100 de ori mai mult. Această proprietate face MSE sensibilă la valori aberante: o singură predicție foarte greșită poate domina pierderea.

Un exemplu numeric: modelul estimează prețuri de locuințe și greșește cu 10.000 USD pentru majoritatea caselor, dar cu 200.000 USD pentru un conac. MSE va încerca agresiv să corecteze eroarea conacului, afectând posibil performanța pentru celelalte 99 de case.

Gradientul MSE față de o predicție este:

dMSE/dy_pred = (2/n) * (y_pred - y_true)

Este liniar în eroare. Erorile mai mari produc gradienți mai mari. Aceasta poate fi o proprietate utilă în regresie — erorile mari primesc corecții mari —, dar pentru clasificare entropia încrucișată oferă adesea un semnal mai potrivit predicțiilor probabilistice.

Notă tehnică a traducerii: Entropia încrucișată nu penalizează erorile „exponențial”, așa cum afirmă originalul; dependența ei față de probabilitatea clasei corecte este logaritmică și devine nelimitată când acea probabilitate tinde spre zero.

Pierderea prin entropie încrucișată

Funcție de pierdere uzuală pentru clasificare. Provine din teoria informației și măsoară entropia încrucișată dintre distribuția adevărată și distribuția prezisă.

Notă tehnică a traducerii: Entropia încrucișată nu este ea însăși o divergență: H(P,Q) = H(P) + KL(P||Q). Atunci când distribuția-țintă P este fixă, minimizarea entropiei încrucișate este echivalentă cu minimizarea divergenței KL.

Entropie încrucișată binară — BCE:

BCE = -(y * log(p) + (1 - y) * log(1 - p))

y este eticheta adevărată — 0 sau 1 —, iar p este probabilitatea prezisă.

De ce funcționează -log(p): când eticheta adevărată este 1 și preziceți p = 0.99, pierderea este -log(0.99) = 0.01. Când preziceți p = 0.01, pierderea este -log(0.01) = 4.6. Diferența de aproximativ 460 de ori explică semnalul puternic al entropiei încrucișate. Ea penalizează sever predicțiile greșite și încrezătoare, dar foarte puțin predicțiile corecte și încrezătoare.

Gradientul față de probabilitate spune aceeași poveste:

dBCE/dp = -(y/p) + (1-y)/(1-p)

Când y = 1, iar p este aproape de zero, gradientul -1/p tinde spre infinit negativ. Modelul primește un semnal mare față de probabilitate pentru a corecta greșeala. Când p este aproape de 1, gradientul față de probabilitate tinde spre -1, nu spre zero; gradientul față de logit al combinației sigmoidă–BCE, p - y, este cel care tinde spre zero pentru o predicție corectă și încrezătoare.

Entropie încrucișată categorială:

Pentru clasificarea cu mai multe clase și ținte codificate one-hot:

CCE = -sum(y_i * log(p_i))

Numai clasa adevărată contribuie la pierdere, deoarece toate celelalte valori y_i sunt zero. Dacă există 10 clase și clasa corectă primește probabilitatea 0,1 — ghicire aleatoare uniformă —, pierderea este -log(0.1) = 2.3. Dacă primește probabilitatea 0,9, pierderea este -log(0.9) = 0.105. Modelul învață să concentreze masa de probabilitate asupra răspunsului corect.

De ce MSE poate fi nepotrivită pentru clasificare

Диаграмма к уроку «Funcții de pierdere»

Gradienții MSE se pot aplatiza când probabilitățile sunt aproape de 0 sau 1 din cauza saturării sigmoidei. Entropia încrucișată compensează acest efect: în derivarea compusă, termenul logaritmic anulează factorul mic al derivatei sigmoidei și furnizează gradienți utili față de logit acolo unde sunt necesari.

Notă tehnică a traducerii: dBCE/dp devine nelimitat lângă o predicție greșită extremă, dar pentru BCE combinată cu sigmoida gradientul față de logit se simplifică la p - y, care este mărginit între -1 și 1. Așadar, diagrama descrie derivata față de probabilitate; nu trebuie interpretată ca o explozie a gradientului față de logit.

Netezirea etichetelor

Etichetele one-hot standard spun: „acesta este 100% clasa 3 și 0% orice altceva”. Este o afirmație puternică. Netezirea etichetelor o atenuează:

smooth_label = (1 - alpha) * one_hot + alpha / num_classes

Cu alpha = 0.1 și 10 clase, în loc de [0, 0, 1, 0, ...], ținta devine [0.01, 0.01, 0.91, 0.01, ...]. Modelul urmărește 0,91 în loc de 1,0.

De ce poate funcționa: pentru a produce exact 1,0 prin softmax în aritmetică reală, diferențele dintre logiți trebuie să tindă spre infinit. Acest comportament favorizează încrederea excesivă, poate afecta generalizarea și poate face modelul mai fragil la schimbarea distribuției. În convenția formulei de mai sus, netezirea cu alpha = 0.1 și 10 clase fixează ținta clasei corecte la 0,91 și menține logiții într-un interval mai moderat.

Notă tehnică a traducerii: Originalul trece de la ținta corect calculată 0,91 la afirmația că aceasta este plafonată la 0,9. Valoarea este 0,91 pentru formula prezentată; 0,9 apare într-o altă convenție, care distribuie masa alpha numai între clasele incorecte. Afirmația că GPT și „majoritatea modelelor moderne” folosesc netezirea etichetelor nu este universal valabilă și depinde de model și rețeta de antrenare.

Pierderea contrastivă

Fără etichete de clasă explicite. Doar perechi de intrări și întrebarea: sunt similare sau diferite?

Pierdere contrastivă în stil SimCLR — NT-Xent / InfoNCE:

Luați o imagine și creați două vederi augmentate — decupare, rotire și modificarea culorilor. Acestea alcătuiesc „perechea pozitivă” și ar trebui să aibă embeddinguri similare. Vederile provenite din celelalte imagini ale lotului formează perechi negative și ar trebui să fie mai puțin similare.

L = -log(exp(sim(z_i, z_j) / tau) / sum(exp(sim(z_i, z_k) / tau)))

sim() este similitudinea cosinus, z_i și z_j sunt perechea pozitivă, iar tau, temperatura, controlează cât de ascuțită este distribuția. O temperatură mai mică accentuează diferențele dintre similitudini și concentrează mai mult pierderea asupra negativelor foarte similare.

Notă tehnică a traducerii: Numitorul InfoNCE trebuie să includă termenul pozitiv și termenii negativi, excluzând doar comparația ancorei cu ea însăși. Descrierea originală spune că suma este numai peste negative, ceea ce ar permite un raport mai mare decât 1. Funcția din secțiunea „Construiți” include corect pozitivul. În SimCLR, un lot cu N imagini produce 2N vederi și, pentru fiecare ancoră, o vedere pozitivă și 2N-2 negative; nu sunt pur și simplu 255 de negative pentru orice lot de 256. Lucrarea SimCLR folosește în configurația principală tau = 0.5, nu 0,07.

Pierderea triplet:

Primește trei intrări: ancora, exemplul pozitiv — aceeași clasă — și exemplul negativ — altă clasă.

L = max(0, d(anchor, positive) - d(anchor, negative) + margin)

Marja, adesea aleasă în funcție de sarcină, impune un decalaj minim între distanțele pozitivă și negativă. Dacă exemplul negativ este deja suficient de departe, pierderea este zero — nu există gradient și nici actualizare. Antrenarea poate deveni eficientă, dar necesită selectarea atentă a tripletelor, inclusiv alegerea negativelor dificile aflate aproape de ancoră.

Focal loss

Pentru seturi de date dezechilibrate și numeroase exemple ușoare. Entropia încrucișată standard atribuie în continuare pierdere exemplelor deja bine clasificate. Focal loss reduce ponderea exemplelor ușoare:

FL = -alpha * (1 - p_t)^gamma * log(p_t)

p_t este probabilitatea prezisă a clasei adevărate, iar gamma controlează focalizarea. Cu gamma = 0, obțineți entropia încrucișată ponderată prin alpha. Cu gamma = 2, o alegere evaluată în lucrarea originală:

  • Exemplu ușor, p_t = 0.9: ponderea este (0.1)^2 = 0.01. Contribuția este redusă puternic.
  • Exemplu dificil, p_t = 0.1: ponderea este (0.9)^2 = 0.81. Cea mai mare parte a semnalului se păstrează.

Focal loss a fost introdusă de Lin și colaboratorii pentru detecția obiectelor, unde numărul mare de locații de fundal ușor de clasificat copleșea exemplele de prim-plan. Fără focal loss, modelul putea fi dominat de negativele ușoare; cu aceasta, optimizarea se concentrează asupra cazurilor dificile și ambigue.

Notă tehnică a traducerii: gamma = 2 este o alegere experimentală populară, nu o valoare implicită universală. Focal loss nu este automat cea mai bună soluție pentru orice dezechilibru; ponderarea claselor, reeșantionarea și pragurile de decizie sunt alternative ce trebuie evaluate pe metrica relevantă.

Arbore decizional pentru funcția de pierdere

Диаграмма к уроку «Funcții de pierdere»

Peisajul pierderii

Диаграмма к уроку «Funcții de pierdere»

Notă tehnică a traducerii: MSE este o parabolă convexă cu un singur minim față de predicția scalară. Compusă însă cu o rețea neurală, suprafața față de parametri este în general neconvexă și nu devine automat „ușor de optimizat”. Același lucru este valabil pentru celelalte descrieri din diagramă: forma în spațiul parametrilor depinde de model și date.

cross-entropy-loss

Construiți

Pasul 1: MSE și gradientul ei

def mse(predictions, targets):
    n = len(predictions)
    total = 0.0
    for p, t in zip(predictions, targets):
        total += (p - t) ** 2
    return total / n

def mse_gradient(predictions, targets):
    n = len(predictions)
    grads = []
    for p, t in zip(predictions, targets):
        grads.append(2.0 * (p - t) / n)
    return grads

Pasul 2: entropia încrucișată binară

Problema lui log(0) este reală. Dacă modelul prezice exact 0 pentru un exemplu pozitiv, log(0) este infinit negativ. Limitarea valorii previne această situație.

import math

def binary_cross_entropy(predictions, targets, eps=1e-15):
    n = len(predictions)
    total = 0.0
    for p, t in zip(predictions, targets):
        p_clipped = max(eps, min(1 - eps, p))
        total += -(t * math.log(p_clipped) + (1 - t) * math.log(1 - p_clipped))
    return total / n

def bce_gradient(predictions, targets, eps=1e-15):
    grads = []
    for p, t in zip(predictions, targets):
        p_clipped = max(eps, min(1 - eps, p))
        grads.append(-(t / p_clipped) + (1 - t) / (1 - p_clipped))
    return grads

Notă tehnică a traducerii: binary_cross_entropy întoarce media pe n exemple, dar bce_gradient întoarce derivatele pierderilor individuale și omite factorul 1/n. Pentru gradientul pierderii medii, fiecare valoare trebuie împărțită la n. În plus, derivata matematică a operației de limitare este zero în afara intervalului, pe când funcția afișată evaluează formula BCE la probabilitatea limitată; blocul este păstrat exact ca în sursă.

Pasul 3: entropie încrucișată categorială cu softmax

Softmax transformă logiții bruți în probabilități. Apoi calculăm entropia încrucișată față de ținta one-hot.

def softmax(logits):
    max_val = max(logits)
    exps = [math.exp(x - max_val) for x in logits]
    total = sum(exps)
    return [e / total for e in exps]

def categorical_cross_entropy(logits, target_index, eps=1e-15):
    probs = softmax(logits)
    p = max(eps, probs[target_index])
    return -math.log(p)

def cce_gradient(logits, target_index):
    probs = softmax(logits)
    grads = list(probs)
    grads[target_index] -= 1.0
    return grads

Gradientul combinației softmax și entropie încrucișată se simplifică elegant: este probabilitatea prezisă minus 1 pentru clasa adevărată și probabilitatea prezisă pentru toate celelalte clase. Simplificarea nu este o coincidență; acesta este unul dintre motivele pentru care softmax și entropia încrucișată sunt folosite împreună.

Notă tehnică a traducerii: cce_gradient este gradientul entropiei încrucișate softmax ne-limitate. categorical_cross_entropy limitează însă probabilitatea clasei adevărate la eps; sub acel prag, pierderea implementată este local constantă, iar gradientul afișat nu mai este derivata ei exactă. În implementările de producție, utilizați o formulare stabilă direct pe logiți.

Pasul 4: netezirea etichetelor

def label_smoothed_cce(logits, target_index, num_classes, alpha=0.1, eps=1e-15):
    probs = softmax(logits)
    loss = 0.0
    for i in range(num_classes):
        if i == target_index:
            smooth_target = 1.0 - alpha + alpha / num_classes
        else:
            smooth_target = alpha / num_classes
        p = max(eps, probs[i])
        loss += -smooth_target * math.log(p)
    return loss

Pasul 5: pierdere contrastivă — InfoNCE simplificată

def cosine_similarity(a, b):
    dot = sum(x * y for x, y in zip(a, b))
    norm_a = math.sqrt(sum(x * x for x in a))
    norm_b = math.sqrt(sum(x * x for x in b))
    if norm_a < 1e-10 or norm_b < 1e-10:
        return 0.0
    return dot / (norm_a * norm_b)

def contrastive_loss(anchor, positive, negatives, temperature=0.07):
    sim_pos = cosine_similarity(anchor, positive) / temperature
    sim_negs = [cosine_similarity(anchor, neg) / temperature for neg in negatives]

    max_sim = max(sim_pos, max(sim_negs)) if sim_negs else sim_pos
    exp_pos = math.exp(sim_pos - max_sim)
    exp_negs = [math.exp(s - max_sim) for s in sim_negs]
    total_exp = exp_pos + sum(exp_negs)

    return -math.log(max(1e-15, exp_pos / total_exp))

Notă tehnică a traducerii: Funcția calculează numai valoarea InfoNCE; nu implementează gradientul prin similaritatea cosinus, normalizare și log-sum-exp. Pentru antrenare, folosiți autodiferențierea sau derivați explicit toate aceste componente.

Pasul 6: MSE față de entropia încrucișată în clasificare

Antrenați aceeași rețea din lecția 04 — pe setul de date circular — cu ambele funcții de pierdere. Observați dacă entropia încrucișată converge mai repede în această configurație.

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 LossComparisonNetwork:
    def __init__(self, loss_type="bce", hidden_size=8, lr=0.1):
        random.seed(0)
        self.loss_type = loss_type
        self.lr = lr
        self.hidden_size = hidden_size

        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):
        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 backward(self, target):
        if self.loss_type == "mse":
            d_loss = 2.0 * (self.out - target)
        else:
            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]
            for j in range(2):
                self.w1[i][j] -= self.lr * d_h * self.x[j]
            self.b1[i] -= self.lr * d_h
        self.b2 -= self.lr * d_out

    def compute_loss(self, pred, target):
        if self.loss_type == "mse":
            return (pred - target) ** 2
        else:
            eps = 1e-15
            p = max(eps, min(1 - eps, pred))
            return -(target * math.log(p) + (1 - target) * math.log(1 - p))

    def train(self, data, epochs=200):
        losses = []
        for epoch in range(epochs):
            total_loss = 0.0
            correct = 0
            for x, y in data:
                pred = self.forward(x)
                self.backward(y)
                total_loss += self.compute_loss(pred, y)
                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 % 50 == 0 or epoch == epochs - 1:
                print(f"    Epoch {epoch:3d}: loss={avg_loss:.4f}, accuracy={accuracy:.1f}%")
        return losses

Notă tehnică a traducerii: Convergența mai rapidă a entropiei încrucișate nu este garantată pentru orice inițializare și rată de învățare. Limitările din sigmoid și din BCE modifică funcția, dar backward-ul nu aplică derivata acelor limitări; pentru predicții saturate și greșite, acest lucru poate produce un gradient foarte mic sau zero în locul gradientului stabil p - y al BCE combinate cu logitul. În plus, scriptul raportează pe datele de antrenare predicții generate de stări succesive ale modelului, deoarece actualizează ponderile după fiecare exemplu. O comparație robustă cere evaluarea după epocă a unui model fix, pe un set separat și pe mai multe seeduri.

Folosiți

PyTorch oferă toate funcțiile de pierdere standard cu mecanisme integrate de stabilitate numerică:

import torch
import torch.nn as nn
import torch.nn.functional as F

predictions = torch.tensor([0.9, 0.1, 0.7], requires_grad=True)
targets = torch.tensor([1.0, 0.0, 1.0])

mse_loss = F.mse_loss(predictions, targets)
bce_loss = F.binary_cross_entropy(predictions, targets)

logits = torch.randn(4, 10)
labels = torch.tensor([3, 7, 1, 9])
ce_loss = F.cross_entropy(logits, labels)
ce_smooth = F.cross_entropy(logits, labels, label_smoothing=0.1)

Folosiți F.cross_entropy direct pe logiți, nu aplicați mai întâi softmax și apoi logaritmul. Funcția combină log_softmax cu pierderea de verosimilitate logaritmică negativă într-o operație stabilă numeric și evită overflow-ul, underflow-ul și pierderea de precizie asociate materializării premature a probabilităților.

Notă tehnică a traducerii: F.log_softmax urmat de F.nll_loss este stabil numeric și echivalent cu F.cross_entropy, conform documentației PyTorch. Problema apare când se calculează separat softmax și apoi log; formularea originală confundă această variantă instabilă cu perechea corectă log_softmax + nll_loss. Pentru clasificarea binară pe logiți, BCEWithLogitsLoss combină în mod similar sigmoida și BCE printr-o formulare stabilă.

Pentru învățarea contrastivă, multe echipe folosesc implementări proprii sau biblioteci precum lightly ori pytorch-metric-learning. Bucla comună multor obiective calculează similitudini, construiește o normalizare peste pozitive și negative și retropropagă, însă detaliile diferă între InfoNCE, pierderi cu margine și obiective fără negative.

Livrați

Această lecție produce:

  • outputs/prompt-loss-function-selector.md — un prompt reutilizabil pentru alegerea funcției de pierdere potrivite.
  • outputs/prompt-loss-debugger.md — un prompt de diagnosticare pentru situațiile în care curba pierderii arată greșit.

Exerciții

  1. Implementați pierderea Huber — smooth L1 —, care se comportă ca MSE pentru erori mici și ca MAE pentru erori mari. Antrenați o rețea de regresie care prezice y = sin(x) folosind MSE și Huber, după ce adăugați zgomot aleator la 5% dintre țintele de antrenare. Comparați eroarea finală pe setul de testare.

  2. Adăugați focal loss în bucla de antrenare a clasificării binare. Creați un set dezechilibrat — 90% clasa 0 și 10% clasa 1. Comparați BCE standard cu focal loss având gamma=2, pe baza recall-ului clasei minoritare după 200 de epoci.

  3. Implementați pierderea triplet cu selecția negativelor semi-dificile. Generați embeddinguri bidimensionale pentru cinci clase. Pentru fiecare ancoră, găsiți un negativ care satisface d(a, p) < d(a, n) < d(a, p) + margin; dacă este dincolo de marjă, poate avea pierdere triplet zero. Comparați convergența cu alegerea aleatoare a tripletelor.

  4. Rulați comparația dintre MSE și entropia încrucișată, dar urmăriți amplitudinea gradienților din fiecare strat în timpul antrenării. Reprezentați norma medie a gradientului pe epocă. Verificați experimental dacă entropia încrucișată produce gradienți mai mari în epocile timpurii, când modelul este cel mai nesigur.

  5. Implementați pierderea prin divergență KL și verificați dacă minimizarea KL(true || predicted) produce aceiași gradienți față de predicții ca entropia încrucișată atunci când distribuția adevărată este one-hot. Încercați apoi ținte moi — precum în distilarea cunoașterii — în care distribuția „adevărată” provine din ieșirea softmax a unui model profesor.

Notă tehnică a traducerii: Pentru orice distribuție-țintă fixă, nu numai pentru una one-hot, KL(P||Q) și entropia încrucișată H(P,Q) diferă prin constanta H(P) și au aceiași gradienți față de parametrii lui Q. Temperatura și scalarea pot introduce însă factori suplimentari în distilare.

Termeni-cheie

Termen Ce spun oamenii Ce înseamnă de fapt
Funcție de pierdere „Cât de greșit este modelul” Funcție, de obicei diferențiabilă sau subdiferențiabilă, care mapează predicțiile și țintele la un scalar minimizat de optimizator
MSE „Eroarea pătratică medie” Media pătratelor diferențelor dintre predicții și ținte; penalizează pătratic erorile mari
Entropie încrucișată „Pierderea pentru clasificare” Măsoară entropia încrucișată dintre distribuția prezisă și cea adevărată folosind -log(p); pentru ținte fixe, minimizarea ei echivalează cu minimizarea KL
Entropie încrucișată binară „BCE” Entropia încrucișată pentru o variabilă binară: -(y*log(p) + (1-y)*log(1-p))
Netezirea etichetelor „Atenuarea țintelor” Înlocuirea țintelor ferme 0/1 cu valori mai puțin extreme pentru a regulariza încrederea modelului
Pierdere contrastivă „Apropiați, îndepărtați” Pierdere care învață reprezentări prin creșterea similitudinii perechilor pozitive față de cele negative sau prin constrângeri de distanță
InfoNCE „Pierderea CLIP/SimCLR” Entropie încrucișată normalizată și scalată cu temperatură peste scoruri de similitudine, care tratează perechea pozitivă drept clasa corectă între candidați
Focal loss „Soluția pentru date dezechilibrate” Entropie încrucișată ponderată prin (1-p_t)^gamma, care reduce contribuția exemplelor ușoare și concentrează optimizarea asupra celor dificile
Pierdere triplet „Ancoră–pozitiv–negativ” Împinge ancora mai aproape de exemplul pozitiv decât de cel negativ cu cel puțin o marjă în spațiul embeddingurilor
Temperatură „Butonul de ascuțime” Scalar care împarte logiții sau similitudinile și controlează concentrarea distribuției rezultate; o valoare mai mică produce o distribuție mai ascuțită

Lecturi suplimentare

  • Lin și colaboratorii, „Focal Loss for Dense Object Detection” (2017) — a introdus focal loss pentru dezechilibrul extrem al claselor din detecția obiectelor cu RetinaNet.
  • Chen și colaboratorii, „A Simple Framework for Contrastive Learning of Visual Representations” (SimCLR, 2020) — a definit o conductă modernă de învățare contrastivă cu pierderea NT-Xent.
  • Szegedy și colaboratorii, „Rethinking the Inception Architecture” (2016) — a introdus netezirea etichetelor drept tehnică de regularizare.
  • Hinton și colaboratorii, „Distilling the Knowledge in a Neural Network” (2015) — distilarea cunoașterii cu ținte moi și divergență KL, fundamentală pentru comprimarea modelelor.

Sursă: Originalul în limba engleză

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