优化器
PyTorch常用的优化方法都封装在torch.optim里面,其设计很灵活,可以扩展为自定
义的优化方法。所有的优化方法都是继承了基类optim.Optimizer,并实现了自己的优化步
骤。最常用的优化算法就是梯度下降法及其各种变种,后续章节我们将介绍各种算法的原
理,这类优化算法通过使用参数的梯度值更新参数。
3.2节使用的随机梯度下降法(SGD)就是最普通的优化器,一般SGD并说没有加速
效果,3.2节使用的SGD包含动量参数Momentum,它是SGD的改良版。
我们结合3.2小结内容,说明使用优化器的一般步骤为:
(1)建立优化器实例
导入optim模块,实例化SGD优化器,这里使用动量参数momentum(该值一般在
(0,1)之间),是SGD的改进版,效果一般比不使用动量规则的要好。
python
import torch.optim as optim
optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)
以下步骤在训练模型的for循环中。
(2)向前传播
把输入数据传入神经网络Net实例化对象model中,自动执行forward函数,得到out输
出值,然后用out与标记label计算损失值loss。
python
out = model(img)
loss = criterion(out, label)
(3)清空梯度
缺省情况梯度是累加的,在梯度反向传播前,先需把梯度清零。
python
optimizer.zero_grad()
(4)反向传播
基于损失值,把梯度进行反向传播。
python
loss.backward()
(5)更新参数
基于当前梯度(存储在参数的.grad属性中)更新参数。
python
optimizer.step()
完整代码:
python
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
# ===== 1. 修复未定义变量 =====
# 定义模型 (示例: 简单CNN)
class SimpleCNN(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(3, 16, 3)
self.fc = nn.Linear(16 * 30 * 30, 10) # 假设输入32x32图像
def forward(self, x):
x = torch.relu(self.conv1(x))
x = x.view(x.size(0), -1)
return self.fc(x)
model = SimpleCNN() # [!修复model!]
# 定义超参数
EPOCHS = 100 # [!修复EPOCHS!]
LR = 0.01
MOMENTUM = 0.9 # 注意: 使用数值而非物理量
# 创建示例数据集 (实际应替换为真实数据)
dummy_imgs = torch.randn(1000, 3, 32, 32) # [!修复img数据源!]
dummy_labels = torch.randint(0, 10, (1000,)) # [!修复label数据源!]
dataset = TensorDataset(dummy_imgs, dummy_labels)
dataloader = DataLoader(dataset, batch_size=64, shuffle=True) # [!修复dataloader!]
criterion = nn.CrossEntropyLoss() # [!修复criterion!]
optimizer = optim.SGD(model.parameters(), lr=LR, momentum=MOMENTUM)
# ===== 2. 增强型训练循环 =====
for epoch in range(EPOCHS):
for batch in dataloader:
img, label = batch # [!解包获取img/label!]
# 前向传播
out = model(img)
loss = criterion(out, label)
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f'Epoch {epoch + 1}/{EPOCHS} | Loss: {loss.item():.4f}')