Джеймс Дэвис – Нейросети: создание и оптимизация будущего (страница 20)
```
Объяснение:
1. Нейронная сеть:
– Мы используем ту же простую сеть `SimpleNet`, которая состоит из двух полносвязных слоев: один преобразует изображение в 128 признаков, а другой – в 10 классов для классификации.
2. Стохастический градиентный спуск (SGD):
– В `train_loader` установлен параметр `batch_size=1`, что означает, что обновление весов будет происходить после обработки каждого изображения (каждого примера). Это и есть стоходастический градиентный спуск.
3. Процесс обучения:
– Каждый пример (изображение) по очереди пропускается через модель, вычисляются потери и веса обновляются сразу после каждого примера. Это делает процесс обучения быстрым, но при этом обновления могут быть менее стабильными, так как каждый новый пример вносит шум и может изменять направление обучения.
Преимущества и недостатки стохастического градиентного спуска:
– Преимущество: Обучение происходит быстрее, так как модель обновляет веса после каждого примера. Кроме того, этот метод помогает избежать застревания в локальных минимумах, так как шум от каждого примера может помочь сети найти лучшие решения.
– Недостаток: Путь к минимизации может быть менее стабильным, так как каждый шаг зависит от одного примера и может приводить к колебаниям в процессе обучения. Это делает модель менее предсказуемой, и процесс обучения может «дрожать".
3. Мини-батч градиентный спуск:
– Этот метод является компромиссом между пакетным и стохастическим подходами. Мы делим данные на небольшие группы (батчи), обрабатываем каждую группу и обновляем веса после каждой.
– Этот способ стабилен и достаточно эффективен, так как позволяет использовать мощности GPU и в то же время дает более точное направление спуска.
Пример использования мини-батч градиентного спуска (Mini-Batch Gradient Descent) в PyTorch. В этом примере мы делим данные на небольшие группы (батчи) и обновляем веса после обработки каждой группы. Этот подход стабилен, эффективен и идеально подходит для использования на GPU.
Предположим, у нас та же задача классификации изображений из набора данных MNIST, но теперь мы будем использовать батчи.
```python
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
# Определяем простую нейронную сеть
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
self.fc1 = nn.Linear(28*28, 128) # Первый полносвязный слой
self.fc2 = nn.Linear(128, 10) # Второй слой для классификации (10 классов)
def forward(self, x):
x = x.view(-1, 28*28) # Преобразуем изображение в одномерный вектор
x = torch.relu(self.fc1(x)) # Применяем ReLU активацию
x = self.fc2(x) # Выходной слой
return x
# Загружаем данные MNIST
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
train_data = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
train_loader = DataLoader(train_data, batch_size=64, shuffle=True) # Мини-батч градиентный спуск (batch size = 64)
# Создаем модель, функцию потерь и оптимизатор
model = SimpleNet()
criterion = nn.CrossEntropyLoss() # Функция потерь для многоклассовой классификации
optimizer = optim.SGD(model.parameters(), lr=0.01) # Стохастический градиентный спуск
# Обучение
epochs = 1 # Одно обучение (можно увеличить количество эпох)
for epoch in range(epochs):
for data, target in train_loader: # Для каждого мини-батча
optimizer.zero_grad() # Обнуляем градиенты перед вычислением новых
output = model(data) # Прямой проход
loss = criterion(output, target) # Вычисляем потери
loss.backward() # Обратное распространение ошибок
optimizer.step() # Обновляем веса
print(f'Эпоха {epoch+1}, Потери: {loss.item()}')
# Пример завершения обучения
print("Обучение завершено.")
```
Объяснение:
1. Нейронная сеть:
– Мы снова используем простую нейронную сеть `SimpleNet`, состоящую из двух полносвязных слоев.
2. Мини-батч градиентный спуск:
– В `train_loader` установлен параметр `batch_size=64`, что означает, что данные делятся на батчи по 64 примера. Мы обновляем веса после обработки каждого батча данных.
– Этот подход является компромиссом между пакетным (где обрабатываются все данные за один шаг) и стоходастическим (где обновление происходит после каждого примера) градиентным спуском. В мини-батче данные обработаны быстрее и стабильнее, чем в чисто стохастическом подходе.
3. Процесс обучения:
– Для каждого батча (по 64 примера) выполняется прямой проход через модель, вычисляются потери, а затем обновляются веса. Этот процесс повторяется для каждого батча в течение эпохи.
Преимущества мини-батч градиентного спуска:
– Стабильность: В отличие от стохастического градиентного спуска, где обновления могут сильно колебаться, мини-батчи приводят к более стабильному обучению.
– Эффективность: Этот метод хорошо работает с большими наборами данных и позволяет эффективно использовать ресурсы GPU.