Градиентный спуск
| Тип | метод оптимизации первого порядка |
|---|---|
| Предложен | Огюстен Коши (1847) |
| Стохастический вариант | Роббинс и Монро (1951) |
| Ключевой гиперпараметр | темп обучения (learning rate) |
| Популярные оптимизаторы | SGD с моментом, Adam, AdamW |
| Вычисление градиента в нейросетях | обратное распространение ошибки |
Градиентный спуск (англ. gradient descent) — итеративный метод поиска минимума функции: на каждом шаге параметры сдвигаются в направлении, противоположном градиенту, то есть туда, где функция убывает быстрее всего. В машинном обучении минимизируется функция потерь — мера ошибки модели на данных, — а параметрами служат веса модели. Почти все нейросети, включая большие языковые модели, обучаются одним из вариантов градиентного спуска.[3]
Идея
Градиент $\nabla L(\theta)$ — вектор частных производных функции потерь по каждому параметру; он указывает направление наискорейшего роста. Шаг обновления:
$$\theta \leftarrow \theta - \eta \, \nabla L(\theta)$$
где $\eta$ — темп обучения (learning rate). Образ — спуск с горы в тумане: видно только наклон под ногами, и путник каждый раз шагает вниз по склону.
Метод описал Огюстен Коши в 1847 году. Для нейросетей он стал практичным после популяризации обратного распространения ошибки (backpropagation, 1986) — алгоритма, вычисляющего градиент по всем весам за один проход назад по сети с помощью цепного правила.[6] Сейчас это делают автоматически фреймворки вроде PyTorch.
Темп обучения
Самый важный гиперпараметр. Слишком маленький темп — обучение идёт мучительно долго и застревает; слишком большой — шаги «перепрыгивают» минимум, потери скачут или уходят в бесконечность. На практике темп меняют по расписанию: короткий разогрев (warmup) с нуля, затем плавное снижение — косинусное или ступенчатое.
Варианты по объёму данных
| Вариант | Градиент считается по | Свойства |
|---|---|---|
| Полный (batch) | всей выборке | точный, но дорогой шаг; не помещается в память |
| Стохастический (SGD) | одному примеру | шумный, дешёвый шаг |
| Мини-батч | группе из 32–4096 примеров | компромисс, стандарт на практике |
Стохастический подход восходит к работе Роббинса и Монро 1951 года.[5] Шум мини-батчей не только экономит вычисления, но и помогает выбираться из неудачных областей и, по-видимому, способствует лучшему обобщению. Под «SGD» сегодня почти всегда понимают мини-батчевый вариант.
Оптимизаторы
Поверх базового шага придуманы улучшения:[1]
- Момент (momentum) — накапливает «скорость» из предыдущих градиентов, сглаживая колебания в узких оврагах функции потерь. Вариант — момент Нестерова.
- Адаптивные методы — AdaGrad, RMSProp — подбирают свой темп для каждого параметра по истории его градиентов.
- Adam (2014) сочетает момент и адаптивный темп и стал выбором по умолчанию для нейросетей.[2] AdamW правильно отделяет регуляризацию весов от шага (см. Переобучение и регуляризация) и используется при обучении трансформеров.
import torch
model = torch.nn.Linear(10, 1)
opt = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=0.01)
loss_fn = torch.nn.MSELoss()
for xb, yb in loader: # мини-батчи
opt.zero_grad()
loss = loss_fn(model(xb), yb)
loss.backward() # обратное распространение: градиенты
opt.step() # шаг градиентного спуска
Трудности
- Невыпуклость. У нейросетей функция потерь имеет множество локальных минимумов и седловых точек. На практике в высокой размерности плохие локальные минимумы редки, а от сёдел спасает шум SGD.
- Затухание и взрыв градиентов в глубоких сетях — решаются нормализацией, остаточными связями и обрезкой градиента (gradient clipping).
- Масштаб признаков. Признаки разного порядка вытягивают поверхность потерь, и спуск идёт зигзагом; помогает стандартизация.
- Память. Adam хранит два дополнительных значения на каждый параметр, поэтому оптимизатор занимает больше памяти, чем сама модель; для больших моделей используют шардирование состояния и смешанную точность.
Где ещё применяется
Градиентный бустинг — тоже градиентный спуск, только в пространстве функций: каждое новое дерево аппроксимирует антиградиент потерь. Линейные модели в scikit-learn (SGDClassifier) обучаются SGD на данных, не помещающихся в память.
См. также
- Нейронная сеть
- PyTorch
- Переобучение и регуляризация
- Градиентный бустинг (XGBoost, CatBoost, LightGBM)
Источники
- Ruder — An overview of gradient descent optimization algorithms (2016)
- Kingma, Ba — Adam: A Method for Stochastic Optimization (2014)
- Goodfellow, Bengio, Courville — Deep Learning, гл. 8
- PyTorch — torch.optim
- Robbins, Monro — A Stochastic Approximation Method (1951)
- Rumelhart, Hinton, Williams — Learning representations by back-propagating errors (1986)