Градиент — направление наискорейшего роста

Градиент — вектор частных производных, указывающий направление самого быстрого роста функции.

Градиент $\nabla f(x)=\left(\dfrac{\partial f}{\partial x_1},\dots,\dfrac{\partial f}{\partial x_n}\right)$ — вектор, направленный в сторону наискорейшего возрастания $f$; его длина равна крутизне этого роста.

Зачем нужен градиент

Слепой путник на склоне, чтобы спускаться, должен чувствовать наклон под ногами. Математический аналог этого наклона в многомерии — градиент. Если двигаться в сторону $+\nabla f$, функция растёт быстрее всего; в сторону $-\nabla f$ — убывает быстрее всего. Именно поэтому почти все методы непрерывной оптимизации делают шаг против градиента — это и есть градиентный спуск.

Для функции одной переменной градиент — это просто производная $f'(x)$. Для функции $n$ переменных каждая координата градиента — частная производная: насколько меняется $f$, если чуть-чуть подвинуть только одну переменную, а остальные заморозить.

Пример руками

Возьмём $f(x,y)=x^2+3y^2$. Частные производные:

$$\frac{\partial f}{\partial x}=2x,\qquad \frac{\partial f}{\partial y}=6y,\qquad \nabla f(x,y)=(2x,\,6y).$$

В точке $(1,1)$ градиент равен $(2,6)$: по оси $y$ функция растёт втрое круче, чем по оси $x$. Длина градиента $\lVert\nabla f\rVert=\sqrt{4+36}=\sqrt{40}\approx 6.32$ — это скорость роста в самом крутом направлении.

Численный градиент

Когда формулы производной нет (или функция задана кодом), градиент считают численно конечными разностями:

$$\frac{\partial f}{\partial x_i}\approx \frac{f(x+\varepsilon e_i)-f(x-\varepsilon e_i)}{2\varepsilon},$$

где $e_i$ — орт $i$-й оси, $\varepsilon$ — малый шаг. Это центральная разность, точная до $O(\varepsilon^2)$.

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

def numeric_grad(f, v, eps=1e-6):
    g = []
    for i in range(len(v)):
        plus = list(v); plus[i] += eps
        minus = list(v); minus[i] -= eps
        g.append((f(plus) - f(minus)) / (2 * eps))
    return g

point = [1.0, 1.0]
g = numeric_grad(f, point)
print("Численный градиент:", [round(c, 4) for c in g])
print("Точный градиент:    [2, 6]")
length = sum(c * c for c in g) ** 0.5
print("Длина:", round(length, 4))

Вывод:

Численный градиент: [2.0, 6.0]
Точный градиент:    [2, 6]
Длина: 6.3246

Численный градиент совпал с точным до знаков — этот приём незаменим для проверки аналитических формул в реальном коде.

Градиент перпендикулярен линии уровня

Важный геометрический факт: $\nabla f$ в точке всегда перпендикулярен линии уровня, проходящей через эту точку. Интуиция: вдоль линии уровня $f$ не меняется, значит наклон вдоль неё нулевой; а самый крутой рост — строго поперёк. Этот факт лежит в основе условия Лагранжа для задач с ограничениями.

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

Численный градиент стоит $2n$ вычислений $f$ (по два на каждую переменную). Для нейросети с миллионами весов это неприемлемо дорого, поэтому там используют обратное распространение (backpropagation) — способ получить весь градиент за стоимость примерно одного-двух вычислений $f$ через правило цепочки. Но идея та же: градиент — вектор частных производных. Слишком маленький $\varepsilon$ в численной формуле приводит к катастрофическому сокращению (вычитание близких чисел), слишком большой — к ошибке аппроксимации; $\varepsilon\sim 10^{-6}$ — разумный компромисс для float64.

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

  • Шаг $\varepsilon$ наугад. Слишком мал — теряется точность из-за округления; слишком велик — формула неверна.
  • Односторонняя разность вместо центральной. $(f(x+\varepsilon)-f(x))/\varepsilon$ точна лишь до $O(\varepsilon)$ — вдвое хуже по порядку.
  • Путать градиент и производную по направлению. Производная вдоль вектора $u$ равна $\nabla f\cdot u$, а не самому градиенту.

Итоги

  • Градиент $\nabla f$ — вектор частных производных, указывает наискорейший рост; $-\nabla f$ — наискорейшее убывание.
  • Длина градиента — крутизна; направление перпендикулярно линии уровня.
  • Численный градиент через центральную разность точен до $O(\varepsilon^2)$ и удобен для проверки.
Проверьте себя
1. Куда указывает градиент $\nabla f$?
AВ сторону наискорейшего убывания
BВ сторону наискорейшего возрастания функции
CВдоль линии уровня
DВ точку минимума
2. Почему предпочитают центральную разность $(f(x+\varepsilon)-f(x-\varepsilon))/(2\varepsilon)$?
AОна быстрее
BОна точна до $O(\varepsilon^2)$, а односторонняя только до $O(\varepsilon)$
CОна не требует $\varepsilon$
DОна работает без производных
3. Как градиент связан с линией уровня?
AПараллелен ей
BПерпендикулярен ей
CКасается её
DСовпадает с ней