Название | Нейросети: создание и оптимизация будущего |
---|---|
Автор произведения | Джеймс Девис |
Жанр | |
Серия | |
Издательство | |
Год выпуска | 2025 |
isbn |
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.
Сравнение методов
Каждый метод имеет свои плюсы и минусы:
– Batch Gradient Descent: высокая точность, но требует много вычислительных ресурсов и неэффективен для больших данных.
– Stochastic Gradient Descent: быстрое обновление весов, но кривая ошибки "шумная".
– Mini-Batch Gradient Descent: компромисс между точностью и скоростью, подходит для больших данных.
Для больших наборов данных чаще используется Mini-Batch