Градиентный спуск: поиск минимума

Главный алгоритм машинного обучения: скатываемся в минимум, шагая против градиента.

Градиентный спуск — итеративный метод минимизации функции: на каждом шаге сдвигаемся против градиента, $x_{n+1}=x_n-\eta\,\nabla f(x_n)$.

Вот кульминация всего курса — алгоритм, на котором держится современное машинное обучение. Обучить нейросеть — значит минимизировать функцию ошибки от миллионов параметров. Перебрать все варианты невозможно. Но мы знаем: градиент указывает направление роста, значит против градиента — направление спуска. Идея гениально проста: стой, посчитай градиент, сделай маленький шаг под уклон, повтори. Так мы скатываемся в минимум.

Формула шага

$$x_{n+1} = x_n - \eta\,\nabla f(x_n)$$

Здесь $\eta$ (эта) — скорость обучения (learning rate), размер шага. Слишком маленькая — спуск ползёт целую вечность. Слишком большая — мы перепрыгиваем минимум и можем расходиться, скача по стенкам «оврага». Подбор $\eta$ — искусство.

Симуляция спуска

Минимизируем $f(x,y)=x^2+y^2$ — параболоид-чашу с очевидным минимумом в $(0,0)$. Градиент $(2x, 2y)$. Стартуем издалека и смотрим, как точка скатывается в дно.

def f(x, y): return x**2 + y**2

x, y = 4.0, 3.0      # старт
eta = 0.1            # скорость обучения

for step in range(1, 31):
    gx, gy = 2*x, 2*y
    x -= eta * gx
    y -= eta * gy
    if step in (1, 5, 10, 20, 30):
        print(f"шаг {step:>2}: x={x:.5f}  y={y:.5f}  f={f(x,y):.6f}")

print("минимум функции = 0 в точке (0, 0)")

Вывод:

шаг  1: x=3.20000  y=2.40000  f=16.000000
шаг  5: x=1.31072  y=0.98304  f=2.684355
шаг 10: x=0.42950  y=0.32212  f=0.288230
шаг 20: x=0.04612  y=0.03459  f=0.003323
шаг 30: x=0.00495  y=0.00371  f=0.000038
минимум функции = 0 в точке (0, 0)

Точка послушно скатывается в начало координат: значение функции падает от $16$ почти до нуля. Шаг за шагом, следуя против градиента, алгоритм нашёл минимум. Именно так — только в пространстве миллионов измерений — обучаются нейросети.

Как работает под капотом

В каждой точке градиент говорит, куда круче всего вверх; мы идём ровно в противоположную сторону — вниз по склону. Вблизи минимума градиент становится маленьким (склон выполаживается), поэтому и шаги уменьшаются сами собой — точка плавно «оседает» на дно, не перелетая. Множитель $\eta$ масштабирует шаг: он переводит «крутизну» в «расстояние перемещения». Весь интеллект сводится к многократному повторению одного честного локального действия.

Частые ошибки

Первая и главная — неудачная скорость обучения. Большая $\eta$ заставляет точку перепрыгивать минимум и расходиться (значения растут, а не падают); крошечная — спуск тянется бесконечно. Вторая — застревание в локальном минимуме: для сложных «холмистых» функций спуск может осесть в неглубокой ямке, не найдя глубочайшей. Третья — забыть знак минус: шаг по градиенту (без минуса) ведёт вверх, к максимуму, а не к минимуму. Четвёртая — ждать точного нуля: спуск приближается к минимуму, но достигает его лишь в пределе.

Итог

  • Градиентный спуск минимизирует функцию, шагая против градиента.
  • Формула: $x_{n+1}=x_n-\eta\nabla f(x_n)$.
  • Скорость обучения $\eta$ критична: велика — расходимость, мала — медленно.
  • Это базовый алгоритм обучения нейросетей и оптимизации.
Проверьте себя
1. В каком направлении делает шаг градиентный спуск?
AПо градиенту ∇f
BПротив градиента −∇f
CПерпендикулярно градиенту
DВ случайную сторону
2. Что произойдёт при слишком большой скорости обучения η?
AСпуск ускорится без проблем
BТочка может перепрыгивать минимум и расходиться
CФункция станет линейной
DГрадиент обнулится