DL优化算法总结

批量梯度下降(Batch gradient descent)

       批量梯度下降每次学习都使用整个训练集来更新模型参数,即:  

                                                                 θ=θ−η⋅∇θJ(θ)

       每次使用全部训练集样本计算损失函数的梯度,然后使用学习速率朝着梯度相反方向去更新模型的每个参数。

  • 优点:每次更新都会朝着正确的方向进行,最后能够保证收敛于极值点(凸函数收敛于全局极值点,非凸函数可能会收敛于局部极值点)。
  • 缺点:每次学习时间过长,并且如果训练集很大以至于需要消耗大量的内存,并且批量梯度下降不能进行在线模型参数更新

随机梯度下降(Stochastic gradient descent)

       随机梯度下降算法每次从训练集中随机选择一个样本来进行学习,即:   

                                                                 θ=θ−η⋅∇θJ(θ;xi;yi) 

       批量梯度下降算法每次都会使用全部训练样本,因此计算是冗余的,因为每次都使用完全相同的样本集。

  • 优点:每次只随机选择一个样本来更新模型参数,因此每次的学习是非常快速的,并且可以进行在线更新
  • 缺点:每次更新可能并不会按照正确的方向进行存在波动,因此会使得迭代次数(学习次数)增多,即收敛速度变慢。如下图:

                                                 

 

       不过从另一个方面来看,随机梯度下降所带来的波动有个好处就是,对于类似盆地区域(即很多局部极小值点),这个波动的特点可能会使得优化的方向从当前的局部极小值点跳到另一个更好的局部极小值点,这样便可能对于非凸函数,最终收敛于一个较好的局部极值点,甚至全局极值点。

       随机梯度下降最终会和批量梯度下降算法一样,具有相同的收敛性,即凸函数收敛于全局极值点,非凸损失函数收敛于局部极值点。

热重启(Warm restarts)  

       热重启的SGD(SGD with restarts)  

       SGDR(Loshchilov andHutter,2017)是一种使用热重启替代学习速率退火的SGD方法。在每次重新启动时,学习速率被初始化为某个值,并且将减少。重要的是,重启是热重启,因为优化不是从头开始,而是从最后一个步骤中模型收敛的参数开始。关键因素是用积极的余弦退火方案使学习率下降,这会迅速降低学习率,如下所示:

                                

 

       重新启动后的初始的高学习率用于基本上将参数从它们先前收敛的最小值弹射到不同的损失表面(loss surface)。激进的退火使模型能够快速收敛到一个新的更好的解决方案。作者根据经验发现,热重启的SGD需要的时间比学习速率退火少2〜4倍,并且能达到相当或更好的性能。  

小批量梯度下降(Mini-batch gradient descent) 

       Mini-batch梯度下降综合了batch梯度下降与stochastic梯度下降,在每次更新速度与更新次数中间取得一个平衡,其每次更新从训练集中随机选择m(其中m<n)个样本进行学习,即:   

                                                                 θ=θ−η⋅∇θJ(θ;xi:i+m;yi:i+m)

       相对于随机梯度下降,Mini-batch梯度下降降低了收敛波动性,即降低了参数更新的方差,使得更新更加稳定

       相对于批量梯度下降,其提高了每次学习的速度。并且其不用担心内存瓶颈从而可以利用矩阵运算进行高效计算。

       一般而言每次更新随机选择[50,256]个样本进行学习,但是也要根据具体问题而选择,实践中可以进行多次试验,选择一个更新速度与更新次数都较适合的样本数。

  • mini-batch梯度下降可以保证收敛性
  • mini-batch梯度下降常用于神经网络中。

Momentum

       如果在峡谷地区(某些方向较另一些方向上陡峭得多,常见于局部极值点),SGD会在这些地方附近振荡,从而导致收敛速度慢。这种情况下,动量(Momentum)便可以解决。动量在参数更新项中加上一次更新量(即动量项),即:

                                                                 νt=γνt−1+η ∇θJ(θ)  

                                                                 θ=θ−νt  

       其中动量项超参数γ<1一般是小于等于0.9。其作用如下图所示:

        

 

                                      没有动量                                                                       加上动量

       加上动量项就像从山顶滚下一个球,球往下滚的时候累积了前面的动量(动量不断增加),因此速度变得越来越快,直到到达终点。

       同理,在更新模型参数时,对于那些当前的梯度方向与上一次梯度方向相同的参数,那么进行加强,即这些方向上更快了;对于那些当前的梯度方向与上一次梯度方向不同的参数,那么进行削减,即这些方向上减慢了。因此可以获得更快的收敛速度与减少振荡。

