ML Atlas

06 · Sieci · 4 min czytania · Interaktywne · aktualizacja

Czym jest exploding gradient i vanishing gradient i dlaczego loss staje się NaN?

W skrócie

Gradient w głębokiej sieci to iloczyn czynników z kolejnych warstw: gdy są mniejsze od 1, zanika, gdy większe, rośnie wykładniczo i wagi uciekają do NaN.

Co to jest

Zanikający gradient (vanishing gradient) to sytuacja, w której gradient dla wczesnych warstw sieci jest tak mały, że te warstwy prawie się nie uczą. Eksplodujący gradient (exploding gradient) to lustrzane odbicie: gradient rośnie wykładniczo z głębokością, kroki stają się ogromne, wagi uciekają poza zakres liczb zmiennoprzecinkowych, a strata zmienia się w Infinity, potem w NaN.

Oba zjawiska występują w głębokich sieciach, w sieciach rekurencyjnych (rozwiniętych w czasie) i w transformerach. Standardowe lekarstwa to dobra inicjalizacja, aktywacje typu ReLU, normalizacja, połączenia residualne oraz przycinanie gradientu (gradient clipping).

Intuicja: głuchy telefon przez dziesięć osób. Jeśli każda mówi trochę ciszej niż usłyszała, na końcu słychać szept; jeśli każda trochę głośniej — krzyk. Gradient przechodzi przez warstwy jak ta wiadomość, tylko że mnożony, a nie przekazywany.

Mechanizm — dlaczego tak działa

Gradient dla wag warstwy l to iloczyn jakobianów warstw l+1 … L. Jeśli typowa norma jakobianu warstwy wynosi a, gradient skaluje się jak a^(L−l): dla a = 1,5 i 10 warstw to około 58 razy więcej, dla a = 0,5 — około 1000 razy mniej. To samo dotyczy sieci rekurencyjnej rozwiniętej w czasie, gdzie ta sama macierz mnoży się na każdym kroku (Bengio i in. 1994, Pascanu i in. 2013).

Na jakobian składają się wagi i pochodna aktywacji. Pochodna sigmoidu wynosi najwyżej 0,25, więc przy wagach rzędu jedności każda warstwa sigmoidowa tłumi gradient co najmniej czterokrotnie — to klasyczne źródło zanikania. ReLU ma pochodną 1 dla aktywnych neuronów, więc o kierunku decydują głównie wagi. Bez sufitu na aktywacje pojawia się dodatnie sprzężenie zwrotne: większe wagi dają większe aktywacje, większe aktywacje większe gradienty, większe gradienty większy krok i jeszcze większe wagi. Momentum i Adam dokładają rozpęd: kilka dużych gradientów z rzędu daje krok większy niż każdy z osobna.

Sufit liczb: float32 kończy się około 3,4·10³⁸, float16 już na 65 504. Przekroczenie daje Infinity, a Infinity − Infinity = NaN; jeden NaN w wagach zaraża całą sieć w jednym przebiegu. Stąd potrzeba restartu z ostatniego dobrego punktu, a nie „douczania”.

Przycinanie gradientu: jeśli norma ‖g‖ przekracza c, przeskaluj g ← c · g/‖g‖ (typowo c = 1–5). Kierunek kroku zostaje, długość jest ograniczona. Zhang i in. (2020) pokazali, że to nie tylko plaster — clipping przyspiesza zbieżność, gdy krzywizna rośnie razem z gradientem. Profilaktyka: inicjalizacja He lub Xaviera (norma jakobianu bliska 1 na starcie), normalizacja warstw, połączenia residualne, rozgrzewka learning rate.

Na przykładzie

Zbudowałem w numpy sieć z 10 warstwami ukrytymi po 64 neurony, przepuściłem przez nią 1347 standaryzowanych obrazów Digits 8×8 (random_state=0) i policzyłem normę gradientu entropii krzyżowej dla wag każdej warstwy — na starcie, przed jakimkolwiek treningiem. Przy sigmoidzie z inicjalizacją Xaviera gradient pierwszej warstwy wynosi 1,1·10⁻⁶, a ostatniej ukrytej 0,30: wczesne warstwy dostają ćwierć miliona razy słabszy sygnał. Przy tanh z Xavierem stosunek wynosi 1,2, przy ReLU z inicjalizacją He — 0,41: gradient dociera do wszystkich warstw.

