随机梯度下降算法是为了解决深度学习中多元目标函数的最优值问题,已经有很多该算法的变种算法。下面我来介绍七种常见的随机梯度下降算法。



算法一:最基本的随机梯度下降算法


在最基本的随机梯度下降算法中,参数每一步通过减去它的梯度来更新的,通常需要首先打乱训练样本,然后将它们划分为一定数量的mini-batch,如果mini-batch的数量为1,那么更新方程一般为:


param = param-lr*g(param)


对于该算法,需要注意的是我们必须小心调节学习率。因为如果学习率设置太大的话,算法会导致目标函数发散;反之如果学习率设置太小的话,算法会导致目标函数收敛过慢。将训练样本随机打乱会避免参数更新的抵消,对于大规模的机器学习任务,随机梯度下降算法表现的性能可观。




算法二:动量法


如果参数的初始值和学习率没有设置恰当,算法一在实践中不能表现出较好的性能。引入动量的算法可以帮助网络跳出局部最优的限制。动量法已经被证明其在训练深度神经网络中的性能可以媲美之前的Hessian优化算法。并且,动量法通过在多次迭代中,在目标值持续递减的方向上累积一个速度矢量来加速梯度下降。其更新公式为:


v=mu*v-lr*g(param)

param=param+v



其中mu是动量系数,其最优值在实践中可以通过trial-and-error的方法来确定。通过与算法一比较可见,动量法仅仅是在权重更新上加了一部分之前的权重更新。当梯度下降保持原来的方向时,这就会增加下降的布幅,从而使得更快地达到最优值;当梯度下降改变方向时,动量法就会使得改变量平滑一点,这个对于网络的初始值设置地不好具有重要的弥补作用。动量法可以使得网络较快地达到最优值而没有太多震荡。




算法三:Nesterov Accelerated Gradient


NAG算法是基于算法二的一个变种,既然我们已经有了基于之前的更新mu*v,我们现在不计算在param处的梯度,取而代之的是计算在param+mu*v处的梯度,于是NAG算法的更新公式为:


v=mu*v-lr*g(param+mu*v)

param=param+v



由于NAG算法在计算梯度时做了小小的改变,在实践中,这使得NAG在很多情况下表现地要比算法二更加稳定。


现在既然已经有了根据目标函数的陡峭程度来更新参数,除此之外,我们还希望可以根据每个参数的特点来制定或大或小的更新步幅,换句话说,更新算法需要更精准。




算法四:AdaGrad


如果我们希望根据每个参数去调节学习率,那么AdaGrad恰好解决了这个问题。AdaGrad算法根据每个参数过去的更新历史来决定现在的更新学习率。AdaGrad会记录之前每一步更新值的平方,通过将这些累加起来来调节每一步学习率的大小。这样一来,对于那些频繁更新的参数,学习率会比较小;而对于那些不频繁更新的参数,学习率会比较大。从这个角度看,AdaGrad很适合比较稀疏的数据。更新公式如下:


G=G+[g(param)]^2

param=param-lr*g(param)/sqrt(G+epsilon)



其中epsilon是一个极小值,为了数值稳定。AdaGrad的一个优点是它可以避免手动去调节学习率,并且在很多时候,只要初始化学习率为0.01即可,然后可以放任不管。但是,一个明显的缺点是随着更新步骤的增多,学习率将会一直减小直至接近于0,这样就会导致网络更新停滞。




算法五:RMSProp


RMSProp是为了解决算法四的学习率消失问题,通过在历史更新与梯度平方之间设置一定的比例。其更新公式如下:


G=0.9*G+0.1*[g(param)]^2

param=param-lr*g(param)/sqrt(G+epsilon)



RMSProp与接下来要讨论的算法六几乎是同时提出的。




算法六:AdaDelta


AdaDelta也是为了解决AdaGrad的学习率消失问题,与AdaGrad累积历史更新所不同的是,AdaDelta将过去的更新限制在固定的长度w里面。并且,由于存储过去w个更新在计算上效率很低,取而代之的是通过采取指数衰减的形式来保留最近的更新项(平方梯度)。


这里需要定义一个叫做均方根的概念,均方根的公式如下:

RMS[g]=sqrt(E(g^2)+epsilon)

简而言之,均方根就是平方均值的平方根。



AdaDelta的更新公式如下:


首先初始化两个均值,E[g^2]=0,E[d_param^2]=0


E[g^2]=rou*E[g^2]+(1-rou)*g^2

d_param=RMS[d_param]/RMS[g]*g

E[d_param^2]=rou*E[d_param^2]+(1-rou)*d_param^2

param=param-lr*d_param



其中rou为衰减率。




算法七:Adam


最近,Adam算法被提出来,该算法非常有效,并且只需要一阶梯度,而且对内存要求也很低。Adam同时考虑了梯度以及梯度的平方,因此,Adam同时具有AdaGrad和AdaDelta的优点,能够很好地适应于稀疏数据或不当的初始化网络。


Adam算法的更新公式如下:


初始化一阶向量m和二阶向量v为0;

设置最优的beta1、beta2的值(论文中有介绍实践最优默认值);




m=beta1*m+(1-beta1)*g

v=beta2*v+(1-beta2)*g^2

m=m/(1-beta1)

v=v/(1-beta2)

param=param-lr*m/(sqrt(v)+epsilon)





总结


根据我之前所使用的情况来看,Adam算法是最快的也是最稳定的。不过,我想具体问题应该有所不同吧,最常用的是算法二、算法四、算法七了。

 
 
 
来源:张泽旺 深度学习每日摘要
智造家