How to choose optimizer ?训练时,如何选择优化器?

 站在巨人的肩膀上肩膀左肩膀右+1+2+3+4


当学习神经网络到一定程度时,不难发现优化器和损失函数是神经网络模型不可缺少的部分。

优化器Optimizer


目录

1 优化器Optimizer

2 优化器调用及相关参数

3 优化方法

3.1 SGD算法——随机梯度下降方法

3.2 ASGD算法——平均随机梯度下降算法

3.3 Adagrad算法

3.4 Adadelta算法——自适应学习率调整

3.5 RMSprop算法

3.6 Adam算法——自适应矩估计

3.7 Adamax算法——Adam的无穷范数变种

3.8 SparseAdam算法

3.9 L-BFGS算法

3.10 Rprop算法——弹性反向传播算法

4 重要优化函数的动态图 

4.1 损失平面等高线

4.2 在鞍点处的比较


1 优化器Optimizer

求解神经网络,也就是求解 y =f(wx + b) 中的w 和 b。

如:何找到正确的权重值 w 和 b 呢?

方法1:随机搜索

  • 需要很多权重值,随机采样,然后把它们输入损失函数,再看它们效果如何。

方法2:梯度下降算法

  • 首先,初始化 w 和 b, 然后,使用梯度下降算法,对 w 和 b 进行更新。
  • 估值和真值间存在误差通过loss函数可以得到结果,优化器则考虑将损失值传递到网络的前端,最终目的是达到一个训练学习的目的。
  • 所有的优化函数都位于torch.optim包下,常用的优化器SGD、Adam、Adadelta、Adagrad、Adamax等,后续详细介绍。

2 优化器调用及相关参数

2.1 以SGD、Adam为例

optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9)
optimizer = optim.Adam([var1, var2], lr = 0.0001)
# lr:学习率,大于0的浮点数
# momentum:动量参数,大于0的浮点数
# parameters:Variable参数,要优化的对象

2.2  torch.optim包下调用,同时指定优化的参数

torch.optim.Optimizer(params, defaults)
# params (iterable) —— Variable 或者 dict的iterable。指定了什么参数应当被优化。
# defaults —— (dict):包含了优化选项默认值的字典(一个参数组没有指定的参数选项将会使用默认值)。

2.3  优化器调用过程

load_state_dict(state_dict):加载optimizer状态。
state_dict():以dict返回optimizer的状态。包含两项:state - 一个保存了当前优化状态的dict,param_groups - 一个包含了全部参数组的dict。
add_param_group(param_group):给 optimizer 管理的参数组中增加一组参数,可为该组参数定制 lr,momentum, weight_decay 等,在 finetune 中常用。
step(closure) :进行单次优化 (参数更新)。
zero_grad() :清空所有被优化过的Variable的梯度。

3 优化方法

3.1 SGD算法——随机梯度下降方法

g_{t} = \triangledown _{\theta _{t-1}}f(\theta _{t-1})

\triangle \theta _{t} = -\eta *g_{t}       
其中, \eta是学习率,g_{t}是梯度

torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False)

params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float) – 学习率
momentum (float, 可选) – 动量因子(默认:0)
weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认:0)
dampening (float, 可选) – 动量的抑制因子(默认:0)
nesterov (bool, 可选) – 使用Nesterov动量(默认:False)
  • 实质:
    • SGD表示min-batch gradient descent。
    • SGD就是每一次迭代计算mini-batch的梯度,然后对参数进行更新,是常见的优化方法之一。SGD完全依赖于当前batch的梯度,所以η(学习率)可理解为允许当前batch的梯度多大程度影响参数更新。
  • 优点:
    • 训练速度快,避免了批量梯度更新过程中的计算冗余问题,对于很大的数据集,也能够以较快的速度收敛.
  • 缺点:
    • SGD优化方向不一定是全局最优的,容易收敛到局部最优。在某些情况下可能被困在鞍点【但是在合适的初始化和学习率设置下,鞍点的影响其实没这么大】
    • 选择合适的learning rate比较困难
    • 对所有的参数更新使用同样的learning rate。对于稀疏数据或者特征,有时我们可能想更新快一些对于不经常出现的特征,对于常出现的特征更新慢一些,这时候SGD就不太能满足要求了。
    • 因为误差,所以每一次迭代的梯度受抽样的影响比较大,也就是说梯度含有比较大的噪声,不能很好的反映真实梯度。
    • SGD有较高的方差,其波动较大。

3.2 ASGD算法——平均随机梯度下降算法

torch.optim.ASGD(params, lr=0.01, lambd=0.0001, alpha=0.75, t0=1000000.0, weight_decay=0)

params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float, 可选) – 学习率(默认:1e-2)
lambd (float, 可选) – 衰减项(默认:1e-4)
alpha (float, 可选) – eta更新的指数(默认:0.75)
t0 (float, 可选) – 指明在哪一次开始平均化(默认:1e6)
weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)
  • 实质:ASGD 就是用空间换时间的一种 SGD。

3.3 Adagrad算法

n_{t} = n_{t-1} +g_{t}^{2}

\triangle\theta _{t}=-\frac{\eta }{\sqrt{n_{t}+\varepsilon }}*g_{t}

