这里,我们不对每一个具体的优化算法做解释,只是对torch.optim
下的算法的使用方法以及有哪些属性做一下说明。
torch.optim
是一个实现了各种优化算法的库。大部分常用的方法得到支持,并且接口具备足够的通用性,使得未来能够集成更加复杂的方法。
为了使用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
也支持为每个参数单独设置选项。若想这么做,不要直接传入Variable
的iterable
,而是传入dict
的iterable
。每一个dict
都分别定义了一组参数,并且包含一个param
键,这个键对应参数的列表。其他的键应该optimizer
所接受的其他参数的关键字相匹配,并且会被用于对这组参数的优化。例如,当我们想指定每一层的学习率时,这是非常有用的:
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)
:
一些优化算法例如Conjugate Gradient
和LBFGS
需要重复多次计算函数,因此你需要传入一个闭包去允许它们重新计算你的模型。这个闭包应当清空梯度, 计算损失,然后返回。
for input, target in dataset:
def closure():
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward()
return loss
optimizer.step(closure)
optimizer
都有哪些属性.load_state_dict(state_dict)
:加载optimizer
的状态,state_dict
是一个状态字典,是.state_dict()
属性的返回值.state_dict()
:以dict
返回optimizer
的状态它包含两项:
state
- 一个保存了当前优化状态的dict。optimizer的类别不同,state的内容也会不同
param_groups
- 一个包含了全部参数组的dict
{'state': {},
'param_groups': [{'lr': 0.03, 'momentum': 0,
'dampening': 0, 'weight_decay': 0,
'nesterov': False,
'params': [2371287067888, 2371287067528]}]}
.step(closure)
:进行单次优化 (参数更新);closure (callable)
是一个重新评价模型并返回loss的闭包,对于大多数参数来说是可选的zero_grad()
:清空所有被优化过的Variable
的梯度