深度学习之:优化器 (optimizer)

深度学习之:优化器 (optimizer)


        我们知道,越复杂的神经网络 , 越多的数据 , 需要在训练神经网络的过程上花费的时间也就越多. 原因很简单, 就是因为计算量太大了. 可是往往有时候为了解决复杂的问题, 复杂的结构和大数据又是不能避免的, 所以我们需要寻找一些方法, 让神经网络聪明起来, 快起来,让cost()的收敛速度更加理想.

        这个时候,就应该让优化器出场大显神通了.

        今天,我们来探讨一下各种常见的优化器

1.Batch gradient descent 批梯度下降

BGD 采用整个训练集的数据来计算 cost function 对参数的梯度

每次更新我们需要计算整个数据集的梯度,因此使用批量梯度下降进行优化时,计算速度很慢,而且对于不适合内存计算的数据将会非常棘手。批量梯度下降算法不允许我们实时更新模型

我们会事先定义一个迭代次数 epoch,首先计算梯度向量 params_grad,然后沿着梯度的方向更新参数 params,learning rate 决定了我们每一步迈多大。
但是批量梯度下降算法能确保收敛到凸平面的全局最优和非凸平面的局部最优。

2.Stochastic Gradient Descent (SGD)  随机梯度下降

随机梯度下降算法参数更新针对每一个样本集x(i) 和y(i) 。批量梯度下降算法在大数据量时会产生大量的冗余计算,比如:每次针对相似样本都会重新计算。这种情况时,SGD算法每次则只更新一次。因此SGD算法通过更快,并且适合online。


但是SGD以高方差进行快速更新,这会导致目标函数出现严重抖动的情况。一方面,正是因为计算的抖动可以让梯度计算跳出局部最优,最终到达一个更好的最优点;另一方面,SGD算法也会因此产生过调。

当我们稍微减小 learning rate,SGD 和 BGD 的收敛性是一样的。

3.Min-batch gradient descent  小批量梯度下降法

MBGD 每一次利用一小批样本,即 n 个样本进行计算, 
这样它可以降低参数更新时的方差,收敛更稳定, 
另一方面可以充分地利用深度学习库中高度优化的矩阵操作来进行更有效的梯度计算。

和 SGD 的区别是每一次循环不是作用于每个样本,而是具有 n 个样本的批次

 

4.Momentum 动量法

Momentum 通过加入 γv_t−1 ,可以加速 SGD, 并且抑制震荡

当我们将一个小球从山上滚下来时,没有阻力的话,它的动量会越来越大,但是如果遇到了阻力,速度就会变小。 
加入的这一项,可以使得梯度方向不变的维度上速度变快,梯度方向有所改变的维度上的更新速度变慢,这样就可以加快收敛并减小震荡。

å éç¥ç»ç½ç»è®­ç» (Speed Up Training)

5.AdaGrad

Adagrad优化算法是一种自适应优化算法,针对高频特征更新步长较小,而低频特征更新较大。因此该算法适合应用在特征稀疏的场景。

这种方法是在学习率上面动手脚, 使得每一个参数更新都会有自己与众不同的学习率, 他的作用和 momentum 类似, 不过不是给喝醉酒的人安排另一个下坡, 而是给他一双不好走路的鞋子, 使得他一摇晃着走路就脚疼, 鞋子成为了走弯路的阻力, 逼着他往前直着走. 他的数学形式是这样的. 接下来又有什么方法呢? 如果把下坡和不好走路的鞋子合并起来, 是不是更好呢? 没错, 这样我们就有了 RMSProp 更新方法.

å éç¥ç»ç½ç»è®­ç» (Speed Up Training)

6.RMSProp

有了 momentum 的惯性原则 , 加上 adagrad 的对错误方向的阻力, 我们就能合并成这样. 让 RMSProp同时具备他们两种方法的优势. 不过细心的同学们肯定看出来了, 似乎在 RMSProp 中少了些什么. 原来是我们还没把 Momentum合并完全, RMSProp 还缺少了 momentum 中的 这一部分. 所以, 我们在 Adam 方法中补上了这种想法.

å éç¥ç»ç½ç»è®­ç» (Speed Up Training)

