问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

深度学习优化算法详解:从SGD到Adam

创作时间:
作者:
@小白创作中心

深度学习优化算法详解:从SGD到Adam

引用
CSDN
1.
https://blog.csdn.net/weixin_42398658/article/details/84525917

在深度学习中,优化算法的选择对模型的训练效果和效率有着至关重要的影响。本文将详细介绍几种常用的优化算法,包括随机梯度下降(SGD)、动量(Momentum)、AdaGrad、RMSProp和Adam等。

病态曲率

在神经网络训练中,病态曲率是一个常见的问题。考虑以下损失轮廓:

在进入蓝色标记的山沟状区域之前,我们随机开始。颜色表示损失函数在特定点处的值,红色表示最大值,蓝色表示最小值。我们的目标是最小值点,但需要穿过山沟。这个区域就是所谓的病态曲率。

梯度下降沿着山沟的山脊反弹,向极小的方向移动较慢。这是因为脊的表面在W1方向上弯曲得更陡峭。在脊的表面上的一个点梯度可以分解为两个分量,一个沿着方向w1,另一个沿着w2。梯度在w1方向上的分量要大得多,因此梯度的方向更靠近w1,而不是朝向w2(最小值位于其上)。

通常情况下,我们使用低学习率来应对这样的反复振荡,但在病态曲率区域使用低学习率,可能要花很多时间才能达到最小值处。事实上,有论文报告,防止反复振荡的足够小的学习率,也许会导致从业者相信损失完全没有改善,干脆放弃训练。

牛顿法

下降梯度是一阶优化方法。它只考虑损失函数的一阶导数而不是较高的导数。这基本上意味着它没有关于损失函数曲率的线索。它可以判断损失是否在下降和速度有多快,但无法区分曲线是平面,向上弯曲还是向下弯曲。

