Частные производные и градиент
Градиент — это вектор из частных производных; он указывает направление, в котором функция растёт быстрее всего.
Частная производная ∂f/∂x — производная функции многих переменных по одной из них, при фиксированных остальных. Градиент — вектор из всех частных производных.
Функции многих переменных
Функция потерь зависит не от одного числа, а от всех весов модели сразу — это функция многих переменных. Например, f(x, y) = x² + y² — «чаша» в трёхмерном пространстве. Чтобы понять, как она меняется, спрашиваем отдельно: «как меняется f, если двигать только x?» и «только y?». Это и есть частные производные.
# Частная производная по i-й переменной: шевелим только её
def partial(f, point, i, h=1e-5):
p_plus = list(point); p_plus[i] += h
p_minus = list(point); p_minus[i] -= h
return (f(*p_plus) - f(*p_minus)) / (2 * h)
def f(x, y):
return x * x + y * y # df/dx = 2x, df/dy = 2y
point = [3, 4]
print("∂f/∂x в (3,4) =", round(partial(f, point, 0), 4), " (2·3 = 6)")
print("∂f/∂y в (3,4) =", round(partial(f, point, 1), 4), " (2·4 = 8)")
Вывод:
∂f/∂x в (3,4) = 6.0 (2·3 = 6) ∂f/∂y в (3,4) = 8.0 (2·4 = 8)
Градиент = вектор частных производных
Собрав все частные производные в один вектор, получаем градиент ∇f. Для f(x, y) = x² + y² в точке (3, 4) градиент равен (6, 8). У этого вектора замечательное свойство: он указывает направление наискорейшего роста функции, а его длина — насколько круто она растёт в эту сторону. Чтобы функцию уменьшать, идут в противоположную сторону — против градиента. Это сердце градиентного спуска.
import math
def gradient(f, point, h=1e-5):
grad = []
for i in range(len(point)):
p_plus = list(point); p_plus[i] += h
p_minus = list(point); p_minus[i] -= h
grad.append((f(*p_plus) - f(*p_minus)) / (2 * h))
return grad
def f(x, y):
return x * x + y * y
g = gradient(f, [3, 4])
print("Градиент в (3,4):", [round(v, 4) for v in g])
print("Длина градиента :", round(math.sqrt(sum(v * v for v in g)), 4))
print("Направление спуска (против градиента):", [round(-v, 4) for v in g])
Вывод:
Градиент в (3,4): [6.0, 8.0] Длина градиента : 10.0 Направление спуска (против градиента): [-6.0, -8.0]
Градиент в минимуме равен нулю
Ещё одно ключевое свойство: в точке минимума (или максимума) функция плоская во все стороны, поэтому все частные производные равны нулю — градиент нулевой. У f(x, y) = x² + y² минимум в (0, 0). Проверим, что градиент там обнуляется: именно по этому признаку оптимизация понимает, что «приехали».
def gradient(f, point, h=1e-5):
return [(f(*[p + (h if k == i else 0) for k, p in enumerate(point)])
- f(*[p - (h if k == i else 0) for k, p in enumerate(point)])) / (2 * h)
for i in range(len(point))]
def f(x, y): return x * x + y * y
print("Градиент в минимуме (0,0):", [round(v, 6) for v in gradient(f, [0, 0])])
print("Градиент в (1,1): ", [round(v, 4) for v in gradient(f, [1, 1])])
Вывод:
Градиент в минимуме (0,0): [0.0, 0.0] Градиент в (1,1): [2.0, 2.0]
Итог
- Частная производная — производная по одной переменной, остальные заморожены.
- Градиент — вектор всех частных производных; указывает направление наискорейшего роста.
- Против градиента — направление наискорейшего убывания (спуск к минимуму).
- В минимуме градиент нулевой — это сигнал «функция дальше не уменьшается».