Оптимизаторы в DL. От SGD до AdamW
Вопрос про то, какие есть оптимизаторы в глубоком обучении и какие у них особенности и отличия друг от друга очень популярный. В этом блоге разберем, как именно нужно отвечать на этот вопрос)
Для начала, пару слов о терминологии:
- Оптимизировать будем функцию потерь, то есть некоторый функционал качества работы модели. Например, MSE или logloss.
- Оптимизировать = искать глобальный (в идеале) минимум этой функции потерь.
- Оптимизируем с помощью движения в сторону антиградиента, а тому как именно двигаться и будет посвящена эта статья.
Антиградиент - потому что градиент показывает наискорейшее локальное возрастание функции. Мы хотим искать убывание, то есть берем градиент со знаком минус = антиградиент.
1. GD: Gradient Descent
- Считаем градиент по всей обучающей выборке.
- Смещаемся в сторону антиградиента со скоростью learning rate по формуле:
Может быть довольно точным, но считать градиент на всей выборке просто вычислительно нереально)
2. SGD: Stochastic Gradient Descent
- Нарезаем датасет на батчи: группы данных. Причем очень важно перемешать датасет и выдавать батчи случайно от эпохи к эпохе.
- Считаем градиент по батчу
- Смещаемся в сторону антиградиента со скоростью learning rate по все той же формуле:
- Баланс между скоростью и стабильностью
- Прост в реализации
- Кроме градиентов и весов модели ничего не нужно держать в оперативной памяти
3. SGD с импульсом (Momentum)
Отличие от SGD в том, что мы дополнительно накапливаем градиенты с прошлых шагов и двигаемся не только в сторону “жадного” антиградиента на текущем шаге, но и в сторону общего движения оптимизации.
Пытаемся решить проблему того, что градиент показывает только в сторону локального изменения функции потерь, а мы целимся в сторону глобального минимума.
- Считаем градиент по батчу
- Считаем момент / импульс / скорость по формуле (1)
- Смещаемся в сторону антиградиента со скорректированной скоростью по формуле: (2)
- Ускоряет обучение в направлениях с устойчивым градиентом.
- Сглаживает колебания в шумных градиентах.
- Быстрее обычного SGD.
- Лучше проходит "овраги" в ландшафте функции потерь.
4. Nesterov Accelerated Gradient (NAG)
Отличие от обычного момента в том, что мы как бы заглядываем в будущее и рассчитываем направление оптимального движения оттуда. Грубо: сначала смещаемся по моменту, а только потом по антиградиенту. Если до сих пор непонятно, то лучше всмотреться в формулу
- Считаем градиент по батчу
- Считаем момент / импульс / скорость по формуле (1)
- Смещаемся в сторону антиградиента со скорректированной скоростью по формуле: (2)
Видно, что изменился подсчет градиента, считаем не просто по тета, а по тета минус импульс
5. AdaGrad (Adaptive Gradient)
Делает адаптивные шаги, то есть у разных параметров разные по скорости шаги, тем самым выравнивает скорость в среднем на всем обучении. Логика в том, чтобы делать маленькие шаги при очень больших суммарных градиентах, и увеличивать скорость при небольших суммарных градиентах. Такое возможно за счет деления на корень из суммы квадратов градиентов.
- Считаем градиент по батчу
- Обновляем сумму квадратов градиентов (1)
- Делим скорость learning rate на корень из суммы квадратов градиентов (эпсилон нужен, чтобы случайно на 0 не разделить)
- Смещаемся в сторону антиградиента со скорректированной скоростью по формуле (2):
- Адаптивный learning rate для каждого параметра.
- Большие градиенты уменьшают шаг, малые — увеличивают.
- Learning rate может стать слишком малым (обучение останавливается).
- Нужно в оперативной памяти дополнительно хранить квадраты градиентов.
5. RMSprop
Решаем проблему остановки обучения из-за очень низкого learning rate с помощью экспоненциального сглаживания. В остальном то же самое.
- Считаем градиент по батчу
- Обновляем сумму квадратов градиентов через скользящее среднее (1)
- Делим скорость learning rate на корень из суммы квадратов градиентов (эпсилон нужен, чтобы случайно на 0 не разделить)
- Смещаемся в сторону антиградиента со скорректированной скоростью по формуле (2):
6. Adam (Adaptive Moment Estimation)
Комбинация Momentum и RMSprop, то есть адаптивный learning rate + учет истории градиентов.
- Считаем градиент по батчу
- Обновляем момент (1)
- Обновляем сумму квадратов градиентов через скользящее среднее (2)
- Смещаемся по формуле (3):
- Иногда сходится к субоптимальным решениям
- Требует тонкой настройки
- Нужно в оперативной памяти дополнительно хранить моменты и квадраты градиентов.
Улучшенный Adam с правильным учетом L2-регуляризации (weight decay).
Это сделано для того, чтобы эффект L2-регуляризации не затухал со временем и обобщающая способность модели была выше.
Плюсы и минусы такие же как у Адама, но чуть лучше сходится за счет регуляризации.
Заключение
Конечно, есть и другие оптимизаторы, и они даже используются на практике, но про них не спрашивают на собеседованиях и не особо часто используют в реальных задачах. Поэтому достаточно просто знать, что иногда придется использовать что-то кроме адама, например, lion.
Также не забывайте, что есть разные оптимизаторы специально придуманные для мульти-гпу, например, LARS, LAMB.
Но для собесов и работы до определенного момента достаточно знать только рассмотренные выше.