与优化函数相关的部分在torch.optim
模块中,其中包含了大部分现在已有的流行的优化方法。
Optimizer
要想使用optimizer,需要创建一个optimizer 对象,这个对象会保存当前状态,并根据梯度更新参数。
Optimizer
要构造一个Optimizer
,需要使用一个用来包含所有参数(Tensor
形式)的iterable,把相关参数(如learning rate、weight decay等)装进去。
注意,如果想要使用.cuda()
方法来将model移到GPU中,一定要确保这一步在构造Optimizer
之前。因为调用.cuda()
之后,model里面的参数已经不是之前的参数了。
示例代码如下:
optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum = 0.9)
optimizer = optim.Adam([var1, var2], lr = 0.0001)
last_epoch
代表上一次的epoch的值,初始值为-1。
也可以用一个dict的iterable指定参数。这里的每个dict都必须要params
这个key,params
包含它所属的参数列表。除此之外的key必须它的Optimizer
(如SGD
)里面有的参数。
You can still pass options as keyword arguments. They will be used as defaults, in the groups that didn’t override them. This is useful when you only want to vary a single option, while keeping all others consistent between parameter groups.
这在针对特定部分进行操作时很有用。比如只希望给指定的几个层单独设置学习率:
optim.SGD([
{'params': model.base.parameters()},
{'params': model.classifier.parameters(), 'lr': 0.001}
],
lr = 0.01, momentum = 0.9)
在上面这段代码中model.base
将会使用默认学习率0.01,而model.classifier
的参数蒋欢使用0.001的学习率。
所有optimizer都实现了step()
方法,调用这个方法可以更新参数,这个方法有以下两种使用方法:
optimizer.step()
多数optimizer里都可以这么做,每次用backward()
这类的方法计算出了梯度后,就可以调用一次这个方法来更新参数。
示例程序:
for input, target in dataset:
optimizer.zero_grad()
ouput = model(input)
loss = loss_fn(output, target)
loss.backward()
optimizer.step()
optimizer.step(closure)
有些优化算法会多次重新计算函数(比如Conjugate Gradient、LBFGS),这样的话你就要使用一个闭包(closure)来支持多次计算model的操作。这个closure的运行过程是,清除梯度,计算loss,返回loss。
(这个我不太理解,因为这些优化算法不熟悉)
示例程序:
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)
这里就不完整介绍documentation中的内容了,只介绍基类。具体的算法的参数需要理解它们的原理才能明白,这个改天单独来一篇文章介绍。
class torch.optim.Optimizer(params, defaults)
这是所有optimizer的基类。
注意,各参数的顺序必须保证每次运行都一致。有些数据结构就不满足这个条件,比如dictionary的iterator和set。
params
(iterable)是torch.Tensor
或者dict
的iterable。这个参数指定了需要更新的Tensor。defaults
(dict)是一个dict,它包含了默认的的优化选项。add_param_group(param_group)
这个方法的作用是增加一个参数组,在fine tuning一个预训练的网络时有用。
load_state_dict(state_dict)
这个方法的作用是加载optimizer的状态。
state_dict()
获取一个optimizer的状态(一个dict)。
zero_grad()
方法用于清空梯度。
step(closure)
用于进行单次更新。
class torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)