Овраги и осцилляция

В вытянутой долине градиентный спуск зигзагует между стенками вместо движения по дну — это главная слабость метода.

Овраг (ravine) — вытянутая долина, где функция круто меняется в одном направлении и почти плоская вдоль другого; градиентный спуск в ней мучительно медленный.

Откуда берутся овраги

Если кривизна функции по разным осям сильно различается, чаша вытягивается в длинный жёлоб. Возьмём $f(x,y)=x^2+100y^2$. По оси $y$ стенки в $100$ раз круче, чем по $x$. Градиент почти всегда смотрит поперёк оврага (в крутую стенку), а не вдоль него (к минимуму). Поэтому спуск прыгает от стенки к стенке, едва-едва продвигаясь по дну.

Число обусловленности

Степень «оврагистости» измеряет число обусловленности гессиана — отношение наибольшей кривизны к наименьшей:

$$\kappa=\frac{\lambda_{\max}}{\lambda_{\min}}.$$

Для $f=x^2+100y^2$ это $\kappa=100/1=100$. Скорость градиентного спуска падает с ростом $\kappa$: число итераций для заданной точности растёт примерно как $\kappa$. При $\kappa=10^6$ (типично для плохо масштабированных данных) спуск практически стоит на месте.

Зигзаг в коде

Запустим спуск на овраге и посмотрим на знаки координаты $y$ — они скачут, выдавая осцилляцию.

def grad(v):
    x, y = v
    return [2 * x, 200 * y]      # f = x^2 + 100 y^2

def f(v):
    return v[0] ** 2 + 100 * v[1] ** 2

x = [10.0, 1.0]
alpha = 0.009      # близко к критическому 2/200 = 0.01
for k in range(1, 31):
    g = grad(x)
    x = [x[0] - alpha * g[0], x[1] - alpha * g[1]]
    if k <= 6 or k % 6 == 0:
        print(f"шаг {k:2d}: x=({x[0]:.4f}, {x[1]:+.4f})  f={f(x):.4f}")

Вывод:

шаг  1: x=(9.8200, -0.8000)  f=160.4324
шаг  2: x=(9.6432, +0.6400)  f=133.9521
шаг  3: x=(9.4697, -0.5120)  f=115.8889
шаг  4: x=(9.2992, +0.4096)  f=103.2525
шаг  5: x=(9.1318, -0.3277)  f=94.1276
шаг  6: x=(8.9674, +0.2621)  f=87.2871
шаг 12: x=(8.0415, +0.0687)  f=65.1382
шаг 18: x=(7.2112, +0.0180)  f=52.0337
шаг 24: x=(6.4666, +0.0047)  f=41.8191
шаг 30: x=(5.7989, +0.0012)  f=33.6272

Координата $y$ меняет знак на каждом шаге (осцилляция между стенками оврага), а $x$ ползёт к нулю до обидного медленно: за $30$ шагов прошли лишь от $10$ до $5.8$. Узкое горлышко — именно пологое направление $x$, по которому информации о наклоне почти нет.

Лекарства

  • Масштабирование/нормировка. Привести переменные к одному масштабу — уменьшить $\kappa$, сделать чашу круглой.
  • Momentum. Накапливать скорость вдоль дна оврага, гасить поперечные колебания (следующий раздел).
  • Метод Ньютона. Учесть кривизну гессианом — он «выпрямляет» овраг (раздел про Ньютона).

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

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

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

  • Списывать медленность на малый $\alpha$. В овраге увеличение $\alpha$ вызовет взрыв по крутой оси раньше, чем ускорит движение по пологой.
  • Игнорировать масштаб признаков. Разные единицы измерения создают искусственные овраги.
  • Не считать $\kappa$. Большое число обусловленности — сигнал, что чистый спуск не подойдёт.

Итоги

  • Овраг — вытянутая долина с разной кривизной по осям; спуск зигзагует между стенками.
  • Число обусловленности $\kappa=\lambda_{\max}/\lambda_{\min}$ задаёт замедление (итераций $\sim\kappa$).
  • Лечится нормировкой, моментом или вторым порядком (Ньютон).
Проверьте себя
1. Почему градиентный спуск медлен в овраге?
AГрадиент равен нулю
BОдин общий шаг не подходит сразу крутой и пологой осям — возникает зигзаг
CФункция не выпукла
DСлишком много переменных
2. Что такое число обусловленности $\kappa$ гессиана?
AСумма собственных чисел
BОтношение наибольшей кривизны к наименьшей $\lambda_{\max}/\lambda_{\min}$
CНорма градиента
DЧисло переменных
3. Какое средство НЕ помогает против оврагов?
AНормировка переменных
BMomentum
CМетод Ньютона
DПросто увеличить общий шаг $\alpha$