Этот процесс позволяет сети с каждым шагом приближаться к решению задачи, становясь все более точной.


Примеры для разных типов градиентного спуска с использованием библиотеки PyTorch


Для каждого типа градиентного спуска мы решим простую задачу регрессии: предскажем значение (y) для каждого (x) по уравнению ( y = 2x + 3 ) с добавлением небольшого шума.


1. Обычный (Batch) Градиентный Спуск

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

```python

import torch

import torch.nn as nn

import torch.optim as optim

import numpy as np

import matplotlib.pyplot as plt

# Генерация данных

np.random.seed(0)

X = np.linspace(-1, 1, 100)

Y = 2 * X + 3 + 0.1 * np.random.randn(100)

# Преобразование в тензоры

X_tensor = torch.FloatTensor(X).view(-1, 1)

Y_tensor = torch.FloatTensor(Y).view(-1, 1)

# Простая линейная модель

model = nn.Linear(1, 1)

criterion = nn.MSELoss()

optimizer = optim.SGD(model.parameters(), lr=0.01)

# Обучение с использованием batch градиентного спуска

epochs = 1000

losses = []

for epoch in range(epochs):

optimizer.zero_grad()

predictions = model(X_tensor)

loss = criterion(predictions, Y_tensor)

loss.backward()

optimizer.step()

losses.append(loss.item())

# График ошибки

plt.plot(losses)

plt.xlabel("Epoch")

plt.ylabel("Loss")

plt.title("Batch Gradient Descent")

plt.show()

```

Пояснение: Модель обновляет веса, используя весь набор данных для каждого шага. Такой подход может быть более точным, но затратен по времени на больших данных.


2. Стохастический Градиентный Спуск (SGD)


Теперь каждый пример обновляет веса независимо, что делает обучение более быстрым, но и более "шумным".

```python

# Новая модель

model = nn.Linear(1, 1)

optimizer = optim.SGD(model.parameters(), lr=0.01)

# Обучение с использованием стохастического градиентного спуска

losses = []

for epoch in range(epochs):

for x, y in zip(X_tensor, Y_tensor):

optimizer.zero_grad()

prediction = model(x.view(-1, 1))

loss = criterion(prediction, y.view(-1, 1))

loss.backward()

optimizer.step()

losses.append(loss.item())

# График ошибки

plt.plot(losses)

plt.xlabel("Step")

plt.ylabel("Loss")

plt.title("Stochastic Gradient Descent")

plt.show()

```

Пояснение: В этом случае на каждом шаге градиентный спуск обновляет веса после каждого отдельного примера. Этот метод быстрее для больших данных, но ошибки "шумные" – кривая потерь будет менее сглаженной по сравнению с batch градиентным спуском.


3. Мини-Batch Градиентный Спуск


Данные разбиваются на небольшие группы (мини-батчи). Это компромисс между двумя подходами: сеть обновляется быстрее, чем в обычном batch, но при этом обновления более устойчивы, чем в SGD.

```python

# Новая модель

model = nn.Linear(1, 1)

optimizer = optim.SGD(model.parameters(), lr=0.01)

batch_size = 10 # Размер мини-батча

# Обучение с использованием мини-batch градиентного спуска

losses = []

for epoch in range(epochs):

permutation = torch.randperm(X_tensor.size()[0])

for i in range(0, X_tensor.size()[0], batch_size):

indices = permutation[i:i + batch_size]

batch_x, batch_y = X_tensor[indices], Y_tensor[indices]

optimizer.zero_grad()

predictions = model(batch_x)

loss = criterion(predictions, batch_y)

loss.backward()

optimizer.step()

losses.append(loss.item())

# График ошибки

plt.plot(losses)

plt.xlabel("Step")

plt.ylabel("Loss")

plt.title("Mini-Batch Gradient Descent")

plt.show()

```

Пояснение: Мини-batch градиентный спуск делит данные на небольшие части, например, по 10 примеров на батч. Это позволяет получить более сглаженный процесс обучения с эффективностью близкой к SGD.

Сравнение методов

Каждый метод имеет свои плюсы и минусы: