目录
PyTorch优化器
当数据、模型和损失函数确定,任务的数学模型就已经确定,接着就要选择一个合适的优化器(Optimizer)对该模型进行优化。
本节将介绍 PyTorch 中优化器的方法(函数)和使用方法,下一小节将介绍 PyTorch 中十种不同的优化器。
优化器基类:Optimizer
优化器基类 Optimizer
PyTorch 中所有的优化器(如:optim.Adadelta、optim.SGD、optim.RMSprop 等)均是 Optimizer 的子类,Optimizer 中定义了一些常用的方法,有 zero_grad()、step(closure)、state_dict()、load_state_dict(state_dict)和add_param_group(param_group),本节将会一一介绍。
认识 Optimizer 的方法之前,需要了解一个概念,叫做参数组(param_groups)。在finetune,某层定制学习率,某层学习率置零操作中,都会设计参数组的概念,因此首先了解参数组的概念非常有必要。
optimizer 对参数的管理是基于组的概念,可以为每一组参数配置特定的 lr,momentum,weight_decay 等等。
参数组在 optimizer 中表现为一个 list(self.param_groups),其中每个元素是dict,表示一个参数及其相应配置,在 dict 中包含’params’、‘weight_decay’、‘lr’ 、'momentum’等字段。
import torch
import torch.optim as optim
w1 = torch.randn(2, 2)
w1.requires_grad = True
w2 = torch.randn(2, 2)
w2.requires_grad = True
w3 = torch.randn(2, 2)
w3.requires_grad = True
# 一个参数组
optimizer_1 = optim.SGD([w1, w3], lr=0.1)
print('len(optimizer.param_groups): ', len(optimizer_1.param_groups))
print(optimizer_1.param_groups, '\n')
# 两个参数组
optimizer_2 = optim.SGD([{'params': w1, 'lr': 0.1},
{'params': w2, 'lr': 0.001}])
print('len(optimizer.param_groups): ', len(optimizer_2.param_groups))
print(optimizer_2.param_groups)
输出:
len(optimizer.param_groups): 1
[{'params': [tensor([[ 1.1477, 0.2218],
[-0.1969, 0.7078]], requires_grad=True), tensor([[-0.0280, 0.7410],
[-0.3232, -1.6549]], requires_grad=True)], 'lr': 0.1, 'momentum': 0, 'dampening': 0, 'weight_decay': 0, 'nesterov': False}]
len(optimizer.param_groups): 2
[{'params': [tensor([[ 1.1477, 0.2218],
[-0.1969, 0.7078]], requires_grad=True)], 'lr': 0.1, 'momentum': 0, 'dampening': 0, 'weight_decay': 0, 'nesterov': False}, {'params': [tensor([[ 0.1914, -1.0996],
[-1.1645, 0.8719]], requires_grad=True)], 'lr': 0.001, 'momentum': 0, 'dampening': 0, 'weight_decay': 0, 'nesterov': False}]
PyTorch 的十个优化器
上一节,介绍了所有优化器的基类——Optimizer 类,在 Optimizer 类中定义了 5 个实用的基本方法,虽然了解了 Optimizer 类,但是还无法构建一个能优化网络的优化器。
在本小节中,将会介绍目 PyTorch 提供的十种优化器,有常见的 SGD、ASGD、Rprop、RMSprop、Adam 等等。这里都说的是优化器,并没有优化方法,因为 PyTorch 中给出的优化器与原始论文中提出的优化方法,多多少少有改动,详细还需看优化器源码。
1. torch.optim.SGD
class torch.optim.SGD(params, lr=<object object>, momentum=0, dampening=0, weight_decay=0, nesterov=False)
功能:
可实现 SGD 优化算法,带动量 SGD 优化算法,带 NAG(Nesterov accelerated gradient)动量 SGD 优化算法,并且均可拥有 weight_decay 项。
参数:
params(iterable)
参数组(参数组的概念请查看 3.2 优化器基类:Optimizer),优化器要管理的那部分参数。
lr(float)
初始学习率,可按需随着训练过程不断调整学习率。
momentum(float)
动量,通常设置为 0.9,0.8
dampening(float)
dampening for momentum ,暂时不了解其功能,在源码中是这样用的:buf.mul_(momentum).add_(1 - dampening, d_p),值得注意的是,若采用nesterov,dampening 必须为 0.
weight_decay(float)
权值衰减系数,也就是 L2 正则项的系数
nesterov(bool)
bool 选项,是否使用 NAG(Nesterov accelerated gradient)
注意事项:
pytroch 中使用 SGD 十分需要注意的是,更新公式与其他框架略有不同!
PyTorch 中是这样的:
v
=
ρ
∗
v
+
g
v=ρ ∗ v+g
v=ρ∗v+g
p
=
p
−
l
r
∗
v
=
p
−
l
r
∗
ρ
∗
v
−
l
r
∗
g
p=p−lr∗v = p - lr∗ρ ∗v - lr∗g
p=p−lr∗v=p−lr∗ρ∗v−lr∗g
其他框架:
v
=
ρ
∗
v
+
l
r
∗
g
v = ρ∗v + lr∗g
v=ρ∗v+lr∗g
p
=
p
−
v
=
p
−
ρ
∗
v
−
l
r
∗
g
p = p−v = p - ρ∗v - lr∗g
p=p−v=p−ρ∗v−lr∗g
ρ
ρ
ρ是动量,
v
v
v是速率,
g
g
g是梯度,
p
p
p是参数,其实差别就是在
ρ
∗
v
ρ∗v
ρ∗v 这一项,PyTorch中将此项也乘了一个学习率。
2. torch.optim.ASGD
class torch.optim.ASGD(params, lr=0.01, lambd=0.0001, alpha=0.75, t0=1000000.0, weight_decay=0)
功能:
ASGD 也称为SAG,表示随机平均梯度下降(Averaged Stochastic Gradient Descent),简单地说 ASGD 就是用空间换时间的一种 SGD,详细可参看论文:http://riejohnson.com/rie/stograd_nips.pdf
参数:
params(iterable)
参数组(参数组的概念请查看 3.1 优化器基类: Optimizer),优化器要优化的那些参数。
lr(float)
初始学习率,可按需随着训练过程不断调整学习率。
lambd(float)
衰减项,默认值 1e-4。
alpha(float)
power for eta update ,默认值 0.75。
t0(float)
point at which to start averaging,默认值 1e6。
weight_decay(float)
权值衰减系数,也就是 L2 正则项的系数。
3. torch.optim.Rprop
class torch.optim.Rprop(params, lr=0.01, etas=(0.5, 1.2), step_sizes=(1e-06, 50))
功能:
实现 Rprop 优化方法(弹性反向传播),优化方法原文《Martin Riedmiller und Heinrich Braun: Rprop - A Fast Adaptive Learning Algorithm. Proceedings of the International Symposium on Computer and Information Science VII, 1992》 该优化方法适用于 full-batch,不适用于 mini-batch,因而在 mini-batch 大行其道的时代里,很少见到。
4. torch.optim.Adagrad
class torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0, initial_accumulator_value=0)
功能:
实现 Adagrad 优化方法(Adaptive Gradient), Adagrad 是一种自适应优化方法,是自适应的为各个参数分配不同的学习率。这个学习率的变化,会受到梯度的大小和迭代次数的影响。梯度越大,学习率越小;梯度越小,学习率越大。缺点是训练后期,学习率过小,因为 Adagrad 累加之前所有的梯度平方作为分母。
详细公式请阅读: Adaptive Subgradient Methods for Online Learning and
Stochastic Optimization John Duchi, Elad Hazan, Yoram Singer; 12(Jul):2121−2159,
2011.
5. torch.optim.Adadelta
class torch.optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-06, weight_decay=0)
功能:
实现 Adadelta 优化方法。 Adadelta 是 Adagrad 的改进。 Adadelta 分母中采用距离当前时间点比较近的累计项,这可以避免在训练后期,学习率过小。详细公式请阅读:https://arxiv.org/pdf/1212.5701.pdf
6. torch.optim.RMSprop .
class torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)
功能:
实现 RMSprop 优化方法( Hinton 提出), RMS 是均方根( root meam square)的意思。 RMSprop 和 Adadelta 一样,也是对 Adagrad 的一种改进。 RMSprop 采用均方根作为分母,可缓解 Adagrad 学习率下降较快的问题, 并且引入均方根,可以减少摆动,详细了解可读: http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf
7. torch.optim.Adam(AMSGrad) .
class torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)
功能:
实现 Adam(Adaptive Moment Estimation))优化方法。 Adam 是一种自适应学习率的优化方法, Adam 利用梯度的一阶矩估计和二阶矩估计动态的调整学习率。吴老师课上说过,Adam 是结合了 Momentum 和 RMSprop,并进行了偏差修正。
参数:
amsgrad
是否采用 AMSGrad 优化方法, asmgrad 优化方法是针对 Adam 的改进,通过添加额外的约束,使学习率始终为正值。 (AMSGrad, ICLR-2018 Best-Pper 之一,《On the convergence of Adam and Beyond》 )。详细了解 Adam 可阅读,Adam: A Method for Stochastic Optimization。
8. torch.optim.Adamax
class torch.optim.Adamax(params, lr=0.002, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)
功能:
实现 Adamax 优化方法。 Adamax 是对 Adam 增加了一个学习率上限的概念,所以也称之为 Adamax。详细了解可阅读, Adam: A Method for Stochastic Optimization(没错,就是 Adam 论文中提出了Adamax)。
9. torch.optim.SparseAdam
class torch.optim.SparseAdam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08)
功能:
针对稀疏张量的一种“ 阉割版”Adam 优化方法。
- only moments that show up in the gradient get updated, and only those
portions of the gradient get applied to the parameters
10.torch.optim.LBFGS
class torch.optim.LBFGS(params, lr=1, max_iter=20, max_eval=None, tolerance_
grad=1e-05, tolerance_change=1e-09, history_size=100, line_search_fn=None)
功能:
实现 L-BFGS( Limited-memory Broyden– Fletcher– Goldfarb– Shanno)优化方法。L-BFGS 属于拟牛顿算法。 L-BFGS 是对 BFGS 的改进,特点就是节省内存。
注意事项:
- This optimizer doesn’t support per-parameter options and parameter groups
(there can be only one). - Right now all parameters have to be on a single device. This will be
improved in the future.(2018-10-07)
参考材料
https://github.com/tensor-yu/PyTorch_Tutorial/tree/master/Data