正文
对于非凸目标函数,容易陷入那些次优的局部极值点中,如在神经网路中。那么如何避免呢。
Dauphin[19]
指出更严重的问题不是局部极值点,而是鞍点(These saddle points are usually surrounded by a plateau of the same error, which makes it notoriously hard for SGD to escape, as the gradient is close to zero in all dimensions.)。
梯度下降优化算法
下面将讨论一些在深度学习社区中经常使用用来解决上诉问题的一些梯度优化方法,不过并不包括在高维数据中不可行的算法,如
牛顿法
。
Momentum
如果在峡谷地区(某些方向较另一些方向上陡峭得多,常见于局部极值点)
[1]
,SGD会在这些地方附近振荡,从而导致收敛速度慢。这种情况下,动量(Momentum)便可以解决
[2]
。动量在参数更新项中加上一次更新量(即动量项),即:
νt=γνt−1+η ∇θJ(θ)
θ=θ−νt
其中动量项超参数
γ
其作用如下图所示:
图2 没有动量
图3 加上动量
加上动量项就像从山顶滚下一个球,求往下滚的时候累积了前面的动量(动量不断增加),因此速度变得越来越快,直到到达终点。同理,在更新模型参数时,对于那些当前的梯度方向与上一次梯度方向相同的参数,那么进行加强,即这些方向上更快了;对于那些当前的梯度方向与上一次梯度方向不同的参数,那么进行削减,即这些方向上减慢了。因此可以获得更快的收敛速度与减少振荡。
从山顶往下滚的球会盲目地选择斜坡。更好的方式应该是在遇到倾斜向上之前应该减慢速度。
Nesterov accelerated gradient(
NAG,涅斯捷罗夫梯度加速
)不仅增加了动量项,并且在计算参数的梯度时,在损失函数中减去了动量项,即计算
∇θJ(θ−γνt−1),这种方式预估了下一次参数所在的位置。即:
νt=γνt−1+η⋅∇θJ(θ−γνt−1)
θ=θ−νt
如下图所示:
图4 NAG更新
详细介绍可以参见Ilya Sutskever的PhD论文
[9]
。假设动量因子参数
γ=0.9,首先计算当前梯度项,如上图小蓝色向量,然后加上动量项,这样便得到了大的跳跃,如上图大蓝色的向量。这便是只包含动量项的更新。而NAG首先来一个大的跳跃(动量项),然后加上一个小的使用了动量计算的当前梯度(上图红色向量)进行修正得到上图绿色的向量。这样可以阻止过快更新来提高响应性,如在RNNs中
[8]
。
通过上面的两种方法,可以做到每次学习过程中能够根据损失函数的斜率做到自适应更新来加速SGD的收敛。下一步便需要对每个参数根据参数的重要性进行各自自适应更新。
Adagrad
Adagrad
[3]
也是一种基于梯度的优化算法,它能够对每个参数自适应不同的学习速率,对稀疏特征,得到大的学习更新,对非稀疏特征,得到较小的学习更新,因此该优化算法适合处理稀疏特征数据。
Dean等[4]
发现Adagrad能够很好的提高SGD的鲁棒性,google便用起来训练大规模神经网络(
看片识猫:recognize cats in Youtube videos
)。
Pennington等[5]
在GloVe中便使用Adagrad来训练得到词向量(Word Embeddings), 频繁出现的单词赋予较小的更新,不经常出现的单词则赋予较大的更新。
在前述中,每个模型参数
θi使用相同的学习速率
η,而Adagrad在每一个更新步骤中对于每一个模型参数
θi使用不同的学习速率
ηi,设第
t次更新步骤中,目标函数的参数
θi梯度为
gt,i,即:
gt,i=∇θJ(θi)
那么SGD更新方程为:
θt+1,i=θt,i−η⋅gt,i
而Adagrad对每一个参数使用不同的学习速率,其更新方程为:
其中,