Оптимизаторы нейросетей: SGD, Momentum и Adam на Python
Оптимизатор - это правило, которое превращает градиенты в изменения весов. Обычный градиентный спуск использует только текущий градиент; momentum помнит прошлые направления, а Adam ещё и подбирает длину шага для каждого веса.
Суть простыми словами
Оптимизатор - это правило, которое превращает градиенты в изменения весов. Обычный градиентный спуск использует только текущий градиент; momentum помнит прошлые направления, а Adam ещё и подбирает длину шага для каждого веса.
Сравните обычный градиентный спуск, momentum и Adam, минимизируя одну и ту же функцию шаг за шагом.
Главные идеи
- Momentum хранит скорость, поэтому прокатывается через плоские участки и мелкие неровности.
- Adam хранит скользящие средние градиента и квадрата градиента.
- Коррекция смещения (деление на 1 − βᵗ) исправляет эти средние на первых шагах.
- Хорошая инициализация весов и мини-батчи тоже делают обучение быстрее и стабильнее.
Когда это использовать?
- Понять, что происходит внутри нейронных сетей и библиотек ИИ.
- Разобраться в идее до того, как реализовать её в соответствующих задачах.
- Подготовиться к курсам по машинному обучению, собеседованиям и проектам.
Посмотрите в действии
Нажмите Запуск, и три оптимизатора наперегонки спустятся в одну и ту же неровную долину. Увеличьте скорость обучения, чтобы увидеть, как momentum проскакивает минимум.
Пример кода
import math
# Minimise f(x) = (x - 3)² with three optimizers. The gradient is 2(x - 3).
grad = lambda x: 2 * (x - 3)
def sgd(steps, lr=0.1):
x = 0.0
for _ in range(steps):
x -= lr * grad(x)
return x
def momentum(steps, lr=0.1, beta=0.9):
x, v = 0.0, 0.0
for _ in range(steps):
v = beta * v + grad(x) # remember the direction we were going
x -= lr * v
return x
def adam(steps, lr=0.3, b1=0.9, b2=0.999, eps=1e-8):
x, m, v = 0.0, 0.0, 0.0
for t in range(1, steps + 1):
g = grad(x)
m = b1 * m + (1 - b1) * g # running mean of gradients
v = b2 * v + (1 - b2) * g * g # running mean of squared gradients
m_hat, v_hat = m / (1 - b1 ** t), v / (1 - b2 ** t)
x -= lr * m_hat / (math.sqrt(v_hat) + eps)
return x
for steps in (5, 20, 50):
print(f"{steps:>2} steps sgd={sgd(steps):.3f} momentum={momentum(steps):.3f} adam={adam(steps):.3f}")
Ожидаемый результат
5 steps sgd=2.017 momentum=4.741 adam=1.476
20 steps sgd=2.965 momentum=4.048 adam=3.813
50 steps sgd=3.000 momentum=3.091 adam=3.014
Как это работает
Все три минимизируют (x − 3)², самая низкая точка которой x = 3. SGD движется равномерно, momentum разгоняется и проскакивает цель, прежде чем успокоиться, а Adam масштабирует каждый шаг скользящими средними градиента и его квадрата. Через 50 шагов все три близки к 3.
Измените значения и запустите программу в онлайн-компиляторе Python CodeUtility без локальной установки Python.
Практические задания
Изменяйте входные данные и проверяйте граничные случаи перед работой с большими наборами.
- Измените входные данные или веса и предскажите результат до запуска.
- Выводите промежуточные значения, чтобы проследить каждый шаг вычислений.
- Решите задачи по ссылкам ниже, чтобы самостоятельно реализовать идею.
Попрактикуйтесь на задаче
Примените материал этого урока к реальной задаче. Каждая задача запускается в браузере, с мгновенными тестами и разбором от ИИ.
- Инициализация весов Xavier и He Вычислите диапазон или стандартное отклонение для инициализации весов слоя. Легко
- Мини-батч градиентный спуск Обучите линейную модель, обновляя веса после каждого небольшого батча, а не после всего набора данных. Средне
- Градиентный спуск с моментом Примените обновления с моментом, которые сохраняют часть предыдущего шага, чтобы обучение ускорялось в постоянных направлениях. Легко
- Оптимизатор Adam Реализуйте Adam, стандартный оптимизатор глубокого обучения, со скользящими средними и коррекцией смещения. Средне