Ответ
Градиентный спуск — это итеративный алгоритм оптимизации первого порядка, используемый для нахождения локального минимума дифференцируемой функции. В контексте глубокого обучения и машинного обучения он применяется для минимизации функции потерь J(θ) путём обновления параметров модели θ.
Основная идея: На каждом шаге мы вычисляем градиент функции потерь относительно параметров. Градиент — это вектор, указывающий направление наискорейшего роста функции. Поэтому для минимизации мы делаем шаг в противоположном направлении.
Формула обновления (для параметра θ_i):
θ_i := θ_i - α * ∂J(θ) / ∂θ_i
где α — скорость обучения (learning rate), гиперпараметр, контролирующий размер шага.
Основные варианты алгоритма:
| Вариант | Описание | Плюсы | Минусы |
|---|---|---|---|
| Batch Gradient Descent | Вычисляет градиент по всему обучающему набору за одну итерацию. | Стабильное, детерминированное направление к минимуму. | Очень медленно на больших датасетах; требует всей памяти данных. |
| Stochastic Gradient Descent (SGD) | Вычисляет градиент и обновляет параметры для одного случайного примера за итерацию. | Быстрый; может выпрыгивать из локальных минимумов. | Сильно флуктуирует; сходимость может быть нестабильной. |
| Mini-batch Gradient Descent | Компромисс: вычисляет градиент по небольшой случайной подвыборке (mini-batch). | Более стабилен, чем SGD; использует аппаратное ускорение (векторизацию). | Требует настройки размера батча. |
Практический пример реализации Mini-batch SGD для линейной регрессии на NumPy:
import numpy as np
def mini_batch_gradient_descent(X, y, learning_rate=0.01, epochs=100, batch_size=32):
"""
X: матрица признаков (m samples, n features)
y: вектор целевых значений (m, )
"""
m, n = X.shape
theta = np.random.randn(n) # Инициализация параметров
for epoch in range(epochs):
# Перемешиваем данные в каждую эпоху
indices = np.random.permutation(m)
X_shuffled = X[indices]
y_shuffled = y[indices]
for i in range(0, m, batch_size):
X_batch = X_shuffled[i:i+batch_size]
y_batch = y_shuffled[i:i+batch_size]
# Вычисление градиента для батча
predictions = X_batch.dot(theta)
errors = predictions - y_batch
gradient = (2 / batch_size) * X_batch.T.dot(errors)
# Обновление параметров
theta -= learning_rate * gradient
# (Опционально) Мониторинг потерь
if epoch % 10 == 0:
loss = np.mean((X.dot(theta) - y) ** 2)
print(f"Epoch {epoch}, Loss: {loss:.4f}")
return theta
Критические аспекты для успеха:
- Скорость обучения (α): Слишком большая — алгоритм расходится; слишком малая — обучение происходит крайне медленно. Часто используют затухание (decay) или адаптивные методы (Adam, RMSprop).
- Инициализация параметров: Важна для сложных моделей (например, нейросетей). Используют методы Xavier/Glorot или He.
- Момент (Momentum): Техника, которая помогает ускорить сходимость и проходить мелкие локальные минимумы, добавляя инерцию от предыдущих обновлений градиента.