NAG

       从山顶往下滚的球会盲目地选择斜坡。更好的方式应该是在遇到倾斜向上之前应该减慢速度。     

       Nesterov accelerated gradient(NAG,涅斯捷罗夫梯度加速)不仅增加了动量项,并且在计算参数的梯度时,在损失函数中减去了动量项,即计算∇θJ(θ−γνt−1),这种方式预估了下一次参数所在的位置。即:   

                                                                 νt=γνt−1+η⋅∇θJ(θ−γνt−1)  

                                                                 θ=θ−νt  

       如下图所示:

                                  

 

                                                                NAG更新

       详细介绍可以参见Ilya Sutskever的PhD论文。假设动量因子参数γ=0.9,首先计算当前梯度项,如上图小蓝色向量,然后加上动量项,这样便得到了大的跳跃,如上图大蓝色的向量。这便是只包含动量项的更新。而NAG首先来一个大的跳跃(动量项),然后加上一个小的使用了动量计算的当前梯度(上图红色向量)进行修正得到上图绿色的向量。这样可以阻止过快更新来提高响应性,如在RNNs中。     

       通过上面的两种方法,可以做到每次学习过程中能够根据损失函数的斜率做到自适应更新来加速SGD的收敛。下一步便需要对每个参数根据参数的重要性进行各自自适应更新。

Adagrad

  • 优点:能够为每个参数自适应不同的学习速率,而一般的人工都是设定为0.01。
  • 缺点:需要计算参数梯度序列平方和,并且学习速率趋势是不断衰减最终达到一个非常小的值。

       Adagrad也是一种基于梯度的优化算法,它能够对每个参数自适应不同的学习速率,对稀疏特征,得到大的学习更新,对非稀疏特征,得到较小的学习更新,因此该优化算法适合处理稀疏特征数据。Dean等发现Adagrad能够很好的提高SGD的鲁棒性,google便用起来训练大规模神经网络(看片识猫:recognize cats in Youtube videos)。Pennington等在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对每一个参数使用不同的学习速率,其更新方程为:  

                                                             

       其中,Gt∈Rd×d是一个对角矩阵,其中第i行的对角元素eii为过去到当前第i个参数θi的梯度的平方和,epsilon是一个平滑参数,为了使得分母不为0(通常ϵ=1e−8),另外如果分母不开根号,算法性能会很糟糕。     

       进一步,将所有Gt,ii,gt,i 的元素写成向量Gt,gt,这样便可以使用向量点乘操作:  

                                                               

RMSprop

       其实RMSprop是Adadelta的中间形式,也是为了降低Adagrad中学习速率衰减过快问题,即:

                                                              

       Hinton建议γ=0.9,η=0.001。

Adam

       Adaptive Moment Estimation(Adam) 也是一种不同参数自适应不同学习速率方法,与Adadelta与RMSprop区别在于,它计算历史梯度衰减方式不同,不使用历史平方衰减,其衰减方式类似动量,如下:   

                                                                 mt=β1mt−1+(1−β1)gt

                                                                 vt=β2vt−1+(1−beta2)g2t 

       mt与vt分别是梯度的带权平均和带权有偏方差,初始为0向量,Adam的作者发现他们倾向于0向量(接近于0向量),特别是在衰减因子(衰减率)β1,β2接近于1时。为了改进这个问题,对mt与vt进行偏差修正(bias-corrected):

                                                                 

       最终,Adam的更新方程为:

                                                                 

       论文中建议默认值:β1=0.9,β2=0.999,ϵ=10−8。论文中将Adam与其它的几个自适应学习速率进行了比较,效果均要好。 

各优化方法比较

                                           

       从上图可以看出, Adagrad、Adadelta与RMSprop在损失曲面上能够立即转移到正确的移动方向上达到快速的收敛。而Momentum 与NAG会导致偏离(off-track)。同时NAG能够在偏离之后快速修正其路线,因为其根据梯度修正来提高响应性。

                                   

       从上图可以看出,在鞍点(saddle points)处(即某些维度上梯度为零,某些维度上梯度不为零),SGD、Momentum与NAG一直在鞍点梯度为零的方向上振荡,很难打破鞍点位置的对称性;Adagrad、RMSprop与Adadelta能够很快地向梯度不为零的方向上转移。    

       从上面两幅图可以看出,自适应学习速率方法(Adagrad、Adadelta、RMSprop与Adam)在这些场景下具有更好的收敛速度与收敛性。

