Hoppa till innehållet
AI-grafen
E· Universitetdeep-learning· ca 60 min· utvecklande· verifierad 2026-09-20

Försvinnande och exploderande gradienter

Kunna diagnostisera gradientproblem och åtgärda med initiering, normalisering och residualer.

Förkunskaper

Intuition

Gradienten till lager 1 i ett djupt nät är en produkt av många faktorer. Små avvikelser från 1 förstärks exponentiellt:

Faktor per lagerEfter 30 lager
0,80,001 — försvunnen
0,950,21
1,01,0
1,054,3
1,2237 — exploderad

Symptomen skiljer sig:

  • Försvinnande: de tidiga lagren lär sig inte alls; lossen planar ut på en dålig nivå; gradientnormen i lager 1 är storleksordningar mindre än i sista lagret.
  • Exploderande: loss blir NaN eller hoppar våldsamt; gradientnormen skjuter i höjden ett enskilt steg.

Diagnosen är enkel: logga gradientnormen per lager. Problemet syns direkt.

Formellt

Fyra åtgärder, och vad var och en faktiskt gör:

ÅtgärdMekanism
He/Xavier-initieringhåller variansen konstant genom lagren från start
ReLU/GELU i stället för sigmoid/tanhderivatan mättas inte mot 0 för stora |x|
Normalisering (batch/layer)håller aktiveringarna i ett rimligt intervall lager för lager
Residualkopplingary=x+F(x)y = x + F(x) ger ∂y/∂x=I+JF\partial y/\partial x = I + J_F — en genväg med faktor 1

Residualkopplingen är den viktigaste av dem. Den är skälet till att nät med hundratals lager är tränbara: gradienten har alltid en väg tillbaka där den multipliceras med 1.

Gradientklippning mot exploderande gradienter: skala ner hela gradientvektorn om dess norm överskrider ett tak. g←g⋅min⁡(1,c∥g∥)g \leftarrow g\cdot\min\Big(1, \frac{c}{\|g\|}\Big) Klipp på global norm, inte per parameter — annars förvrids riktningen. c = 1,0 är standard för transformers.

Viktig nyansering: klippning behandlar symptomet. Om du behöver klippa varje steg är något annat fel — för hög lr, dålig initiering, eller en bugg i förlusten.

Kod

import torch

def gradientprofil(modell):
    """Logga per lager — här syns problemet direkt."""
    rader = []
    for namn, p in modell.named_parameters():
        if p.grad is not None and p.dim() > 1:
            rader.append((namn, float(p.grad.norm()), float(p.norm())))
    for namn, g, w in rader:
        print(f"{namn:34s} |grad| {g:.2e}  |w| {w:.2e}  förhållande {g/max(w,1e-12):.2e}")
    return rader

# I träningsloopen
loss.backward()
norm = torch.nn.utils.clip_grad_norm_(modell.parameters(), max_norm=1.0)   # global norm
if norm > 10:
    print(f"varning: gradientnorm {norm:.1f} före klippning")
opt.step(); opt.zero_grad()

# Typisk utskrift vid försvinnande gradient:
# blocks.0.attn.W_q   |grad| 3.1e-08  ← storleksordningar mindre
# blocks.15.attn.W_q  |grad| 2.4e-04
# blocks.31.attn.W_q  |grad| 1.9e-03

Förhållandet |grad|/|w| är ofta mer informativt än gradientnormen själv: det säger hur stor relativ förändring steget innebär.

Behärskning innebär

  • Diagnostiserar gradientproblem med gradientnormer
  • Åtgärdar med initiering, normalisering och residualer
  • Använder gradientklippning rätt

Logga in för att göra övningarna och bygga upp din behärskning.

Källor

Alla källor och licenser