Зигзаг в овраге: откуда взялись momentum и Adam
Обучить нейросеть — значит спуститься в минимум функции потерь от миллионов переменных. Но геометрия спуска видна уже на двух. Простой градиентный спуск вязнет в оврагах; импульс разгоняется вдоль дна; Adam подстраивает шаг под каждую координату. Поставьте точку старта и отпустите — посмотрите, кто доберётся до дна первым.
Один шаг вниз
Все три метода читают в текущей точке w один и тот же градиент \nabla L(w) — направление наискорейшего роста. Спуск идёт против него. Разница лишь в том, как превратить градиент в шаг.
Градиентный спуск (GD). Самое прямое правило: шагнуть против градиента на величину, заданную скоростью обучения \eta. w_{t+1} = w_t - \eta\, \nabla L(w_t). Просто — но в вытянутом «овраге» (когда вдоль одной оси кривизна большая, а вдоль другой малая) шаг приходится делать крошечным, иначе по крутой оси начинаются колебания. Спуск ползёт зигзагом и почти не движется вдоль дна.
Импульс (momentum). Накопим скорость, как у скатывающегося шарика: каждый шаг чуть «помнит» предыдущие.
v_{t+1} = \beta\, v_t - \eta\, \nabla L(w_t), \qquad w_{t+1} = w_t + v_{t+1}.
Колебания поперёк оврага гасятся (градиенты разнонаправлены и взаимно сокращаются), а вдоль дна скорость накапливается. Коэффициент \beta — это «память» о прошлых шагах; при \beta=0 получается обычный GD.
Adam. Хранит две скользящие средние: самого градиента (как momentum) и его квадрата. Шаг делится на корень из второй средней — получается свой масштаб для каждой координаты.
m_t = \beta_1 m_{t-1} + (1-\beta_1)\,g_t, \quad v_t = \beta_2 v_{t-1} + (1-\beta_2)\,g_t^2, \quad w_{t+1} = w_t - \eta\,\frac{\hat m_t}{\sqrt{\hat v_t}+\varepsilon}.
По крутым осям шаг автоматически уменьшается, по пологим — растёт. Поэтому Adam устойчив даже там, где для GD пришлось бы подбирать \eta вручную.
Потрогайте спуск
Перетащите точку старта по карте высот: тёмное на ней — дно. Из этой точки все три метода побегут вниз одновременно. Покрутите скорость обучения и импульс \beta, переключите ландшафт — и увидите, где GD застревает в зигзаге, как momentum проскакивает овраг по инерции, а Adam ровно идёт к минимуму.
Вытянутость оврага измеряется числом обусловленности \kappa — отношением наибольшей кривизны к наименьшей. Скорость сходимости GD падает как \frac{\kappa-1}{\kappa+1}: при \kappa=100 каждый шаг сокращает ошибку лишь на \sim 2\%. Momentum улучшает зависимость до \sqrt{\kappa} — отсюда его разгон вдоль дна.
Все три метода видят один и тот же градиент — отличается лишь обработка истории шагов. GD живёт настоящим; momentum помнит, куда катился; Adam ещё и помнит, насколько резко менялась каждая координата. В задачах с миллионами переменных эта память и есть разница между «обучилось за час» и «не сошлось никогда».
За пределами картинки
В реальном обучении L считается не по всем данным сразу, а по случайной небольшой порции — мини-батчу; отсюда «стохастический» в SGD. Градиент становится шумным, и тут импульс с адаптивным масштабом помогают ещё сильнее: усреднение гасит шум, а свой масштаб по каждой координате не даёт редким, но крупным градиентам сбить шаг. Почти всё современное глубокое обучение идёт на вариантах Adam (AdamW) ровно по тем причинам, которые видны на этой карте: устойчивость к вытянутым оврагам без ручного подбора скорости обучения.
Связи
- Ландшафт функции потерь — почему в высокой размерности оврагов и сёдел больше, чем локальных минимумов
- Глобальная оптимизация — что делать, когда градиента нет или минимумов много
- Двойной спуск — что происходит с ошибкой, когда модель доходит до точной интерполяции
- Шум превращает оптимизацию в генерацию — тот же спуск, но с шумом: такой спуск уже не ищет дно