轉:深度學習筆記:優化方法總結(BGD,SGD,Momentum,AdaGrad,RMSProp,Adam)

xuxiatian發表於2017-06-12

from:http://blog.csdn.net/u014595019/article/details/52989301

最近在看Google的Deep Learning一書,看到優化方法那一部分,正巧之前用tensorflow也是對那些優化方法一知半解的,所以看完後就整理了下放上來,主要是一階的梯度法,包括SGD, Momentum, Nesterov Momentum, AdaGrad, RMSProp, Adam。 其中SGD,Momentum,Nesterov Momentum是手動指定學習速率的,而後面的AdaGrad, RMSProp, Adam,就能夠自動調節學習速率. 
二階的方法目前我水平太差,看不懂….就不放上來了。


BGD

即batch gradient descent. 在訓練中,每一步迭代都使用訓練集的所有內容. 也就是說,利用現有引數對訓練集中的每一個輸入生成一個估計輸出yi^,然後跟實際輸出yi比較,統計所有誤差,求平均以後得到平均誤差,以此來作為更新引數的依據.

具體實現: 
需要:學習速率 ϵ, 初始引數 θ 
每步迭代過程: 
1. 提取訓練集中的所有內容{x1,,xn},以及相關的輸出yi 
2. 計算梯度和誤差並更新引數: 

g^+1nθiL(f(xi;θ),yi)θθϵg^

優點: 
由於每一步都利用了訓練集中的所有資料,因此當損失函式達到最小值以後,能夠保證此時計算出的梯度為0,換句話說,就是能夠收斂.因此,使用BGD時不需要逐漸減小學習速率ϵk

缺點: 
由於每一步都要使用所有資料,因此隨著資料集的增大,執行速度會越來越慢.


SGD

SGD全名 stochastic gradient descent, 即隨機梯度下降。不過這裡的SGD其實跟MBGD(minibatch gradient descent)是一個意思,即隨機抽取一批樣本,以此為根據來更新引數.

具體實現: 
需要:學習速率 ϵ, 初始引數 θ 
每步迭代過程: 
1. 從訓練集中的隨機抽取一批容量為m的樣本{x1,,xm},以及相關的輸出yi 
2. 計算梯度和誤差並更新引數: 

g^+1mθiL(f(xi;θ),yi)θθϵg^

優點: 
訓練速度快,對於很大的資料集,也能夠以較快的速度收斂.

缺點: 
由於是抽取,因此不可避免的,得到的梯度肯定有誤差.因此學習速率需要逐漸減小.否則模型無法收斂 
因為誤差,所以每一次迭代的梯度受抽樣的影響比較大,也就是說梯度含有比較大的噪聲,不能很好的反映真實梯度.

學習速率該如何調整: 
那麼這樣一來,ϵ如何衰減就成了問題.如果要保證SGD收斂,應該滿足如下兩個要求: 

k=1ϵk=k=1ϵ2k<

而在實際操作中,一般是進行線性衰減: 
ϵk=(1α)ϵ0+αϵτα=kτ

其中ϵ0是初始學習率, ϵτ是最後一次迭代的學習率. τ自然代表迭代次數.一般來說,ϵτ 設為ϵ0的1%比較合適.而τ一般設為讓訓練集中的每個資料都輸入模型上百次比較合適.那麼初始學習率ϵ0怎麼設定呢?書上說,你先用固定的學習速率迭代100次,找出效果最好的學習速率,然後ϵ0設為比它大一點就可以了.


Momentum

上面的SGD有個問題,就是每次迭代計算的梯度含有比較大的噪音. 而Momentum方法可以比較好的緩解這個問題,尤其是在面對小而連續的梯度但是含有很多噪聲的時候,可以很好的加速學習.Momentum借用了物理中的動量概念,即前幾次的梯度也會參與運算.為了表示動量,引入了一個新的變數v(velocity).v是之前的梯度的累加,但是每回合都有一定的衰減.

具體實現: 
需要:學習速率 ϵ, 初始引數 θ, 初始速率v, 動量衰減引數α 
每步迭代過程: 
1. 從訓練集中的隨機抽取一批容量為m的樣本{x1,,xm},以及相關的輸出yi 
2. 計算梯度和誤差,並更新速度v和引數θ

g^+1mθiL(f(xi;θ),yi)vαvϵg^θθ+v

其中引數α表示每回合速率v的衰減程度.同時也可以推斷得到,如果每次迭代得到的梯度都是g,那麼最後得到的v的穩定值為 

ϵg1α

也就是說,Momentum最好情況下能夠將學習速率加速11α倍.一般α的取值有0.5,0.9,0.99這幾種.當然,也可以讓α的值隨著時間而變化,一開始小點,後來再加大.不過這樣一來,又會引進新的引數.