7.Adadelta

Adadelta算法是adagrad算法的改进版,它主要解决了adagrad算法单调递减学习率的问题。通过约束历史梯度累加来替代累加所有历史梯度平方。这里通过在历史梯度上添加衰减因子,并通过迭代的方式来对当前的梯度进行计算,最终距离较远的梯度对当前的影响较小,而距离当前时刻较近的梯度对当前梯度的计算影响较大。

通常,我们设置lambda参数为0.9。为了清楚的表达,这里我们再次列出SGD算法的计算公式:

而adagrad算法的计算公式为:

这里我们简单的替换对角矩阵G为E(带衰减的历史梯度累加)

上式分母正好是均方误差根(RMS),这里我们用简写来表达:

作者提到参数更新应该有相同的假设,因此我们定义另一个指数衰减平均,这里采用的是参数更新的平方

因为t时刻,RMS[]项未知,因此我们采用先前的参数RMS对当前时刻进行渐进表示。最终我们有如下表达式:

采用Adadelta算法作为模型优化器算法时,我们已经不需要设置默认学习率。


 

8.Adam

Adam可以算是用的最多的优化器了.

Adam算法是另一种自适应参数更新算法。和Adadelta、RMSProp算法一样,对历史平方梯度v(t)乘上一个衰减因子,adam算法还存储了一个历史梯度m(t)。

mt和vt分别是梯度一阶矩(均值)和二阶矩(方差)。当mt和vt初始化为0向量时,adam的作者发现他们都偏向于0,尤其是在初始化的时候和衰减率很小的时候(例如,beta1和beta2趋近于1时)。

通过计算偏差校正的一阶矩和二阶矩估计来抵消偏差:

利用上述的公式更新参数,得到adam的更新公式:

如下图, 计算m 时有 momentum 下坡的属性, 计算 v 时有 adagrad 阻力的属性, 然后再更新参数时 把 m 和 V 都考虑进去. 实验证明, 大多数时候, 使用 adam 都能又快又好的达到目标, 迅速收敛. 所以说, 在加速神经网络训练的时候, 一个下坡, 一双破鞋子, 功不可没.

å éç¥ç»ç½ç»è®­ç» (Speed Up Training)

Adam的一些优点包括:

  • 相对较低的内存要求(虽然高于梯度下降和梯度下降与动量)
  • 即使很少调整超参数(α除外)通常也能很好地工作

这篇专栏文章详细地介绍了Adam优化算法传送门

Adam的paper 传送门

不同优化器的效果比较?

SGD optimization on saddle point

SGD optimization on loss surface contours

上面两种情况都可以看出,Adagrad, Adadelta, RMSprop 几乎很快就找到了正确的方向并前进,收敛速度也相当快,而其它方法要么很慢,要么走了很多弯路才找到。

由图可知自适应学习率方法即 Adagrad, Adadelta, RMSprop, Adam 在这种情景下会更合适而且收敛性更好。
 

总结

  • 当训练数据特征较为稀疏的时候,采用自适应的优化器通常能获得更好的性能,而且我们采用自适应优化器的默认值即可获得较优的性能。
  • RMSprop算法是adagrad算法的优化版,它解决了学习率趋近于零的问题。Adadelta算法和RMSprop算法类似,区别在于Adadelta用参数的RMS作为更新规则的分子。最后,Adam则是在RMSprop的基础上加入了偏差校正和动量。综上来看,Adam可能是最佳的选择
  • 最近很多paper都采用不带动量的SGD算法,辅助一些简单的学习率退火策略。如上所述,SGD算法能够找到极小值,但是比其他优化器花费的时间更多。和其他算法相比,SGD算法更加依赖于初始化参数的设置和退火策略,而且SGD算法更加容易陷入鞍点。所以,如果你想模型更快的收敛或者训练一个深层次、复杂度较高的网络,自适应的优化器应该是首选优化器。

references:

https://www.jianshu.com/p/0acd30a23e4e

https://morvanzhou.github.io/tutorials/machine-learning/ML-intro/3-06-speed-up-learning/

猜你喜欢

转载自blog.csdn.net/Torres_10/article/details/84144474
今日推荐