g_{t}从1到进行一个递推形成一个约束项regularizer:-\frac{1}{\sum_{r=1}^{t}(g_{r})^2+\varepsilon }\varepsilon保证分母非0。

torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0)

params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float, 可选) – 学习率(默认: 1e-2)
lr_decay (float, 可选) – 学习率衰减(默认: 0)
weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)
  • 实质:
    • Adagrad算法就是将每一个参数的每一次迭代的梯度取平方累加后在开方,用全局学习率除以这个数,作为学习率的动态更新,即对学习率的一种约束。
  • 核心思想:
    • 对于频繁出现的参数使用更小的更新速率,对于不频繁出现的参数使用更大的更新速率。正因为如此,该优化函数脚适用于稀疏的数据,比如在Google从YouTube视频上识别猫时,该优化函数大大提升了SGD的鲁棒性。在训练GloVe词向量时该优化函数更加适用。
  • 特点:
    • 前期g_{t}t较小的时候, regularizer较大,能够放大梯度
    • 后期g_{t}较大的时候,regularizer较小,能够约束梯度
    • 适合处理稀疏梯度
  • 优点:
    • Adagrad 是一种自适应优化方法,是自适应的为各个参数分配不同的学习率。
    • 学习率的变化,会受到梯度的大小和迭代次数的影响。梯度越大,学习率越小;梯度越小,学习率越大。
  • 缺点:
    • 缺点是训练后期,学习率过小,因为 Adagrad 累加之前所有的梯度平方作为分母。随着算法不断迭代,r会越来越大,整体的学习率会越来越小。所以,一般来说AdaGrad算法一开始是激励收敛,到了后面就慢慢变成惩罚收敛,速度越来越慢。
    • 由公式可以看出,仍依赖于人工设置一个全局学习率。η设置过大的话,会使regularizer过于敏感,对梯度的调节太大。中后期,分母上梯度平方的累加将会越来越大,使gradient→0gradient→0,使得训练提前结束。
    • 经验表明,在普通算法中也许效果不错,但在深度学习中,深度过深时会造成训练提前结束。因为它到后面的衰减可能越来越慢,然后就提前结束了。为了解决提前结束的问题,引入了如下的算法:Adadelta!RMSprop!

3.4 Adadelta算法——自适应学习率调整

n_{t} =\upsilon * n_{t-1} +\left ( 1-\nu \right )*g_{t}^{2}

\triangle\theta _{t}=-\frac{\eta }{\sqrt{n_{t}+\varepsilon }}*g_{t}     

Adadelta还是依赖于全局学习,经过近似牛顿迭代法计算对应的平均值:

E|g^{2}|_{t} =\rho *E|g^{2}|_{t-1} +\left ( 1-\rho \right )*g_{t}^{2}

\triangle x_{t}=-\frac{\sqrt{\sum_{r= 1}^{t-1}\triangle x_{r} } }{\sqrt{E| g^{2}|_{t} +\varepsilon }}

E表示期望,此时Adadelta不再依赖于全局学习率。

torch.optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-06, weight_decay=0)

params (iterable) :待优化参数的iterable或者是定义了参数组的dict
rho (float, 可选) : 用于计算平方梯度的运行平均值的系数(默认:0.9)
eps (float, 可选): 为了增加数值计算的稳定性而加到分母里的项(默认:1e-6)
lr (float, 可选): 在delta被应用到参数更新之前对它缩放的系数(默认:1.0)
weight_decay (float, 可选) :权重衰减(L2惩罚)(默认: 0)
  • Adadelta是对Adagrad的扩展,主要针对三个问题
    • 学习率后期非常小的问题;
    • 手工设置初始学习率;
    • 更新xt时,两边单位不统一
  • 实质
    • 最初方案依然是对学习率进行自适应约束,但是进行了计算上的简化。
    • 不同于adagrad将以前所有的偏导都累加起来,adadelta控制了累加的范围到一定的窗口中。但是,并非简单的将窗口大小设置并且存储,而是通过下式动态改变的上述的参数。也就是说,Adagrad会累加之前所有的梯度平方,而Adadelta只累加固定大小的项,并且也不直接存储这些项,仅仅是近似计算对应的平均值。
  • 效果
    • 训练初中期,加速效果不错,很快
    • 训练后期,反复在局部最小值附近抖动

3.5 RMSprop算法

当 \rho = 0.5时,下式变为求梯度平方和的平均数: E|g^{2}|_{t} =\rho *E|g^{2}|_{t-1} +\left ( 1-\rho \right )*g_{t}^{2}

再求根,就变成了RMS(均方根):RMS|g|_{t} =\sqrt{E|g^{2}|_{t} +\varepsilon }

此时,RMS就可以作为学习率的一个约束:\triangle x_{t}=-\frac{\eta }{RMS{| g|_{t} }}*g_{t}

torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)

