Как ответить
Градиентный взрыв и затухание градиентов — это две противоположные проблемы при обучении глубоких нейронных сетей с обратным распространением ошибки. Суть в том, что при передаче градиента от выходного слоя к входному через многослойную цепочку весов и активаций, его значение либо экспоненциально растёт (взрыв), либо стремится к нулю (затухание). Обе делают обучение нестабильным: взрыв приводит к переполнению чисел и NaN, затухание — к остановке обучения на ранних слоях.
Причин несколько. Для затухания — классические сигмоида и tanh, градиент которых в насыщении близок к нулю, плюс малое инициализированное значение весов. Для взрыва — большие начальные веса или нестабильные функции активации (например, ReLU без нормализации). Особенно остро обе проблемы стоят в RNN из-за развёртывания во времени.
Основные методы борьбы:
- Инициализация весов: Xavier (Glorot) для tanh/сигмоиды, He для ReLU. Они подбирают дисперсию так, чтобы сигнал проходил без сильного затухания или взрыва.
- Функции активации: замена сигмоиды на ReLU (всё, что ≥0 — градиент 1) или его модификации (Leaky ReLU, ELU). Это уменьшает затухание. Для взрыва — ограничение значений (ReLU6).
- Нормализация: Batch Normalisation (фиксирует среднее и дисперсию внутри батча) и Layer Normalisation (для RNN/Transformer). Стабилизирует распределение входов каждого слоя, уменьшая накопление больших/малых градиентов.
- Градиентное клиппирование: прямое ограничение нормы градиента (например, max_norm=5). Работает от взрыва — просто обрезаем, если слишком большой.
- Skip-connections (ResNet, DenseNet): позволяют градиенту «перепрыгивать» слои, обходя цепочки умножений. Решает затухание в глубоких сетях.
- Архитектуры RNN: LSTM и GRU — за счёт гейтов и ячейки памяти градиент может долго сохраняться, не затухая. Вариант — gradient clipping для взрыва.
- Оптимизаторы с адаптивным шагом: Adam, RMSprop — автоматически подстраивают learning rate под каждый параметр, частично сглаживая аномалии градиентов.
- Диагностика: логгирование нормы градиентов (L2) при обучении — если видим резкий всплеск или падение до нуля, подкручиваем параметры.
На практике я обычно начинаю с He-инициализации, ReLU, BatchNorm и Adam. Если вижу градиентный взрыв (скачки loss или NaN), добавляю клиппирование с порогом 1–10. Для RNN — беру LSTM и клиппирование.