Vanishing Gradient
Проблема исчезающего градиента возникает, когда при обратном распространении градиенты уменьшаются от слоя к слою, из-за чего ранние слои перестают обучаться. Рассматриваются причины и способы решения.
Проблема исчезающего градиента возникает, когда градиенты, которые обратное распространение ошибки передает от функции потерь к первым слоям глубокой нейронной сети, геометрически уменьшаются с глубиной, поэтому самые ранние слои получают слишком малые обновления и не могут обучаться. Поскольку градиент на слое — это произведение локальных производных всех расположенных выше слоев, в сети, где каждый слой уменьшает градиент, его величина между выходом и входом может упасть на много порядков. Сепп Хохрайтер проанализировал этот эффект в своей дипломной работе 1991 года, и он затруднял обучение глубоких сетей прямого распространения и рекуррентных нейронных сетей (RNN), пока не появились более подходящие функции активации, методы инициализации и архитектуры.
Почему градиенты исчезают#
Обратное распространение ошибки применяет правило цепочки, поэтому градиент, доходящий до слоя, — это градиент сверху, умноженный на матрицу весов каждого последующего слоя и производную его функции активации. Производная сигмоиды не превышает 0,25 — это ее значение при входе 0 — и стремится к 0, когда нейрон насыщается при больших положительных или отрицательных входах. Производная tanh достигает максимума 1 и тоже стремится к 0 при насыщении. Поэтому двадцать слоев с сигмоидой умножают градиент как минимум на 0,25²⁰ — менее 10⁻¹² — еще до учета весов. Масштаб весов не менее важен, чем функция активации: Glorot и Bengio связали значительную часть этой проблемы с инициализацией и предложили выбирать дисперсии весов с учетом количества входов и выходов каждого слоя, чтобы дисперсии активаций и градиентов оставались примерно постоянными во всей сети.
Этот эффект легко измерить, сравнив нормы градиентов весов в верхней и нижней частях 20-слойной сети с сигмоидой, с остаточными связями и без них:
import torch
torch.manual_seed(0)
x = torch.randn(64, 32)
# The same 20-layer sigmoid network, without and with residual shortcuts
for residual in (False, True):
layers = [torch.nn.Linear(32, 32) for _ in range(20)]
h = x
for layer in layers:
out = torch.sigmoid(layer(h))
h = h + out if residual else out
h.sum().backward()
# Compare the weight-gradient size at the last layer and the first layer
last, first = layers[-1].weight.grad.norm(), layers[0].weight.grad.norm()
print(f"residual={residual}: layer 20 gradient {last:.1e}, layer 1 gradient {first:.1e}")Без коротких связей норма градиента последнего слоя равна 2.5e+02, а первого — 4.2e-15, то есть примерно на 17 порядков меньше; поэтому веса первого слоя практически никогда не меняются. При наличии остаточных коротких связей градиент первого слоя равен 5.6e+01 — примерно в 38 раз меньше градиента последнего слоя, равного 2.1e+03.
Исчезающие и взрывающиеся градиенты#
Обе проблемы возникают из-за многократного умножения. Исчезающие градиенты незаметно тормозят обучение: функция потерь продолжает снижаться за счет последних слоев, а ранние слои остаются близкими к случайной инициализации. Взрывающиеся градиенты, наоборот, геометрически растут и явно проявляются в виде скачков функции потерь и значений NaN. Обрезка градиентов ограничивает норму взрывающегося градиента перед каждым обновлением, но не помогает, если градиент уже исчез. Связанная с этим проблема «умирающего ReLU» возникает, когда вход нейрона ReLU остается отрицательным: его градиент становится равен 0, и нейрон перестает обучаться.
Как предотвратить исчезновение градиентов#
Самое распространённое решение — остаточное соединение, прямой путь, лежащий в основе остаточных сетей (ResNet). Остаточный блок возвращает x + F(x), поэтому его градиент по x равен единице плюс производная F, а прямой путь без изменений передаёт градиент из вышестоящего слоя.
Остаточные короткие связи позволяют обучать ResNet с более чем 100 слоями и встречаются почти во всех современных глубоких архитектурах — от трансформеров до YOLO26, чьи блоки C3k2 содержат остаточные узкие блоки, а стандартные сверточные блоки объединяют пакетную нормализацию с активациями SiLU.
Вместе с остаточными связями применяют и другие решения:
- Ненасыщающиеся функции активации: Производная ReLU для положительных входов в точности равна 1, а Leaky ReLU и SiLU сохраняют ненулевой градиент также для отрицательных входов.
- Масштабированная инициализация: Инициализация Xavier (Glorot) подходит для слоев с tanh и сигмоидой, а инициализация He удваивает дисперсию весов, компенсируя обнуление половины входов функцией ReLU.
- Слои нормализации: Пакетная нормализация и нормализация слоев удерживают входы функций активации около нулевого среднего и единичной дисперсии, не позволяя им попадать в плоские области насыщения.
- Рекуррентные архитектуры с вентилями: Сети с долгой краткосрочной памятью (LSTM) и с вентильными рекуррентными блоками (GRU) передают состояние дальше с помощью вентильных аддитивных обновлений, а не многократного умножения. Благодаря этому исходная LSTM могла сохранять информацию на временных интервалах длиной более 1 000 шагов.