params (iterable) :待优化参数的iterable或者是定义了参数组的dict
lr (float, 可选) :学习率(默认:1e-2)
momentum (float, 可选) : 动量因子(默认:0)
alpha (float, 可选) : 平滑常数(默认:0.99)
eps (float, 可选) : 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
centered (bool, 可选):如果为True,计算中心化的RMSProp,并且用它的方差预测值对梯度进行归一化
weight_decay (float, 可选):权重衰减(L2惩罚)(默认: 0)
  • 实质:RMSprop是Adagrad的一种发展、Adadelta的变体,效果趋于二者之间。RMSprop 采用均方根作为分母,可缓解 Adagrad 学习率下降较快的问题, 并且引入均方根,可以减少摆动。
  • 优点:
    • 相比于AdaGrad,这种方法很好的解决了深度学习中过早结束的问题。
    • 适合处理非平稳目标,对于RNN效果很好。
  • 缺点:
    • 引入了新的超参,衰减系数ρ。
    • 依然依赖于全局学习速率。

3.6 Adam算法——自适应矩估计

m_{t} =\mu *m_{t-1} +\left ( 1-\mu \right )*g_{t}

n_{t} =\upsilon * n_{t-1} +\left ( 1-\nu \right )*g_{t}^{2}

\widehat{m}_{t}=\frac{m_{t}}{1-\mu ^{t}}

\widehat{n}_{t}=\frac{n_{t}}{1-\nu ^{t}}

\triangle \theta _{t} = -\frac{\widehat{m}_{t}}{\sqrt{\widehat{n}_{t}}+\varepsilon }*\eta

其中, m_{t}n_{t}分别是对梯度的一阶矩估计和二阶矩估计,可以看作对期望E|g_{t}|E|g_{t}^2|的估计;\widehat{m}_{t}\widehat{n}_{t}是对{m}_{t}{n}_{t}的校正,这样可以近似为对期望的无偏估计。
可以看出,直接对梯度的矩估计对内存没有额外的要求,而且可以根据梯度进行动态调整,而-\frac{\widehat{m}_{t}}{\sqrt{\widehat{n}_{t}}+\varepsilon }对学习率形成一个动态约束,而且有明确的范围。

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

arams (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float, 可选) – 学习率(默认:1e-3)
betas (Tuple[float, float], 可选) – 用于计算梯度以及梯度平方的运行平均值的系数(默认:0.9,0.999)
eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)
  • 实质:
    • Adam(Adaptive Moment Estimation)是另外一种给每个参数计算不同更新速率的方法,其本质上是带有动量项的RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。
  • 优点:
    • 经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。
    • 存储了以前的偏导平方衰减平均值,此外,还存储以前的偏导衰减平均值。
    • Adam结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点。 
    • 对内存需求较小,为不同的参数计算不同的自适应学习率,也适用于大多非凸优化,适用于大数据集和高维空间。

3.7 Adamax算法——Adam的无穷范数变种

n_{t} =max(\upsilon * n_{t-1}, |g_{t}|)

\triangle x = -\frac{\widehat{m}_{t}}{\sqrt{​{n}_{t}}+\varepsilon }*\eta

torch.optim.Adamax(params, lr=0.002, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)

params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float, 可选) – 学习率(默认:2e-3)
betas (Tuple[float, float], 可选) – 用于计算梯度以及梯度平方的运行平均值的系数
eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)
  • 实质:
    • Adamax 是对 Adam 增加了一个学习率上限的概念,所以也称之为 Adamax。
  • 优点:
    • Adamax是Adam的一种变体,此方法对学习率的上限提供了一个更简单的范围。
    • Adamax学习率的边界范围更简单。 

3.8 SparseAdam算法

torch.optim.SparseAdam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08)

params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float, 可选) – 学习率(默认:2e-3)
betas (Tuple[float, float], 可选) – 用于计算梯度以及梯度平方的运行平均值的系数
eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
  • 实质:
    • 针对稀疏张量的一种“阉割版”Adam 优化方法。 

3.9 L-BFGS算法

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)

lr (float) – 学习率(默认:1)
max_iter (int) – 每一步优化的最大迭代次数(默认:20))
max_eval (int) – 每一步优化的最大函数评价次数(默认:max * 1.25)
tolerance_grad (float) – 一阶最优的终止容忍度(默认:1e-5)
tolerance_change (float) – 在函数值/参数变化量上的终止容忍度(默认:1e-9)
history_size (int) – 更新历史的大小(默认:100)
  • 实质:
    • ​​​​​​​L-BFGS 属于拟牛顿算法。 L-BFGS 是对 BFGS 的改进,特点就是节省内存。 

3.10 Rprop算法——弹性反向传播算法

torch.optim.Rprop(params, lr=0.01, etas=(0.5, 1.2), step_sizes=(1e-06, 50))

params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float, 可选) – 学习率(默认:1e-2)
etas (Tuple[float, float], 可选) – 一对(etaminus,etaplis), 它们分别是乘法的增加和减小的因子(默认:0.5,1.2)
step_sizes (Tuple[float, float], 可选) – 允许的一对最小和最大的步长(默认:1e-6,50)
  • 不推荐:该优化方法适用于 full-batch,不适用于 mini-batch。​​​​​​​

4 重要优化函数的动态图 

4.1 损失平面等高线

4.2 在鞍点处的比较

 

  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MengYa_DreamZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值