Эпоха 3 · Взрыв deep learning · 2014

23 Adam

Adam: A Method for Stochastic Optimization · Kingma & Ba · ICLR 2015
🟧 оригинал выборочно~30 миноригинал ↗
Суть за 20 секунд. Оптимизатор, объединяющий momentum (сглаженное направление) и RMSProp (по-параметрический масштаб) с поправкой на смещение. Даёт быструю устойчивую сходимость почти без тюнинга — дефолт глубокого обучения. Доказательство сходимости, правда, оказалось ошибочным.

Контекст

SGD требует тонкой ручной настройки learning rate и плохо ведёт себя при разреженных/разномасштабных градиентах. Кингма и Ба дают почти-универсальный оптимизатор.

Идея и механизм

Для каждого параметра держим два бегущих средних градиента: первый момент m (как momentum — сглаженное направление) и второй момент v (как RMSProp — сглаженный квадрат, то есть масштаб). Деление шага на √v даёт по-параметрические адаптивные шаги: где градиенты часто большие — шаг меньше, где редкие — больше.

оптимизация Моменты и зачем нужна bias correction

Бегущие средние (экспоненциальные) первого и второго момента градиента:

mt = β1 mt−1 + (1−β1) gt,   vt = β2 vt−1 + (1−β2) gt²

Проблема старта. Инициализируем m0 = v0 = 0, поэтому на первых шагах оценки занижены. Раскрыв рекурсию, можно показать E[mt] = (1 − β1t) E[g] — отсюда поправка делением:

m̂t = mt1 − β1t,   v̂t = vt1 − β2t

Финальный шаг — момент, делённый на корень из масштаба:

w ← w − η · m̂t√v̂t + ε

Деление на √v̂ нормирует каждый параметр к своему масштабу градиента — отсюда устойчивость почти без подбора learning rate.

Python Один шаг Adam
def adam_step(w, g, m, v, t, lr=1e-3, b1=0.9, b2=0.999, eps=1e-8):
    m = b1 * m + (1 - b1) * g          # 1-й момент (momentum)
    v = b2 * v + (1 - b2) * g * g      # 2-й момент (масштаб)
    mh = m / (1 - b1 ** t)             # bias correction
    vh = v / (1 - b2 ** t)
    w -= lr * mh / (vh ** 0.5 + eps)   # адаптивный по-параметрический шаг
    return w, m, v
градиент g m: сглаж. направление v: масштаб (RMS) шаг m̂/√v̂
Adam = momentum (куда двигаться) ÷ масштаб градиента (как сильно), по каждому параметру отдельно.
Аналогия. Спускаться с горы в тумане. Momentum — это инерция: не дёргаться на каждый камень, а держать общее направление вниз. Деление на масштаб — это разная длина шага под ногой: на крутом скользком участке (большие градиенты) ступаешь мелко и осторожно, на пологом (маленькие) — шире. Adam делает и то, и другое автоматически.

Почему это важно

«Поставил и работает» почти без тюнинга → дефолтный оптимизатор глубокого обучения, особенно для трансформеров (обычно AdamW — с корректным weight decay). Нюанс: исходное доказательство сходимости оказалось ОШИБОЧНЫМ (контрпример в AMSGrad, ICLR-2018), и иногда хорошо настроенный SGD лучше генерализует.

Связи

← дополняет7. Backpropagation

Чёткое разделение труда: backprop отвечает «куда» (вычисляет градиент), Adam — «каким шагом» (как по нему двигаться). Один даёт направление, другой — масштаб и инерцию; вместе они и есть обучение сети.

→ движок для32. Transformer

Практически все большие модели обучаются вариантом Adam (AdamW). Без устойчивого адаптивного оптимизатора обучение трансформеров на огромных данных было бы куда капризнее — Adam здесь незаметная, но несущая деталь.

↔ соперник27. ResNet

Две стороны одной задачи «как обучить глубокую сеть»: Adam улучшает оптимизатор, ResNet — архитектуру (skip-связи). Иногда удачная архитектура важнее хитрого оптимизатора, иногда наоборот — и обе линии развивались параллельно.

Вопросы пытливого ума

Если доказательство сходимости было неверным, почему Adam всё равно работает?

Потому что «работает на практике» и «доказуемо сходится в худшем случае» — разные вещи. AMSGrad показал контрпример, где Adam не сходится, и предложил фикс — но на реальных задачах глубокого обучения исходный Adam отлично себя ведёт. Теория догоняла практику; это частый сюжет в ML, где эмпирический успех опережает гарантии.

Говорят, SGD обобщает лучше Adam — почему тогда все пользуются Adam?

Adam быстрее и устойчивее на старте, меньше требует подбора lr — критично для огромных моделей, где один прогон стоит дорого. На некоторых задачах (классическое зрение) тщательно настроенный SGD+momentum даёт чуть лучшее обобщение, но это требует возни. Для трансформеров Adam/AdamW почти безальтернативен — там SGD обучается плохо.

Зачем AdamW, если есть Adam — в чём разница?

В том, как применяется weight decay. В обычном Adam L2-регуляризация попадает в градиент и потом делится на √v̂ — масштабируется неравномерно и работает не как задумано. AdamW отвязывает weight decay от адаптивного шага (применяет напрямую к весам), и регуляризация снова ведёт себя корректно. Маленькая поправка с заметным эффектом на обобщение.

Что читать в оригинале

Конспекта + алгоритм-бокса из статьи достаточно. Если копать — вывод bias correction (мат-блок) и обсуждение в AMSGrad про сходимость.