如何选择SGD优化器

       如果你的数据特征是稀疏的,那么你最好使用自适应学习速率SGD优化方法(Adagrad、Adadelta、RMSprop与Adam),因为你不需要在迭代过程中对学习速率进行人工调整。     

       RMSprop是Adagrad的一种扩展,与Adadelta类似,但是改进版的Adadelta使用RMS去自动更新学习速率,并且不需要设置初始学习速率。而Adam是在RMSprop基础上使用动量与偏差修正。RMSprop、Adadelta与Adam在类似的情形下的表现差不多。Kingma指出收益于偏差修正,Adam略优于RMSprop,因为其在接近收敛时梯度变得更加稀疏。因此,Adam可能是目前最好的SGD优化方法

       有趣的是,最近很多论文都是使用原始的SGD梯度下降算法,并且使用简单的学习速率退火调整(无动量项)。现有的已经表明:SGD能够收敛于最小值点,但是相对于其他的SGD,它可能花费的时间更长,并且依赖于鲁棒的初始值以及学习速率退火调整策略,并且容易陷入局部极小值点,甚至鞍点。因此,如果你在意收敛速度或者训练一个深度或者复杂的网络,你应该选择一个自适应学习速率的SGD优化方法。

更多的SGD优化策略

Shuffling and Curriculum Learning

       为了使得学习过程更加无偏,应该在每次迭代中随机打乱训练集中的样本。     

       另一方面,在很多情况下,我们是逐步解决问题的,而将训练集按照某个有意义的顺序排列会提高模型的性能和SGD的收敛性,如何将训练集建立一个有意义的排列被称为Curriculum Learning[16]。    

       Zaremba与Sutskever[17]在使用Curriculum Learning来训练LSTMs以解决一些简单的问题中,表明一个相结合的策略或者混合策略比对训练集按照按照训练难度进行递增排序要好。

Batch normalization

       为了方便训练,我们通常会对参数按照0均值1方差进行初始化,随着不断训练,参数得到不同程度的更新,这样这些参数会失去0均值1方差的分布属性,这样会降低训练速度和放大参数变化随着网络结构的加深。     

       Batch normalization在每次mini-batch反向传播之后重新对参数进行0均值1方差标准化。这样可以使用更大的学习速率,以及花费更少的精力在参数初始化点上。Batch normalization充当着正则化、减少甚至消除掉Dropout的必要性。  

Early stopping

       在验证集上如果连续的多次迭代过程中损失函数不再显著地降低,那么应该提前结束训练,详细参见NIPS 2015 Tutorial slides,或者参见防止过拟合的一些方法。  

Gradient noise

       Gradient noise[21]即在每次迭代计算梯度中加上一个高斯分布N(0,σ2t)的随机误差,即 :

                                                                  gt,i=gt,i+N(0,σ2t)

       高斯误差的方差需要进行退火:

                                                                 

       对梯度增加随机误差会增加模型的鲁棒性,即使初始参数值选择地不好,并适合对特别深层次的负责的网络进行训练。其原因在于增加随机噪声会有更多的可能性跳过局部极值点并去寻找一个更好的局部极值点,这种可能性在深层次的网络中更常见。

问题与挑战     

       虽然梯度下降算法效果很好,并且广泛使用,但同时其也存在一些挑战与问题需要解决:  

选择一个合理的学习速率很难

       如果学习速率过小,则会导致收敛速度很慢。如果学习速率过大,那么其会阻碍收敛,即在极值点附近会振荡。  

学习速率调整(Learning rate schedules)

       试图在每次更新过程中,改变学习速率,如退火。一般使用某种事先设定的策略或者在每次迭代中衰减一个较小的阈值。无论哪种调整方法,都需要事先进行固定设置,这便无法自适应每次学习的数据集特点。  

微调学习速率(Tuning the learning rate)  

       在许多情况下,除了超参数,我们的模型是不需要改进和调整的。

参考资料

2018年深度学习优化算法最新综述 https://mp.weixin.qq.com/s?__biz=MzU0NTAyNTQ1OQ==&mid=2247486522&idx=2&sn=80872f8044c51d67b1deb359b6b24bda&chksm=fb7270e6cc05f9f0f674cebf8a59d80e6374aa98e6cfb663d519cda0f8053871804737e2e2e6&scene=0&xtrack=1#rd

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值