解决方案?考虑二阶导数,或者说梯度改变得有多快。使用二阶导数解决这一问题的一个非常流行的技术是牛顿法(Newton's Method)。牛顿法通过计算海森矩阵做到这一点。Hessian矩阵是损失函数在所有权重组合上的二阶导数的矩阵。

然而,现代神经网络架构的参数量可能是数亿,计算数亿的平方的梯度在算力上不可行。虽然高阶优化方法在算力上不太可行,但二阶优化关于纳入梯度自身如何改变的想法是可以借鉴的。

随机梯度下降(SGD)

SGD的学习原理很简单就是选择一条数据,就训练一条数据,然后修改权值算法过程如下:

随机梯度下降法:
给定数据集,数据集标记为:,学习器为,学习率
对于迭代足够多次
{
1.随机选择数据:
2.计算损失梯度:
3.修改权值:
}

SGD算法在训练过程中很有可能选择被标记错误的标记数据,或者与正常数据差异很大的数据进行训练,那么使用此数据求得梯度就会有很大的偏差,因此SGD在训练过程中会出现很强的随机现象。如何解决呢?可以多选择几个数据在一起求梯度和,然求均值,这样做的好处是即使有某条数据存在严重缺陷,也会因为多条数据的中和而降低其错误程度。

动量学习法

动量学习法和SGD一起使用的非常流行的技术。动量也不仅使用当前步骤的梯度来指导搜索,而是累积过去步骤的梯度以确定要去的方向。

在物理学中,动量的英文与物体的质量、速度相关的物理量。一般而言,一个物体的动量指的的是这个物体在它运动方向上保持运动的趋势。动量是矢量这里我们可以把梯度理解成力,力是有大小和方向的,而且力可以改变速度的大小和方向,并且速度可以累积。这里把权值理解成速度,当力(梯度)改变时就会有一段逐渐加速或逐渐减速的过程,我们通过引入动量就可以加速我们的学习过程,可以在鞍点处继续前行,也可以逃离一些较小的局部最优区域。

根据牛顿定律,动量等于质量乘以速度,而在动量学习算法中,我们假设质量的单位为1,因此速度v就可以直接当做动量了,我们同时引入超参数,其取值在【0,1】范围之间,用于调节先前梯度(力)的衰减效果,其更新方式为:

(1)

根据上面的随机梯度下降算法给出动量随机梯度下降算法;
初始化:
给定数据集,数据集标记为:,初始速度,随机采样m条数据,训练周期k,学习率衰减最低值b,学习器为,初始学习率,初始动量参数为
训练:
对于
{
1.随机采样米条数据:
2.计算采样数据平均损失梯度:
3.更新速度:
4.更新参数:
}

在随机梯度的学习算法中,每一步的步幅都是固定的,而在动量学习算法中,每一步走多远不仅依赖于本次的梯度的大小还取决于过去的速度。速度v是累积各轮训练参的梯度,其中越大,依赖以前的梯度越大。假如每轮训练的梯度方向都是相同的,和小球从斜坡滚落,由于但衰减因子的存在,小球并不会一直加速,而是达到最大速度后开始匀速行驶,这里假设每轮获得的梯度都是相同的,那么速度最大值为(按照(1)计算可得):

从上式可以看到当= 0.9时,最大速度相当于梯度下降的10倍(带进上式去算可得),通常可取0.5,0.9,0.99,情况一般调整没有调整的那么重要适当。取值即可。

AdaGrad(自适应梯度算法)

AdaGrad其实很简单,就是将每一维各自的历史梯度的平方叠加起来,然后更新的时候除以该历史梯度值即可。如针对第我个参数,算法如下。

定义首先一个量用于累加梯度的平方,如下:

平方的原因是去除梯度符号的干扰,防止抵消,更新时:

其中= 10 ^ -7,防止数值溢出。

从上式可以看出,AdaGrad使的参数在累积的梯度较小时()就会放大学习率,使网络训练更加快速。在梯度的累积量较大时()就会缩小学习率,延缓网络的训练,简单的来说,网络刚开始时学习率很大,当走完一段距离后小心翼翼,这正是我们需要的。但是这里存在一个致命的问题就是AdaGrad容易受到过去梯度的影响,陷入“过去”无法自拔,因为梯度很容易就会累积到一个很大的值,此时学习率就会被降低的很厉害,因此AdaGrad很容易过分的降低学习率率使其提前停止,怎么解决这个问题呢?RMSProp算法可以很好的解决该问题。

RMSProp(均方根支柱)

同样,RMSProp可以自动调整学习率。还有,RMSProp为每个参数选定不同的学习率。

虽然AdaGrad在理论上有些较好的性质,但是在实践中表现的并不是很好,其根本原因就是随着训练周期的增长,学习率降低的很快。而RMSProp算法就在AdaGrad基础上引入了衰减因子,如下式,RMSProp在梯度累积的时候,会对“过去”与“现在”做一个平衡,通过超参数进行调节衰减量,常用的取值为0.9或者0.5(这一做法和SGD有异曲同工之处)

参数更新阶段,和AdaGrad相同,学习率除以历史梯度总和即可。

实践中,RMSProp更新方式对深度学习网络十分有效,是深度学习的最有效的更新方式之一。

Adam(自适应动量优化)

到目前为止,我们已经看到RMSProp和动量采用对比方法。虽然动量加速了我们对最小值方向的搜索,但RMSProp阻碍了我们在振荡方向上的搜索.Adam通过名字我们就可以看出他是基于动量和RMSProp的微调版本,该方法是目前深度学习中最流行的优化方法,在默认情况尽量使用亚当作为参数的更新方式

首先计算当前最小批量数据梯度。和动量学习法一样,计算衰减梯度五:和RMSProp算法类似,计算衰减学习率R:最后更新参数:

上面就是RMSProp和动量的有机集合,使他们的优点集于一身,是不是很漂亮,但还是有一个问题就是开始时梯度会很小,R和v经常会接近0,因此我们需要初始给他一个?合适的值,这个值怎么给才合适呢先看下面的公式:

其中吨表示训练次数,刚开始动很大,随着训练次数吨的增加VB逐渐趋向于V,R类似下面给出总体的算法结构。

初始化:
给定数据集,数据集标记为:,初始速度,随机采样m条数据,训练周期k,学习器为,初始学习率,初始动量参数为,学习衰减参数,
训练:
用于:
{
1.随机采样米条数据:
2.计算当前采样数据的梯度:
3.更新当前速度:
4.更新当前学习率:
5.更新训练次数:
6.更新参数:
}

结语

本文介绍了三种应对病态曲率同时加速训练过程的梯度下降方法。在这三种方法之中,也许动量法用得更普遍,尽管从论文上看Adam更吸引人。经验表明这三种算法都能收敛到给定损失曲面的不同的最优局部极小值。然而,动量法看起来要比Adam更容易找到比较平坦的最小值,而自适应方法(自动调整学习率)倾向于迅速地收敛于较尖的最小值。比较平坦的最小值概括性更好。

尽管这些方法有助于我们训练深度网络难以控制的损失平面,随着网络日益变深,它们开始变得不够用了。除了选择更好的优化方法,有相当多的研究试图寻找能够生成更平滑的损失曲面的架构。批量归一化(Batch Normalization)和残差连接(Residual Connections)正是这方面的两个例子。我们会在后续的文章中详细介绍它们。但这篇文章就到此为止了。欢迎在评论中提问。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号