特點: 
前後梯度方向一致時,能夠加速學習 
前後梯度方向不一致時,能夠抑制震盪


Nesterov Momentum

這是對之前的Momentum的一種改進,大概思路就是,先對引數進行估計,然後使用估計後的引數來計算誤差

具體實現: 
需要:學習速率 ϵ, 初始引數 θ, 初始速率v, 動量衰減引數α 
每步迭代過程: 
1. 從訓練集中的隨機抽取一批容量為m的樣本{x1,,xm},以及相關的輸出yi 
2. 計算梯度和誤差,並更新速度v和引數θ

g^+1mθiL(f(xi;θ+αv),yi)vαvϵg^θθ+v

注意在估算g^的時候,引數變成了θ+αv而不是之前的θ


AdaGrad

AdaGrad可以自動變更學習速率,只是需要設定一個全域性的學習速率ϵ,但是這並非是實際學習速率,實際的速率是與以往引數的模之和的開方成反比的.也許說起來有點繞口,不過用公式來表示就直白的多: 

ϵn=ϵδ+n1i=1gigi

其中δ是一個很小的常亮,大概在107,防止出現除以0的情況.

具體實現: 
需要:全域性學習速率 ϵ, 初始引數 θ, 數值穩定量δ 
中間變數: 梯度累計量r(初始化為0) 
每步迭代過程: 
1. 從訓練集中的隨機抽取一批容量為m的樣本{x1,,xm},以及相關的輸出yi 
2. 計算梯度和誤差,更新r,再根據r和梯度計算引數更新量 

g^+1mθiL(f(xi;θ),yi)rr+g^g^θ=ϵδ+rg^θθ+θ

優點: 
能夠實現學習率的自動更改。如果這次梯度大,那麼學習速率衰減的就快一些;如果這次梯度小,那麼學習速率衰減的就滿一些。

缺點: 
任然要設定一個變數ϵ 
經驗表明,在普通演算法中也許效果不錯,但在深度學習中,深度過深時會造成訓練提前結束。


RMSProp

RMSProp通過引入一個衰減係數,讓r每回合都衰減一定比例,類似於Momentum中的做法。

具體實現: 
需要:全域性學習速率 ϵ, 初始引數 θ, 數值穩定量δ,衰減速率ρ 
中間變數: 梯度累計量r(初始化為0) 
每步迭代過程: 
1. 從訓練集中的隨機抽取一批容量為m的樣本{x1,,xm},以及相關的輸出yi 
2. 計算梯度和誤差,更新r,再根據r和梯度計算引數更新量 

g^+1mθiL(f(xi;θ),yi)rρr+(1ρ)g^g^θ=ϵδ+rg^θθ+θ

優點: 
相比於AdaGrad,這種方法很好的解決了深度學習中過早結束的問題 
適合處理非平穩目標,對於RNN效果很好

缺點: 
又引入了新的超參,衰減係數ρ 
依然依賴於全域性學習速率


RMSProp with Nesterov Momentum

當然,也有將RMSProp和Nesterov Momentum結合起來的

具體實現: 
需要:全域性學習速率 ϵ, 初始引數 θ, 初始速率v,動量衰減係數α, 梯度累計量衰減速率ρ 
中間變數: 梯度累計量r(初始化為0) 
每步迭代過程: 
1. 從訓練集中的隨機抽取一批容量為m的樣本{x1,,xm},以及相關的輸出yi 
2. 計算梯度和誤差,更新r,再根據r和梯度計算引數更新量 

θ~θ+αvg^+1mθ~iL(f(xi;θ~),yi)rρr+(1ρ)g^g^vαvϵrg^θθ+v


Adam

Adam(Adaptive Moment Estimation)本質上是帶有動量項的RMSprop,它利用梯度的一階矩估計和二階矩估計動態調整每個引數的學習率。Adam的優點主要在於經過偏置校正後,每一次迭代學習率都有個確定範圍,使得引數比較平穩。

具體實現: 
需要:步進值 ϵ, 初始引數 θ, 數值穩定量δ,一階動量衰減係數ρ1, 二階動量衰減係數ρ2 
其中幾個取值一般為:δ=108,ρ1=0.9,ρ2=0.999 
中間變數:一階動量s,二階動量r,都初始化為0 
每步迭代過程: 
1. 從訓練集中的隨機抽取一批容量為m的樣本{x1,,xm},以及相關的輸出yi 
2. 計算梯度和誤差,更新r和s,再根據r和s以及梯度計算引數更新量 

g+1mθiL(f(xi;θ),yi)sρ1s+(1ρ1)grρ2r+(1ρ2)ggs^s1ρ1r^r1ρ2θ=ϵs^r^+δθθ+θ

相關文章