优化器

常见的优化器

SGD

随机梯度下降,基本的优化算法,它通过计算每个参数的梯度来更新参数。

我们可以使用SGD实现对所有样本的梯度下降、小批量梯度下降或者单样本的随机梯度下降。

1
torch.optim.SGD(params, lr, momentum=0, dampening=0, weight_decay=0, nesterov=False)
  • params:要优化的参数的迭代器或列表
  • lr:学习率,必须指定,没有默认值
  • momentum:动量因子,用于加速梯度下降的过程,比如momentum=0.9
  • dampening:动量的阻尼系数,用于控制动量的影响。当dampening非零时,会减少动量的累积效应
  • weight_decay:权重衰减(L2惩罚),用于正则化,防止模型过拟合
  • nesterov:是否使用Nesterov动量,默认值为FalseNesterov动量是一种改进的动量方法,它在计算梯度时考虑了未来的位置

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import torch
import torch.optim as optim
import torch.nn as nn

model = nn.Linear(10, 1)

dataloader = ...

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

num_epochs = 10

for epoch in range(num_epochs):
for X, y in dataloader:
y_hat = model(X)
loss = loss_function(y_hat, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()

Adam

optim.Adam 是 PyTorch 中提供的一种自适应矩估计(Adaptive Moment Estimation,简称 Adam)优化器

1
torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)

优化器的使用

定义好优化器后,我们可以使用zero_grad()方法将优化器中需要优化的参数的梯度全部变为零,这样做的目的是防止梯度累积

如果要对参数进行梯度下降的优化,使用step()方法,

比如,实现一个Softmax回归:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

class SoftmaxRegression(nn.Module):
def __init__(self, num_input, num_output):
super().__init__()
self.flatten = nn.Flatten()
self.linear1 = nn.Linear(num_input, 100)
self.linear2 = nn.Linear(100, num_output)

def forward(self, x):
x = self.flatten(x)
x = self.linear1(x)
x = F.relu(x)
x = self.linear2(x)
return x

def accuracy(data_iter, model):
right_number = 0
number = 0
for X, y in data_iter:
y_hat = model(X).argmax(dim=1)
right_number += (y_hat == y).sum().item()
number += len(y)
return right_number / number

# 加载数据集
batch_size = 128
train_data = datasets.FashionMNIST(root='./data', transform=transforms.ToTensor(), train=True, download=False)
test_data = datasets.FashionMNIST(root='./data', transform=transforms.ToTensor(), train=False, download=False)
train_iter = DataLoader(dataset=train_data, shuffle=True, batch_size=batch_size, num_workers=4)
test_iter = DataLoader(dataset=test_data, shuffle=False, batch_size=batch_size, num_workers=4)

# 定义模型和损失函数
num_input = 28*28
num_output = 10
loss_function = nn.CrossEntropyLoss()
model = SoftmaxRegression(num_input, num_output)

# 定义优化器
lr = 0.01
optimizer = optim.SGD(model.parameters(), lr=lr)

# 训练
num_epochs = 5
for epoch in range(num_epochs):
for X, y in train_iter:
y_hat = model(X)
loss = loss_function(y_hat, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()

with torch.no_grad():
acc = accuracy(test_iter, model)
print(f'epoch {epoch + 1}, Test Accuracy {(acc*100):2f}%')

给不同的层设置不同的学习率等参数

除了上述的参数传入方式外,pytorch的optim还支持以字典的形式传入参数,如果对不同的层想设置不同的参数,可以使用列表的格式分开,列表中的元素为不同层参数字典。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F

class Net(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Linear(10, 20)
self.layer2 = nn.Linear(20, 30)
self.layer3 = nn.Linear(30, 1)

def forward(self, x):
x = F.relu(self.layer1(x))
x = F.relu(self.layer2(x))
x = self.layer3(x)
return x

model = Net()

# 将每个层的参数展开成一个Tensor列表,然后再传递给优化器
params_1 = list(model.layer1.parameters()) + list(model.layer2.parameters())
params_2 = model.layer3.parameters()

# optimizer只能优化Tensor类型的参数,只能传入model.parameters()类型迭代器或者多个Tensor构成的列表
optimizer = optim.SGD([
{'params': params_1, 'lr': 0.01},
{'params': params_2, 'lr':0.02, 'weight_decay': 0.001, 'momentum': 0.9}
])

print(optimizer)

输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SGD (
Parameter Group 0
dampening: 0
differentiable: False
foreach: None
lr: 0.01
maximize: False
momentum: 0
nesterov: False
weight_decay: 0

Parameter Group 1
dampening: 0
differentiable: False
foreach: None
lr: 0.02
maximize: False
momentum: 0.9
nesterov: False
weight_decay: 0.001
)

优化器
https://blog.shinebook.net/2025/03/02/人工智能/pytorch/优化器/
作者
X
发布于
2025年3月2日
许可协议