Это краткое руководство по настройке, работе и пониманию градиентного спуска.
Цель: минимизировать выпуклую функцию или максимизировать вогнутую функцию.
Шаги высокого уровня:
- Выберите функцию стоимости
- Вычислите первую производную (частные производные в некоторых случаях)
- Постепенно сходитесь к точке минимума. Простая интуиция, вогнутость можно представить как выпуклую функцию при переворачивании.
import random import numpy as np from sklearn import datasets
2D пример:
Задача: минимизировать функцию: f(x) = 5x + x².
theta = 3 learning_rate = .1 cost = lambda x: 5*x + x**2 derivative = lambda x: 5 + 2*(x**1) history = [ theta ] for iteration in range(25): theta = theta - ( learning_rate * derivative(theta) ) history.append(theta)
- используя 1-ю производную (наклон) от ( 5x + x² ) в сочетании со скоростью обучения, мы постепенно приближаемся к глобальному минимуму.
3D пример:
Задача: минимизация функции: f(a, b) = a² + b², ограничение между -10–10 для a и b.
theta = np.array([ -10, -10 ]) learning_rate = .01 cost = lambda X: np.sum(np.square(X)) derivative_x1 = lambda X: 2*X[0] + 0 derivative_x2 = lambda X: 0 + 2*X[1] history = [ theta ] for iteration in range(10000): derivatives = np.array([ learning_rate * derivative_x1(theta), learning_rate * derivative_x2(theta) ]) theta = theta - derivatives history.append(theta)
min: [-1.82287515e-87 -1.82287515e-87], что довольно близко к [ 0, 0 ].
Пример MSE:
Задача: 1/(m) * sum( ( y — y_hat )² ), где y_hat = m*X + b.
def cost (m, b, X, y): y_hat = (m*X + b) return np.mean( np.square( y - y_hat ) )
Теперь у нас есть два градиента, m и b, поэтому мы получаем две частные производные. Помните вышеизложенное, возьмите частную производную функции стоимости по m и сделайте то же самое для b.
X, y = datasets.make_regression() X = np.sum(X, axis=1) n = len(y) learning_rate = 0.001 ## initial gradient positions, np.random.seed(11) m_gradient = np.random.rand() b_gradient = np.random.rand() for iteration in range(2, 10): new_m_gradient = 0 new_b_gradient = 0 for i in range(n): x_i = X[i] y_i = y[i] y_hat = m_gradient*x_i + b_gradient new_m_gradient += ( (2/n) * (y_i - y_hat) * (-1) * x_i ) new_b_gradient += ( (2/n) * (y_i - y_hat) * (-1) ) b_gradient = b_gradient - (learning_rate * new_b_gradient) m_gradient = m_gradient - (learning_rate * new_m_gradient)
Полный блокнот можно найти здесь.