Идея и формула спуска
Градиентный спуск — итеративное движение против градиента: самый прямой способ скатиться в минимум.
Градиентный спуск — метод минимизации по правилу $x_{k+1}=x_k-\alpha\,\nabla f(x_k)$, где $\alpha>0$ — длина шага (learning rate).
Почему против градиента
Градиент указывает направление наискорейшего роста. Чтобы функция убывала максимально быстро, надо идти ровно в противоположную сторону — против градиента. Отсюда главная формула всей непрерывной оптимизации:
$$x_{k+1}=x_k-\alpha\,\nabla f(x_k).$$
Здесь $x_k$ — текущая точка, $\nabla f(x_k)$ — наклон в ней, $\alpha$ — насколько далеко шагнуть. Повторяем, пока градиент не станет почти нулевым (мы на дне). На этой формуле обучаются практически все нейросети мира.
Почему шаг уменьшает $f$
Разложим $f$ по Тейлору вдоль шага $-\alpha\nabla f$:
$$f(x_k-\alpha\nabla f)\approx f(x_k)-\alpha\,\lVert\nabla f(x_k)\rVert^2.$$
Слагаемое $\lVert\nabla f\rVert^2\ge 0$, значит при достаточно малом $\alpha>0$ функция гарантированно убывает (пока градиент не ноль). Это и есть теоретическая гарантия спуска.
Первая реализация
Минимизируем чашу $f(x,y)=x^2+3y^2$ с дном в $(0,0)$. Градиент $\nabla f=(2x,6y)$.
def grad(v):
x, y = v
return [2 * x, 6 * y]
def f(v):
x, y = v
return x * x + 3 * y * y
x = [5.0, 5.0]
alpha = 0.1
for k in range(1, 26):
g = grad(x)
x = [x[0] - alpha * g[0], x[1] - alpha * g[1]]
if k <= 5 or k % 5 == 0:
print(f"шаг {k:2d}: x=({x[0]:.4f}, {x[1]:.4f}) f={f(x):.5f}")
Вывод:
шаг 1: x=(4.0000, 2.0000) f=28.00000 шаг 2: x=(3.2000, 0.8000) f=12.16000 шаг 3: x=(2.5600, 0.3200) f=6.86080 шаг 4: x=(2.0480, 0.1280) f=4.24346 шаг 5: x=(1.6384, 0.0512) f=2.69222 шаг 10: x=(0.5369, 0.0005) f=0.28823 шаг 15: x=(0.1759, 0.0000) f=0.03095 шаг 20: x=(0.0576, 0.0000) f=0.00332 шаг 25: x=(0.0189, 0.0000) f=0.00036
Точка уверенно скатывается к $(0,0)$, $f$ падает к нулю. Обратите внимание: по оси $y$ (где кривизна $6$) спуск идёт куда быстрее, чем по $x$ (кривизна $2$) — координата $y$ почти мгновенно обнулилась, а $x$ тянется. Это первый намёк на проблему оврагов.
Критерий останова
На практике цикл крутят не фиксированное число раз, а пока $\lVert\nabla f(x_k)\rVert>\tau$. Когда норма градиента упала ниже порога — считаем, что достигли дна.
Как работает под капотом
Градиентный спуск — это метод первого порядка: он использует только наклон, игнорируя кривизну. Поэтому он дёшев (один градиент на шаг, никаких матриц) и масштабируется на миллионы переменных — отсюда его доминирование в глубоком обучении. Платой за дешевизну становится медленная (линейная) сходимость и чувствительность к выбору $\alpha$ и к форме функции. Все улучшения (Momentum, Adam, Ньютон) пытаются добавить немного информации о кривизне или истории шагов, не теряя дешевизны.
Частые ошибки
- Шаг в сторону $+\nabla f$. Знак минус критичен; забыли минус — и функция растёт.
- Нет критерия останова. Без него цикл либо рано бросает, либо крутится впустую около дна.
- Один $\alpha$ на все задачи. Подходящий шаг зависит от масштаба функции — об этом следующий урок.
Итоги
- Формула: $x_{k+1}=x_k-\alpha\nabla f(x_k)$ — шаг против градиента.
- Малый $\alpha>0$ гарантирует убывание $f$ (по Тейлору).
- Метод первого порядка: дёшев, масштабируем, но медленный и чувствительный к $\alpha$.