torch.optim
是一个实现了各种优化算法的库。
我们需要构建一个optimizer对象。这个对象能够保持当前参数状态并基于计算得到的梯度进行参数更新。
为了构建一个Optimizer
,你需要给它一个包含了需要优化的参数(必须都是Variable
对象)的iterable。然后,你可以设置optimizer的参 数选项,比如学习率,权重衰减,
等等。
例子:
optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9)
optimizer = optim.Adam([var1, var2], lr = 0.0001)
Optimizer
也支持为每个参数单独设置选项。此时,我们应该传入dict
的iterable。每一个dict都分别定义了一组参数,并且包含一个param
键,这个键对应参数的列表。
当你只想改动一个参数组的选项,但其他参数组的选项不变时,这是非常有用的。
例如,当我们想指定每一层的学习率时,
optim.SGD([
{'params': model.base.parameters()},
{'params': model.classifier.parameters(), 'lr': 1e-3}
], lr=1e-2, momentum=0.9)
这意味着model.base
的参数将会使用1e-2
的学习率,model.classifier
的参数将会使用1e-3
的学习率,并且0.9
的momentum将会被用于所有的参数。
所有的optimizer都实现了step()
方法,这个方法会更新所有的参数。它能按两种方式来使用:
1.optimizer.step()
这是大多数optimizer所支持的简化版本。一旦梯度被如backward()之类的函数计算好后,我们就可以调用这个函数。
例子:
for input, target in dataset:
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward()
optimizer.step()
2.optimizer.step(closure)
这个函数的用法没看懂,但用的也很少。
class torch.optim.Optimizer(params, defaults)
这是所有优化器的基类。
参数:
Variable
或者 dict
的iterable。指定了什么参数应当被优化。(1)load_state_dict(state_dict)
加载optimizer状态。
参数:
state_dict (dict
) —— optimizer的状态。应当是一个调用state_dict()
所返回的对象。
(2)state_dict()
以dict
返回optimizer的状态。
它包含两项。
state
- 一个保存了当前优化状态的dict。optimizer的类别不同,state的内容也会不同。
param_groups
- 一个包含了全部参数组的dict。
(3)step(closure)
进行单次优化 (参数更新)。
closure参数是可选的。
(4)zero_grad()
清空所有被优化过的Variable的梯度。
下面给出几个最常用的优化器。
class torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)[source]
参数:
class torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)[source]
参数:
class torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False)[source]
参数:
例子:
>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> optimizer.zero_grad()
>>> loss_fn(model(input), target).backward()
>>> optimizer.step()
torch.optim.lr_scheduler
提供了几种方法来根据 epoch 的数量调整学习率。
学习率调整应该在优化器更新后应用,比如:
model = [Parameter(torch.randn(2, 2, requires_grad=True))]
optimizer = SGD(model, 0.1)
scheduler = ExponentialLR(optimizer, gamma=0.9)
for epoch in range(20):
for input, target in dataset:
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward()
optimizer.step()
scheduler.step()
torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=- 1, verbose=False)
将每个参数组的学习率设置为初始 lr 乘以给定函数。当 last_epoch=-1
时,设置initial lr
为 lr。
l r e p o c h = l r i n i t i a l ∗ l r _ l a m b d a ( e p o c h ) lr_{epoch} =lr_{initial} * lr\_lambda(epoch) lrepoch=lrinitial∗lr_lambda(epoch)
# Assuming optimizer has two groups.
lambda1 = lambda epoch: epoch // 30
lambda2 = lambda epoch: 0.95 ** epoch
scheduler = LambdaLR(optimizer, lr_lambda=[lambda1, lambda2])
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
torch.optim.lr_scheduler.MultiplicativeLR(optimizer, lr_lambda, last_epoch=- 1, verbose=False)
将每个参数组的学习率乘以指定函数中给出的因子。 当 last_epoch=-1 时,设置初始 lr 为 lr。
l r e p o c h = l r e p o c h − 1 ∗ l r _ l a m b d a ( e p o c h ) lr_{epoch} =lr_{epoch - 1} * lr\_lambda(epoch) lrepoch=lrepoch−1∗lr_lambda(epoch)
lmbda = lambda epoch: 0.95
scheduler = MultiplicativeLR(optimizer, lr_lambda=lmbda)
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=- 1, verbose=False)
每 step_size epochs
衰减每个参数组的学习率。 请注意,这种衰减可能与此调度程序外部对学习率的其他更改同时发生。 当 last_epoch=-1 时,设置初始 lr 为 lr。
# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.05 if epoch < 30
# lr = 0.005 if 30 <= epoch < 60
# lr = 0.0005 if 60 <= epoch < 90
# ...
scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=- 1, verbose=False)
一旦 epoch 的数量达到milestones
之一,通过 gamma 衰减每个参数组的学习率。 请注意,这种衰减可能与此调度程序外部对学习率的其他更改同时发生。 当 last_epoch=-1 时,设置初始 lr 为 lr。
# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.05 if epoch < 30
# lr = 0.005 if 30 <= epoch < 80
# lr = 0.0005 if epoch >= 80
scheduler = MultiStepLR(optimizer, milestones=[30,80], gamma=0.1)
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
torch.optim.lr_scheduler.ConstantLR(optimizer, factor=0.3333333333333333, total_iters=5, last_epoch=- 1, verbose=False)
将每个参数组的学习率衰减一个小的常数因子,直到 epoch 的数量达到预定义的total_iters
。 请注意,这种衰减可能与此调度程序外部对学习率的其他更改同时发生。 当 last_epoch=-1 时,设置初始 lr 为 lr。
# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.025 if epoch == 0
# lr = 0.025 if epoch == 1
# lr = 0.025 if epoch == 2
# lr = 0.025 if epoch == 3
# lr = 0.05 if epoch >= 4
scheduler = ConstantLR(self.opt, factor=0.5, total_iters=4)
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
torch.optim.lr_scheduler.LinearLR(optimizer, start_factor=0.3333333333333333, end_factor=1.0, total_iters=5, last_epoch=- 1, verbose=False)
通过线性改变小的乘法因子来衰减每个参数组的学习率,直到 epoch 的数量达到预定义的total_iters。 请注意,这种衰减可能与此调度程序外部对学习率的其他更改同时发生。 当 last_epoch=-1 时,设置初始 lr 为 lr。
# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.025 if epoch == 0
# lr = 0.03125 if epoch == 1
# lr = 0.0375 if epoch == 2
# lr = 0.04375 if epoch == 3
# lr = 0.05 if epoch >= 4
scheduler = LinearLR(self.opt, start_factor=0.5, total_iters=4)
for epoch in range(100):
train(...)
validate(...)
scheduler.step()