Wystarczy zmienić skalę wag. ReLU z wagami 1,5 raza większymi niż He daje na ostatniej warstwie aktywacje o odchyleniu 44,5 i gradienty rzędu 58–225 (zalążek eksplozji); z wagami 2 razy mniejszymi — aktywacje o odchyleniu 0,00075 i gradienty rzędu 0,0004–0,0006 (zanik). W praktyce: MLPClassifier z ośmioma warstwami sigmoidowymi po 32 neurony (Adam, lr = 0,001) zatrzymuje się na trafności 10,2% i stracie 2,303 = ln 10, czyli zgadywaniu; ta sama sieć z tanh osiąga 96,9%.

Ta ilustracja działa w przeglądarce z włączonym JavaScriptem: normy gradientu w każdej warstwie głębokiej sieci tuż po inicjalizacji, na paczce 256 cyfr: przy 20 warstwach sigmoidy z Xavierem stosunek pierwsza/ostatnia warstwa to 2,4·10⁻¹³, a przy ReLU z inicjalizacją He 2,19 — gradient nie zanika.

Dane: Digits (ręcznie pisane cyfry 8×8)

W praktyce

  • PyTorch: torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) między backward() a step(); w treningu LLM to standard (typowo próg 1,0).
  • Monitoruj normę gradientu każdej warstwy i maksymalną wartość bezwzględną wag; skok o rzędy wielkości poprzedza NaN o kilka kroków.
  • Mixed precision (float16) wybucha dużo wcześniej niż float32 — stąd GradScaler i bfloat16.
  • Pierwszy ruch po NaN: zmniejsz learning rate 3–10 razy, dodaj clipping, sprawdź standaryzację wejść i brak log(0) w stracie.
  • Przy zanikaniu: zamień sigmoid na ReLU/GELU, dobierz inicjalizację do aktywacji, dodaj BatchNorm/LayerNorm i połączenia residualne; w sieciach rekurencyjnych użyj LSTM lub GRU.

Najczęstsze pytania

Czym różni się exploding gradient od vanishing gradient?
Oba wynikają z mnożenia jakobianów warstw. Gdy ich normy są większe niż 1, gradient rośnie wykładniczo z głębokością (wybuch) — wagi uciekają, strata daje NaN. Gdy mniejsze niż 1, gradient maleje wykładniczo (zanik) — wczesne warstwy się nie uczą. Lekarstwa są częściowo wspólne: inicjalizacja, normalizacja, residua.
Dlaczego loss staje się NaN podczas treningu?
Najczęściej za duży learning rate wypchnął wagi poza zakres liczb (Infinity, potem NaN). Inne przyczyny: log(0) w stracie przy prawdopodobieństwie dokładnie 0, dzielenie przez zero w normalizacji, NaN w danych wejściowych. Sprawdź dane, zmniejsz learning rate, dodaj clipping.
Jak działa gradient clipping?
Po policzeniu gradientów liczy się ich łączną normę; jeśli przekracza próg c, cały wektor gradientu skaluje się tak, by norma wynosiła dokładnie c. Kierunek kroku się nie zmienia, tylko jego długość. Typowy próg to 1,0; stosuje się go przed krokiem optymalizatora.

Źródła

  • Bengio, Y., Simard, P., Frasconi, P. (1994). "Learning long-term dependencies with gradient descent is difficult". IEEE Trans. Neural Networks 5(2), 157–166.
  • Pascanu, R., Mikolov, T., Bengio, Y. (2013). "On the difficulty of training recurrent neural networks". ICML. arXiv:1211.5063
  • Glorot, X., Bengio, Y. (2010). "Understanding the difficulty of training deep feedforward neural networks". AISTATS, PMLR 9, 249–256.
  • Zhang, J., He, T., Sra, S., Jadbabaie, A. (2020). "Why gradient clipping accelerates training: a theoretical justification for adaptivity". ICLR. arXiv:1905.11881
  • Goodfellow, Bengio, Courville (2016). Deep Learning, rozdz. 8.2.4 "Cliffs and exploding gradients", 10.11.1 "Clipping gradients". https://www.deeplearningbook.org/contents/optimization.html

Zobacz też