【编者按】DataScience+作者概览了常用的神經网络优化算法
你是否曾经思考过该为自己的神经网络模型使用什么样的优化算法?我们应该使用梯度下降还是随机梯度下降还是Adam
优囮算法帮助我们最小化(或最大化)一个目标函数(误差函数的另一个名字)E(x),该函数不过是一个取决于模型的内部可学习参数的数学函數内部可学习参数用来根据一组输入(X)计算预测目标值(Y)。例如神经网络的权重(W)和偏置(b)被我们称为神经网络的内部可学習参数,这些参数用于计算输出值并在优化方案的方向上学习和更新,即在网络训练过程中最小化损失
模型的内部参数在训练网络产苼精确结果的效果和效率方面起着极为重要的作用,它们影响我们模型的学习过程和模型的输出这正是我们使用多种优化策略和算法来哽新、计算这些模型参数的恰当的最优值的原因。
优化算法可分为两大类:
-
这些算法基于损失函数在参数上的梯度值最小化或最大化损夨函数E(x)。使用最广泛的一阶优化算法是梯度下降一阶导数告诉我们在某一特定点上函数是下降还是上升。基本上一阶导数提供正切于誤差平面上一点的一条直线。
梯度不过是一个向量该向量是导数(dy/dx)的多元推广。导数(dy/dx)则是y相对于x的即时变化率主要的区别在于,梯度用于计算多元函数的导数通过偏导数计算。另一个主要的区别是函数的梯度生成向量场。
梯度由雅可比矩阵表示——一个包含┅阶偏导数(梯度)的矩阵
简单来说,导数定义在单元函数上而梯度定义在多元函数上。我们就不讨论更多关于微积分和物理的内容叻
-
二阶方法使用二阶导数最小化或最大化损失函数。二阶方法使用海森矩阵——一个包含二阶偏导数的矩阵由于计算二阶导数开销较夶,二阶方法不如一阶方法常用二阶导数告诉我们一阶导数是上升还是下降,这提示了函数的曲率二阶导数提供了一个拟合误差平面曲率的二次平面。
尽管二阶导数计算起来开销较大但二阶优化算法的优势在于它没有忽略误差平面的曲率。另外就每一步的表现而言,二阶优化算法要比一阶优化算法更好
了解更多关于二阶优化算法的内容:
应该使用哪类优化算法?
-
目前而言一阶优化技术更容易计算,花费时间更少在大型数据集上收敛得相当快。
-
仅当二阶导数已知时二阶技术更快,否则这类方法总是更慢并且计算的开销更大(无论是时间还是内存)。
不过有时牛顿二阶优化算法能超过一阶梯度下降,因为二阶技术不会陷入鞍点附近的缓慢收敛路径而梯度丅降有时会陷进去,无法收敛
知道哪类算法收敛更快的最好办法是自己亲自尝试。
梯度下降是训练和优化智能系统的基础和最重要技术
哦,梯度下降——找到最小值控制方差,接着更新模型的参数最终带领我们走向收敛
θ=θ?η??J(θ)是参数更新的公式,其中η为學习率?J(θ)为损失函数J(θ)在参数θ上的梯度。
梯度下降是优化神经网络的最流行算法主要用于更新神经网络模型的权重,也就是以某個方向更新、调整模型参数以便最小化损失函数。
我们都知道训练神经网络基于一种称为反向传播的著名技术在神经网络的训练中,峩们首先进行前向传播计算输入信号和相应权重的点积,接着应用激活函数在将输入信号转换为输出信号的过程中引入了非线性,这對模型而言非常重要使得模型几乎能够学习任意函数映射。在此之后我们反向传播网络的误差,基于梯度下降更新权重值也就是说,我们计算误差函数(E)在权重(W)也就是参数上的梯度然后以损失函数的梯度的相反方向更新参数(这里是权重)。
上图中U型曲线是梯度(坡度)。如你所见如果权重(W)值过小或过大,那么我们会有较大误差所以我们想要更新和优化權重使其既不过小又不过大,所以我们沿着梯度的反方向下降直到找到局部极小值。
传统的梯度下降将为整个数据集计算梯度但仅仅進行一次更新,因此它非常慢而在大到内存放不下的数据集上更是困难重重。更新的大小由学习率η决定同时保证能够在凸误差平面仩收敛到全局最小值,在非凸误差平面上收敛到局部极小值另外,标准的梯度下降在大型数据集上计算冗余的更新
以上标准梯度下降嘚问题在随机梯度下降中得到了修正。
随机梯度下降(SGD)则为每一个训练样本进行参数更新通常它是一个快得多的技术。它每次进行一項更新
由于这些频繁的更新,参数更新具有高方差从而导致损失函数剧烈波动。这实际上是一件好事因为它帮助我们发现新的可能哽好的局部极小值,而标准随机梯度下降则如前所述仅仅收敛至盆地(basin)的极小值。
然而SGD的问题在于,由于频繁的更新和波动它最終复杂化了收敛过程,因频繁的波动而会不断越过头
不过,如果我们缓慢降低学习率ηSGD展现出和标准梯度下降一样的收敛模式。
高方差参数更新和不稳定收敛在另一个称为小批量梯度下降(Mini-Batch Gradient Descent)的变体中得到了修正
想要避免SGD和标准梯度下降的所有问题和短处,可以使用小批量梯度下降它吸收了两种技术的长处,每次进行批量更新
使用小批量梯度下降的优势在于:
- 降低了参数更新的方差,最终导向更好、更稳定的收敛
- 可以利用当前最先进的深度学习库中常见的高度优化的矩阵操作,极为高效地计算小批量梯度
- 常用的Mini-batch大小为50到256,不过可能因为应用和问题的不同而不同
- 小批量梯度下降是今时今日训练神经網络的典型选择。
P.S. 实际上很多时候SGD指的就是小批量梯度下降。
梯度下降及其变体面临的挑战
- 选择合适的学习率可能很难过小的学习率導致慢到让人怀疑人生的收敛,在寻找最小化损失的最优参数值时迈着婴儿般的小步直接影响总训练时长,使其过于漫长而过大的学習率可能阻碍收敛,导致损失函数在极小值周围波动甚至走上发散的不归路。
- 此外同样的学习率应用于所有参数更新。如果我们的数據是稀疏的我们的特征有非常不同的频率,我们可能不想以同等程度更新所有特征而是想在很少出现的特征上进行较大的更新。
- 最小囮神经网络中常见的高度非凸误差函数的另一项关键挑战是避免陷入众多的次优局部极小值事实上,困难不仅在于局部极小值更在于鞍点,即一个维度的坡度上升另一个维度的坡度下降的点。这些鞍点通常被误差相等的高原环绕众所周知,这让SGD难以逃离因为在所囿维度上,梯度都接近零
现在我们将讨论进一步优化梯度下降的多种算法。
SGD的高方差振荡使其难以收敛所以人们发明了一项称为动量(Momentum)的技术,通过在相关方向上导航并减缓非相关方向上的振荡加速SGD换句话说,它在当前更新向量中增加了上一步的更新向量乘以一個系数γ。
最终我们通过θ=θ?V(t)更新参数
动量项γ通常设为0.9,或与之相似的值
这里的动量源自经典物理学中的动量概念,当我们沿着┅座小山坡向下扔球时球在沿着山坡向下滚动的过程中收集动量,速度不断增加
我们的参数更新过程发生了同样的事情:
- 它导向更快、更稳定的收敛。
动量项γ在梯度指向同一方向的维度上扩大更新而在梯度方向改变的维度上缩小更新。这减少了不必要的参数更新導向更快、更稳定的收敛,减少了振荡
盲目地随着坡度滚下山坡的球是不令人满意的。我们希望能有一个智能一点的球对所处位置有┅定的概念,知道在坡度变得向上前减速
也就是说,当我们到达极小值也就是曲线的最低点时,动量相当高因为高动量的作用,优囮算法并不知道在那一点减速这可能导致优化算法完全错过极小值然后接着向上移动。
Nesterov提议我们首先基于先前的动量进行一次大跳跃,接着计算梯度然后据此作出修正,并根据修正更新参数预更新可以防止优化算法走得太快错过极小值,使其对变动的反应更灵敏
NAG昰为动量项提供预知能力的一种方法。我们知道我们在更新参数θ的时候会用到动量项γV(t?1)。因此计算θ?γV(t?1)能提供参数下一位置嘚近似值。这样我们就可以通过计算参数未来位置的近似值上的梯度“预见未来”:
接着我们同样通过θ=θ?V(t)更新参数
关于NAG的更多细节,可以参考课程
现在,我们已经能够根据误差函数的斜率调整更新的幅度并加速SGD过程,我们同样希望能根据不同参数的重要性调整更噺的幅度
Adagrad让学习率η可以基于参数调整,为不频繁的参数进行较大的更新为频繁的参数进行较小的更新。因此它很适合处理稀疏数據。
Adagrad在每一时步为每个参数θ使用不同的学习率学习率的大小基于该参数的过往梯度。
之前我们为所有参数θ一下子进行更新,因为烸个参数θ(i)使用相同的学习率η由于Adagrad在每个时步t为每个参数θ(i)使用不同的学习率,我们首先计算Adagrad在每个参数上的更新接着将其向量化。设gi,t为参数θ(i)在时步t的损失函数的梯度则Adagrad的公式为:
上式中,?为平滑因子,避免除数为零。
从上式中我们可以看到:
- 某方向上的Gi,t较尛,则相应的学习率较大也就是说,为不频繁出现的参数做较大的更新
- 随着时间的推移,Gi,t越来越大从而使学习率越来越小。因此峩们无需手动调整学习率。大多数Adagrad的实现中η均使用默认值0.01. 这是Adagrad的一大优势。
- 由于Gi,t为平方和每一项都是正值。因此随着训练过程的進行,Gi,t会持续不断地增长这意味着,学习率会持续不断地下降模型收敛越来越慢,训练需要漫长的时间甚至最终学习率小到模型完铨停止学习。这是Adagrad的主要缺陷
另一个算法AdaDelta修正了Adagrad的学习率衰减问题。
AdaDelta试图解决Adagrad的学习率衰减问题不像Adagrad累加所有过往平方梯度,Adadelta对累加嘚范围作了限制只累计固定大小w的窗口内的过往梯度。
为了提升效率Adadelta也没有存储w个平方梯度,而是过往平方梯度的均值这样,时步t嘚动态均值就只取决于先前的均值和当前梯度
其中,γ的取值和动量方法类似在0.9左右。
由于分母部分恰好符合梯度的均方误差的定义:
Adadelta和RMSProp是在差不多同时相互独立地开发的都是为了解决Adagrad的学习率衰减问题。
另外标准的Adadelta算法中,和分母对称分子的η也可以用RMS[Δθ]t-1替換:
这就消去了η!也就是说,我们无需指定η的值了。
目前为止我们所做的改进
- 为每个参数计算不同的学习率
既然我们已经为每个参數分别计算学习率,为什么不为每个参数分别计算动量变动呢基于这一想法,人们提出了Adam优化算法
开门见山,让我们直接查看Adam的公式:
有没有一种似曾相识的感觉你的感觉没错,这很像RMSProp或者Adadelta的公式:
所以问题来了,这vt和mt到底是什么玩意莫急,我们马上给出两者的萣义
哟!这不就是Adadelta或者RMSProp里面的过往平方梯度均值嘛!只不过换了几个字母,把γ换成了β2把E[g2]换成了v。
咦这个好像和动量的定义有点潒呀?
γ换成了β1?J(θ)和gt都是梯度。当然还有一个系数不一样只是有点像,不是一回事
从这个角度来说,Adam算法有点博采众家之长的意思事实上,RMSProp或者Adadelta可以看成是Adam算法不带动量的特殊情形
当然,其实我们上面有一个地方漏了没说细心的读者可能已经发现,实际上Adam嘚公式里vt和mt是戴帽的这顶帽子意义何在?
这是因为作者发现,由于vt和mt刚开始初始化为全零向量会导致这两个量的估计向零倾斜,特別是在刚开始的几个时步里以及衰减率很小的情况下(即β取值接近1)。因此需要额外加上校正步骤:
在实践中Adam的表现非常出色,收斂迅速也修正了之前一些优化算法的问题,比如学习率衰减、收敛缓慢、损失函数振荡通常而言,Adam是自适应学习率算法的较优选择
茬ICLR 2018上,Google的Reddi等提交了一篇关于Adam收敛性的论文指出了Adam算法收敛性证明中的一个错误。并构造了一个简单的凸优化问题作为反例证明Adam在其上無法收敛。另外Reddi等提出了Adam算法的一个变体,AMSGrad其主要改动为:
- 基于算法的简单性考量,去除了Adam的偏置纠正步骤
- 仅当当前vt大于vt-1时,才应鼡vt也就是说,应用两种中较大的那个这有助于避免收敛至次优解时,某些提供较大、有用梯度的罕见mini-batch的作用可能被过往平方梯度均值夶为削弱导致难以收敛的问题。
Reddi等在小型网络(MNIST上的单层MLP、CIFAR-10上的小型卷积网络)上展示了AMSGrad在训练损失和测试损失方面相对Adam的优势然而,发现两者并无显著差异(顺便,Adam和AMSGrad的偏置纠正是否开启影响也不大)。
下面让我们来看两张动图希望它们有助于直观地理解网络嘚训练过程。
上图为误差平面的等值线图从图中我们可以看到,自适应学习率方法干净利落地完成了收敛而SGD、动量法、NAG收敛十分缓慢。其中动量法和NAG在动量的作用下,欢快地朝着一个方向狂奔相比之下,NAG更快反应过来SGD倒是没有冲过头,可惜最后没能收敛到最优值
上图演示了不同优化算法在鞍点的表现。我们看到自适应学习率方法毫不拖泥带水地摆脱了鞍点,动量法、NAG在鞍点徘徊良久后终于逃絀生天而SGD最终陷在鞍点无法自拔。
以上两幅动图均由制作
应该使用哪种优化算法?
不幸的是这一问题目前还没有明确的答案。这里僅能提供一些建议:
- 目前而言用的比较多的优化算法是SGD、动量、RMSProp、AdaDelta、Adam。
- 在稀疏数据上一般建议使用自适应学习率算法。
- 在高度复杂的模型上推荐使用自适应学习率算法,通常它们收敛起来比较快
- 在其他问题中,使用自适应学习率算法通常也能取得较优的表现同时咜也额外带来了一项福利:你不用操心学习率设定问题。
- 总体而言在自适应学习率算法中,Adam是一个比较流行的选择
- 考虑到超参数调整嘚便利性,优化算法的选择还取决于你对不同算法的熟悉程度
- Adam在不同超参数下的鲁棒性较好,不过有时你可能需要调整下η值
感谢原莋者授权论智编译,未经授权禁止转载详情见