深度學習最全優化方法總結比較及在tensorflow實現


版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/u010899985/article/details/81836299
梯度下降算法針對凸優化問題原則上是可以收斂到全局最優的,因為此時只有唯一的局部最優點。而實際上深度學習模型是一個復雜的非線性結構,一般屬於非凸問題,這意味着存在很多局部最優點(鞍點),采用梯度下降算法可能會陷入局部最優,這應該是最頭疼的問題。這點和進化算法如遺傳算法很類似,都無法保證收斂到全局最優。因此,我們注定在這個問題上成為“高級煉丹師”。可以看到,梯度下降算法中一個重要的參數是學習速率,適當的學習速率很重要:學習速率過小時收斂速度慢,而過大時導致訓練震盪,而且可能會發散。理想的梯度下降算法要滿足兩點:收斂速度要快;能全局收斂。為了這個理想,出現了很多經典梯度下降算法的變種,下面將分別介紹它們。
SGD
梯度下降算法(Gradient Descent Optimization)是神經網絡模型訓練最常用的優化算法。梯度下降算法背后的原理:目標函數J(θ)關於參數θ的梯度將是目標函數上升最快的方向,對於最小化優化問題,只需要將參數沿着梯度相反的方向前進一個步長(學習速率),就可以實現目標函數的下降。參數更新公式如下:
其中是參數的梯度。
根據計算目標函數J(θ)采用數據量的大小,梯度下降算法又可以分為批量梯度下降算法(Batch Gradient Descent),隨機梯度下降算法(Stochastic GradientDescent)和小批量梯度下降算法(Mini-batch Gradient Descent)。
批量梯度下降算法,J(θ)是在整個訓練集上計算的,如果數據集比較大,可能會面臨內存不足問題,而且其收斂速度一般比較慢。
隨機梯度下降算法,J(θ)是針對訓練集中的一個訓練樣本計算的,又稱為在線學習,即得到了一個樣本,就可以執行一次參數更新。所以其收斂速度會快一些,但是有可能出現目標函數值震盪現象,因為高頻率的參數更新導致了高方差。
小批量梯度下降算法,是折中方案,J(θ)選取訓練集中一個小批量樣本計算,這樣可以保證訓練過程更穩定,而且采用批量訓練方法也可以利用矩陣計算的優勢。這是目前最常用的梯度下降算法。
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(loss)
momentum
SGD方法的一個缺點是,其更新方向完全依賴於當前的batch,因而其更新十分不穩定,每次迭代計算的梯度含有比較大的噪音。解決這一問題的一個簡單的做法便是引入momentum,momentum即動量,是BorisPolyak在1964年提出的,其基於物體運動時的慣性:將一個小球從山頂滾下,其初始速率很慢,但在加速度作用下速率很快增加,並最終由於阻力的存在達到一個穩定速率,即更新的時候在一定程度上保留之前更新的方向,同時利用 當前batch的梯度 微調最終的更新方向。這樣一來,可以在一定程度上增加穩定性,從而學習地更快,並且還有一定擺脫局部最優的能力。
其更新方程如下:
可以看到,參數更新時不僅考慮當前梯度值,而且加上了一個動量項γm,但多了一個超參γ,通常γ設置為0.5,直到初始學習穩定,然后增加到0.9或更高。相比原始梯度下降算法,動量梯度下降算法有助於加速收斂。當梯度與動量方向一致時,動量項會增加,而相反時,動量項減少,因此動量梯度下降算法可以減少訓練的震盪過程。
tf.train.MomentumOptimizer(learning_rate=learning_rate,momentum=0.9)
NAG
NAG(Nesterov Accelerated Gradient),,由Ilya Sutskever(2012 unpublished)在Nesterov工作的啟發下提出的。對動量梯度下降算法的改進版本,其速度更快。其變化之處在於計算“超前梯度”更新動量項 γm,具體公式如下:
既然參數要沿着動量項 γm更新,不妨計算未來位置(θ -γm)的梯度,然后合並兩項作為最終的更新項,其具體效果如圖1所示,可以看到一定的加速效果。
 
momentum基礎上設置 use_nesterov=True
tf.train.MomentumOptimizer(learning_rate=learning_rate,momentum=0.9, use_nesterov=True)
AdaGrad
AdaGrad是Duchi在2011年提出的一種學習速率自適應的梯度下降算法。在訓練迭代過程,其學習速率是逐漸衰減的,經常更新的參數其學習速率衰減更快,這是一種自適應算法。其更新過程如下:
每步迭代過程:
從訓練集中的隨機抽取一批容量為m的樣本{x1,…,xm},以及相關的輸出yi
計算梯度和誤差,更新r,再根據r和梯度計算參數更新量: 
 
其中,全局學習速率 ϵ, 初始參數 θ,梯度平方的累計量r初始化為0), δ(通常為10^−7)是為了防止分母的為 0。
由於梯度平方的累計量r逐漸增加的,那么學習速率是衰減的。考慮下圖所示的情況,目標函數在兩個方向的坡度不一樣,如果是原始的梯度下降算法,在接近坡底時收斂速度比較慢。而當采用AdaGrad,這種情況可以被改善。由於比較陡的方向梯度比較大,其學習速率將衰減得更快,這有利於參數沿着更接近坡底的方向移動,從而加速收斂。對於每個參數,隨着其更新的總距離增多,其學習速率也隨之變慢。
缺點: 任然要設置一個變量ϵ ,經驗表明,在普通算法中也許效果不錯,但在深度學習中,深度過深時會造成訓練提前結束。
tf.train.AdagradOptimizer(learning_rate=0.001).minimize(loss)
Adadelta
Adadelta是對Adagrad的擴展,最初方案依然是對學習率進行自適應約束,但是進行了計算上的簡化。 
Adagrad會累加之前所有的梯度平方,而Adadelta只累加固定大小的項,並且也不直接存儲這些項,僅僅是近似計算對應的平均值。即:
 
其中,η是學習率,gt 是梯度
在此處Adadelta其實還是依賴於全局學習率的,但是作者做了一定處理,經過近似牛頓迭代法之后:
其中,E代表求期望。此時,可以看出Adadelta已經不用依賴於全局學習率了。
tf.train.AdadeltaOptimizer(learning_rate=0.001).minimize(loss)
RMSProp 
RMSprop是對Adagrad算法的改進,主要是解決。其實思路很簡單,類似Momentum思想,引入一個衰減系數,讓梯度平方的累計量r 每回合都衰減一定比例:
其中,衰減系數ρ
decay: 衰減率
epsilon: 設置較小的值,防止分母的為 0.
tf.train.RMSPropOptimizer(learning_rate=0.001,momentum=0.9, decay=0.9, epsilon=1e-10)
優點: 
- 相比於AdaGrad,這種方法有效減少了出現梯度爆炸情況,因此避免了學習速率過快衰減的問題。 
- 適合處理非平穩目標,對於RNN效果很好
缺點: 
- 又引入了新的超參—衰減系數ρ 
- 依然依賴於全局學習速率,
總結:RMSprop算是Adagrad的一種發展,和Adadelta的變體,效果趨於二者之間。
Adam 
自適應矩估計(daptive moment estimation,Adam),是Kingma等在2015年提出的一種新的優化算法,本質上是帶有動量項的RMSprop,其結合了Momentum和RMSprop算法的思想。它利用梯度的一階矩估計 和 二階矩估計 動態調整每個參數的學習率。
具體實現每步迭代過程:
從訓練集中的隨機抽取一批容量為m的樣本{x1,…,xm},以及相關的輸出yi
計算梯度和誤差,更新r和s,再根據r和s以及梯度計算參數更新量 : 
其中,一階動量s,二階動量r(初始化為0),一階動量衰減系數ρ1, 二階動量衰減系數ρ2 
超參數的建議值是ρ1=0.9,ρ2 =0.999,epsilon: 設置較小的值,防止分母的為 0。
實踐
各種優化方法在CIFAR-10圖像識別上比較:
圖片來源:The Marginal Value of Adaptive Gradient Methods in Machine Learning
自適應優化算法在訓練前期階段在訓練集上收斂的更快,但是在測試集上反而並不理想。 
用相同數量的超參數來調參,SGD和SGD +momentum 方法性能在測試集上的額誤差好於所有的自適應優化算法,盡管有時自適應優化算法在訓練集上的loss更小,但是他們在測試集上的loss卻依然比SGD方法高, 
總結:
對於稀疏數據,優先選擇學習速率自適應的算法如RMSprop和Adam算法,而且最好采用默認值,大部分情況下其效果是較好的
SGD通常訓練時間更長,容易陷入鞍點,但是在好的初始化和學習率調度方案的情況下,結果更可靠。
如果要求更快的收斂,並且較深較復雜的網絡時,推薦使用學習率自適應的優化方法。例如對於RNN之類的網絡結構,Adam速度快,效果好,而對於CNN之類的網絡結構,SGD +momentum 的更新方法要更好(常見國際頂尖期刊常見優化方法).
Adadelta,RMSprop,Adam是比較相近的算法,在相似的情況下表現差不多。
在想使用帶動量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果。
特別注意學習速率的問題。學習速率設置得非常大,那么訓練可能不會收斂,就直接發散了;如果設置的比較小,雖然可以收斂,但是訓練時間可能無法接受。理想的學習速率是:剛開始設置較大,有很快的收斂速度,然后慢慢衰減,保證穩定到達最優
其實還有很多方面會影響梯度下降算法,如梯度的消失與爆炸,梯度下降算法目前無法保證全局收斂還將是一個持續性的數學難題。
參考:
[1]Adagrad 
[2]RMSprop[Lecture 6e] 
[3]Adadelta 
[4]Adam 
[5]Nadam 
[6]On the importance of initialization and momentum in deep learning 
————————————————
版權聲明:本文為CSDN博主「Charles_yy」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u010899985/article/details/81836299


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM