優化方法總結
參考
優化方法總結
參考
An overview of gradient descent optimization algorithms
目錄
1. SGD
3種不同的梯度下降方法,區別在於每次參數更新時計算的樣本數據量不同。
1.1 Batch gradient descent
每進行1次參數更新,需要計算整個數據樣本集:
θ=θ−η∇θJ(θ)θ=θ−η∇θJ(θ)
for i in range(nb_epochs):
params_grad = evaluate_gradient(loss_function, data, params)
params = params - learning_rate * params_grad
- 1
- 2
- 3
1.2 Stochastic gradient descent
每進行1次參數更新,只需要計算1個數據樣本:
θ=θ−η∇θJ(x(i),y(i);θ)θ=θ−η∇θJ(x(i),y(i);θ)
for i in range(nb_epochs):
np.random.shuffle(data)
for example in data:
params_grad = evaluate_gradient(loss_function, example, params)
params = params - learning_rate * params_grad
- 1
- 2
- 3
- 4
- 5
1.3 Mini-batch gradient descent
每進行1次參數更新,需要計算1個mini-batch數據樣本:
θ=θ−η∇θJ(x(i:i+n),y(i:i+n);θ)θ=θ−η∇θJ(x(i:i+n),y(i:i+n);θ)
for i in range(nb_epochs):
np.random.shuffle(data)
for batch in get_batches(data, batch_size=50):
params_grad = evaluate_gradient(loss_function, batch, params)
params = params - learning_rate * params_grad
- 1
- 2
- 3
- 4
- 5
【三種gradient descent對比】
Batch gradient descent的收斂速度太慢,而且會大量多餘的計算(比如計算相似的樣本)。
Stochastic gradient descent雖然大大加速了收斂速度,但是它的梯度下降的波動非常大(high variance)。
Mini-batch gradient descent中和了2者的優缺點,所以SGD算法通常也默認是Mini-batch gradient descent。
【Mini-batch gradient descent的缺點】
然而Mini-batch gradient descent也不能保證很好地收斂。主要有以下缺點:
選擇一個合適的learning rate是非常困難的
學習率太低會收斂緩慢,學習率過高會使收斂時的波動過大。
所有參數都是用同樣的learning rate
對於稀疏數據或特徵,有時我們希望對於不經常出現的特徵的參數更新快一些,對於常出現的特徵更新慢一些。這個時候SGD就不能滿足要求了。
sgd容易收斂到局部最優解,並且在某些情況可能被困在鞍點
在合適的初始化和step size的情況下,鞍點的影響沒那麼大。
正是因爲SGD這些缺點,纔有後續提出的各種算法。
2. Momentum
momentum利用了物理學中動量的思想,通過積累之前的動量(mt−1mt−1)來加速當前的梯度。
mt=μ∗mt−1+η∇θJ(θ)θt=θt−1−mt mt=μ∗mt−1+η∇θJ(θ)θt=θt−1−mt
其中,μμ是動量因子,通常被設置爲0.9或近似值。
【特點】
- 參數下降初期,加上前一次參數更新值;如果前後2次下降方向一致,乘上較大的μμ能夠很好的加速。
- 參數下降中後期,在局部最小值附近來回震盪時,gradient→0gradient→0,μμ使得更新幅度增大,跳出陷阱。
- 在梯度方向改變時,momentum能夠降低參數更新速度,從而減少震盪;在梯度方向相同時,momentum可以加速參數更新, 從而加速收斂。
- 總而言之,momentum能夠加速SGD收斂,抑制震盪。
3. Nesterov
Nesterov在梯度更新時做一個矯正,避免前進太快,同時提高靈敏度。
Momentum並沒有直接影響當前的梯度∇θJ(θ)∇θJ(θ),所以Nesterov的改進就是用上一次的動量(−μ∗mt−1−μ∗mt−1)當前的梯度∇θJ(θ)∇θJ(θ)做了一個矯正。
mt=μ∗mt−1+η∇θJ(θ−μ∗mt−1)θt=θt−1−mtmt=μ∗mt−1+η∇θJ(θ−μ∗mt−1)θt=θt−1−mt
Momentum與Nexterov的對比,如下圖:
Momentum:藍色向量
Momentum首先計算當前的梯度值(短的藍色向量),然後加上之前累計的梯度/動量(長的藍色向量)。
Nexterov:綠色向量
Nexterov首先先計算之前累計的梯度/動量(長的棕色向量),然後加上當前梯度值進行矯正後(−μ∗mt−1−μ∗mt−1)的梯度值(紅色向量),得到的就是最終Nexterov的更新值(綠色向量)。
Momentum和Nexterov都是爲了使梯度更新更靈活。但是人工設計的學習率總是有些生硬,下面介紹幾種自適應學習率的方法。
4. Adagrad
Adagrad是對學習率進行了一個約束。
gt=∇θJ(θ)nt=nt−1+(gt)2θt=θt−1−ηnt+ϵ√∗gt=θt−1−η∑tr=1(gr)2+ϵ√∗gtgt=∇θJ(θ)nt=nt−1+(gt)2θt=θt−1−ηnt+ϵ∗gt=θt−1−η∑r=1t(gr)2+ϵ∗gt
這個 −1∑tr=1(gr)2+ϵ√−1∑r=1t(gr)2+ϵ 是一個約束項regularizer,ηη 是一個全局學習率,ϵϵ 是一個常數,用來保證分母非 0。
【特點】
- 前期ntnt較小的時候,regularizer較大,能夠放大梯度
- 後期ntnt較大的時候,regularizer較小,能夠縮小梯度
- 中後期,分母上梯度平方的累加會越來越大,使gradient→0gradient→0,使得訓練提前結束。
【缺點】
- 由公式可以看出,仍依賴於人工設置的一個全局學習率 ηη
- ηη 設置過大的話,會使regularizer過於敏感,對梯度調節太大。
- 最重要的是,中後期分母上的梯度平方累加會越來越大,使gradient→0gradient→0,使得訓練提前結束,無法繼續學習。
Adadelta主要就針對最後1個缺點做了改進。
5. Adadelta
Adadelta依然對學習率進行了約束,但是在計算上進行了簡化。
Adagrad會累加之前所有梯度的平方,而Adadelata只需累加固定大小的項,並且也不直接存儲這些項,僅僅是計算對應的近似平均值。
gt=∇θJ(θ)nt=υ∗nt−1+(1−υ)(gt)2θt=θt−1−ηnt+ϵ√∗gtgt=∇θJ(θ)nt=υ∗nt−1+(1−υ)(gt)2θt=θt−1−ηnt+ϵ∗gt
在此處Adadelta還是依賴全局學習率的,然後作者又利用近似牛頓迭代法,做了一些改進:
E[g2]t=ρ∗E[g2]t−1+(1−ρ)∗(gt)2E[g2]t=ρ∗E[g2]t−1+(1−ρ)∗(gt)2
Δθt=−∑t−1r=1ΔθrE[g2]t+ϵ√Δθt=−∑r=1t−1ΔθrE[g2]t+ϵ
其中,E代表求期望。
此時可以看出Adadelta已經不依賴全局learning rate了。
【特點】
- 訓練初中期,加速效果不錯,很快。
- 訓練後期,反覆在局部最小值附近抖動。
6. RMSprop
RMSprop可以看做Adadelta的一個特例。
當 ρ=0.5ρ=0.5 時, E[g2]t=ρ∗E[g2]t−1+(1−ρ)∗(gt)2E[g2]t=ρ∗E[g2]t−1+(1−ρ)∗(gt)2就變爲求梯度平方和的平均數。
如果再求根的話,就變成RMS(Root Mean Squared,均方根):
RMS[g]t=E[g2]t+ϵ−−−−−−−−√RMS[g]t=E[g2]t+ϵ
此時,RMS就可以作爲學習率 ηη的一個約束:
Δθt=−ηRMS[g]t√∗gtΔθt=−ηRMS[g]t∗gt
比較好的一套參數設置爲:η=0.001,γ=0.9η=0.001,γ=0.9
【特點】
- 其實RMSprop依然依賴於全局學習率
- RMSprop的效果介於Adagrad和Adadelta之間
- 適合處理非平穩目標——對於RNN效果很好。
7. Adam
Adam(Adaptive Moment Estimation)本質上時帶有動量項的RMSprop。
mt=μ∗mt−1+(1−μ)∗gtnt=v∗nt−1+(1−v)∗(gt)2mt^=mt1−μtnt^=nt1−vtΔθt=−mt^nt^√+ϵ∗ηmt=μ∗mt−1+(1−μ)∗gtnt=v∗nt−1+(1−v)∗(gt)2mt^=mt1−μtnt^=nt1−vtΔθt=−mt^nt^+ϵ∗η
mt,ntmt,nt 分別是梯度的一階矩估計和二階矩估計,可以看作對期望E[g]t,E[g2]tE[g]t,E[g2]t的估計;
mt^,nt^mt^,nt^ 分別是對 mt,ntmt,nt 的校正,這樣可以近似爲對期望的無偏估計。
可以看出,直接對梯度的矩估計對內存沒有額外的要求,而且可以根據梯度進行動態調整,而−mt^nt^√+ϵ−mt^nt^+ϵ 對學習率形成一個動態約束,而且有明確範圍。
作者提出的默認的參數設置爲:μ=0.9,v=0.999,ϵ=10−8μ=0.9,v=0.999,ϵ=10−8
【特點】
- Adam梯度經過偏置校正後,每一次迭代學習率都有一個固定範圍,使得參數比較平穩。
- 結合了Adagrad善於處理稀疏梯度和RMSprop善於處理非平穩目標的優點
- 爲不同的參數計算不同的自適應學習率
- 也適用於大多非凸優化問題——適用於大數據集和高維空間。
8. Adamax
Adamax是Adam的一種變體,此方法對學習率的上限提供了一個更簡單的範圍。
nt=max(v∗nt−1,|gt|)Δθt=−mt^nt+ϵ∗ηnt=max(v∗nt−1,|gt|)Δθt=−mt^nt+ϵ∗η
Adamax的學習率邊界範圍更簡單
9. Nadam
Nadam類似於帶有Nexterov動量項的Adam。
gt^=gt1−∏ti=1μigt^=gt1−∏i=1tμi
mt=μt∗mt−1+(1−μt)∗gtmt=μt∗mt−1+(1−μt)∗gt
mt^=mt1−∏t+1i=1μimt^=mt1−∏i=1t+1μi
nt=v∗nt−1+(1−v)∗(gt)2nt=v∗nt−1+(1−v)∗(gt)2
nt^=nt1−vtmt^=(1−μt)∗gt^+μt+1∗mt^nt^=nt1−vtmt^=(1−μt)∗gt^+μt+1∗mt^
Δθt=−mt^nt^√+ϵ∗ηΔθt=−mt^nt^+ϵ∗η
可以看出,Nadam對學習率有更強的約束,同時對梯度的更新也有更直接的影響。
一般而言,在使用帶動量的RMSprop或Adam的問題上,使用Nadam可以取得更好的結果。
經驗之談
幾種算法下降過程的可視化
算法的梯度下降過程對比:
可以看到:
Adagrad,Adadelta和RMSprop都是非常快到達右邊的最優解,而這個時候Momentum和NAG纔開始下降,而且剛開始的下降速度很慢。但是很快NAG就會找到正確的下降方向並且更加速的接近最優解。
SGD下降的最慢了,但是下降的方向總是最正確的。
在鞍點(saddle point)處的對比:
可以看到:
SGD被困在鞍點了,沒法繼續優化。
SGD,Momentum和NAG都在鞍點來回晃動,但最終Momentum和NAG逃離了鞍點。
但是與此同時,Adagrad,RMSprop和Adadelta很快的就離開了鞍點。
優化算法的選擇
- 對於稀疏數據,儘量使用學習率可自適應的算法,不用手動調節,而且最好採用默認參數
- SGD通常訓練時間最長,但是在好的初始化和學習率調度方案下,結果往往更可靠。但SGD容易困在鞍點,這個缺點也不能忽略。
- 如果在意收斂的速度,並且需要訓練比較深比較複雜的網絡時,推薦使用學習率自適應的優化方法。
- Adagrad,Adadelta和RMSprop是比較相近的算法,表現都差不多。
- 在能使用帶動量的RMSprop或者Adam的地方,使用Nadam往往能取得更好的效果。
【學習率自適應的優化算法】:
Adagrad, Adadelta, RMSprop, Adam, Adamax, Nadam
優化SGD的其他策略
Shuffling and Curriculum Learning
Shuffling就是打亂數據,每一次epoch之後 shuffle一次數據,可以避免訓練樣本的先後次序影響優化的結果。
但另一方面,在有些問題上,給訓練數據一個有意義的順序,可能會得到更好的性能和更好的收斂。這種給訓練數據建立有意義的順序的方法被叫做Curriculum Learning。
Batch Normalization
爲了有效的學習參數,我們一般在一開始把參數初始化成0均值和單位方差。但是在訓練過程中,參數會被更新到不同的數值範圍,使得normalization的效果消失,從而導致訓練速度變慢或梯度爆炸等等問題(當網絡越來越深的時候)。
BN給每個batch的數據恢復了normalization,同時這些對數據的更改都是可還原的,即normalization了中間層的參數,又沒有丟失中間層的表達能力。
使用BN之後,我們就可以使用更高的學習率,也不用再在參數初始化上花費那麼多注意力。
BN還有正則化的作用,同時也削弱了對Dropout的需求。
Early Stopping
在訓練的時候我們會監控validation的誤差,並且會(要有耐心)提前停止訓練,如果驗證集的error沒有很大的改進。
Gradient noise
在梯度更新的時候加一個高斯噪聲:
gt,i=gt,i+N(0,σ2t)gt,i=gt,i+N(0,σt2)
方差值的初始化策略是:
σ2t=η(1+t)γσt2=η(1+t)γ
Neelakantan等人表明,噪聲使得網絡的魯棒性更好,而且對於深度複雜的網絡訓練很有幫助。
他們猜想添加了噪聲之後,會使得模型有更多機會逃離局部最優解(深度模型經常容易陷入局部最優解)
An overview of gradient descent optimization algorithms
目錄
1. SGD
3種不同的梯度下降方法,區別在於每次參數更新時計算的樣本數據量不同。
1.1 Batch gradient descent
每進行1次參數更新,需要計算整個數據樣本集:
θ=θ−η∇θJ(θ)θ=θ−η∇θJ(θ)
for i in range(nb_epochs):
params_grad = evaluate_gradient(loss_function, data, params)
params = params - learning_rate * params_grad
- 1
- 2
- 3
1.2 Stochastic gradient descent
每進行1次參數更新,只需要計算1個數據樣本:
θ=θ−η∇θJ(x(i),y(i);θ)θ=θ−η∇θJ(x(i),y(i);θ)
for i in range(nb_epochs):
np.random.shuffle(data)
for example in data:
params_grad = evaluate_gradient(loss_function, example, params)
params = params - learning_rate * params_grad
- 1
- 2
- 3
- 4
- 5
1.3 Mini-batch gradient descent
每進行1次參數更新,需要計算1個mini-batch數據樣本:
θ=θ−η∇θJ(x(i:i+n),y(i:i+n);θ)θ=θ−η∇θJ(x(i:i+n),y(i:i+n);θ)
for i in range(nb_epochs):
np.random.shuffle(data)
for batch in get_batches(data, batch_size=50):
params_grad = evaluate_gradient(loss_function, batch, params)
params = params - learning_rate * params_grad
- 1
- 2
- 3
- 4
- 5
【三種gradient descent對比】
Batch gradient descent的收斂速度太慢,而且會大量多餘的計算(比如計算相似的樣本)。
Stochastic gradient descent雖然大大加速了收斂速度,但是它的梯度下降的波動非常大(high variance)。
Mini-batch gradient descent中和了2者的優缺點,所以SGD算法通常也默認是Mini-batch gradient descent。
【Mini-batch gradient descent的缺點】
然而Mini-batch gradient descent也不能保證很好地收斂。主要有以下缺點:
選擇一個合適的learning rate是非常困難的
學習率太低會收斂緩慢,學習率過高會使收斂時的波動過大。
所有參數都是用同樣的learning rate
對於稀疏數據或特徵,有時我們希望對於不經常出現的特徵的參數更新快一些,對於常出現的特徵更新慢一些。這個時候SGD就不能滿足要求了。
sgd容易收斂到局部最優解,並且在某些情況可能被困在鞍點
在合適的初始化和step size的情況下,鞍點的影響沒那麼大。
正是因爲SGD這些缺點,纔有後續提出的各種算法。
2. Momentum
momentum利用了物理學中動量的思想,通過積累之前的動量(mt−1mt−1)來加速當前的梯度。
mt=μ∗mt−1+η∇θJ(θ)θt=θt−1−mt mt=μ∗mt−1+η∇θJ(θ)θt=θt−1−mt
其中,μμ是動量因子,通常被設置爲0.9或近似值。
【特點】
- 參數下降初期,加上前一次參數更新值;如果前後2次下降方向一致,乘上較大的μμ能夠很好的加速。
- 參數下降中後期,在局部最小值附近來回震盪時,gradient→0gradient→0,μμ使得更新幅度增大,跳出陷阱。
- 在梯度方向改變時,momentum能夠降低參數更新速度,從而減少震盪;在梯度方向相同時,momentum可以加速參數更新, 從而加速收斂。
- 總而言之,momentum能夠加速SGD收斂,抑制震盪。
3. Nesterov
Nesterov在梯度更新時做一個矯正,避免前進太快,同時提高靈敏度。
Momentum並沒有直接影響當前的梯度∇θJ(θ)∇θJ(θ),所以Nesterov的改進就是用上一次的動量(−μ∗mt−1−μ∗mt−1)當前的梯度∇θJ(θ)∇θJ(θ)做了一個矯正。
mt=μ∗mt−1+η∇θJ(θ−μ∗mt−1)θt=θt−1−mtmt=μ∗mt−1+η∇θJ(θ−μ∗mt−1)θt=θt−1−mt
Momentum與Nexterov的對比,如下圖:
Momentum:藍色向量
Momentum首先計算當前的梯度值(短的藍色向量),然後加上之前累計的梯度/動量(長的藍色向量)。
Nexterov:綠色向量
Nexterov首先先計算之前累計的梯度/動量(長的棕色向量),然後加上當前梯度值進行矯正後(−μ∗mt−1−μ∗mt−1)的梯度值(紅色向量),得到的就是最終Nexterov的更新值(綠色向量)。
Momentum和Nexterov都是爲了使梯度更新更靈活。但是人工設計的學習率總是有些生硬,下面介紹幾種自適應學習率的方法。
4. Adagrad
Adagrad是對學習率進行了一個約束。
gt=∇θJ(θ)nt=nt−1+(gt)2θt=θt−1−ηnt+ϵ√∗gt=θt−1−η∑tr=1(gr)2+ϵ√∗gtgt=∇θJ(θ)nt=nt−1+(gt)2θt=θt−1−ηnt+ϵ∗gt=θt−1−η∑r=1t(gr)2+ϵ∗gt
這個 −1∑tr=1(gr)2+ϵ√−1∑r=1t(gr)2+ϵ 是一個約束項regularizer,ηη 是一個全局學習率,ϵϵ 是一個常數,用來保證分母非 0。
【特點】
- 前期ntnt較小的時候,regularizer較大,能夠放大梯度
- 後期ntnt較大的時候,regularizer較小,能夠縮小梯度
- 中後期,分母上梯度平方的累加會越來越大,使gradient→0gradient→0,使得訓練提前結束。
【缺點】
- 由公式可以看出,仍依賴於人工設置的一個全局學習率 ηη
- ηη 設置過大的話,會使regularizer過於敏感,對梯度調節太大。
- 最重要的是,中後期分母上的梯度平方累加會越來越大,使gradient→0gradient→0,使得訓練提前結束,無法繼續學習。
Adadelta主要就針對最後1個缺點做了改進。
5. Adadelta
Adadelta依然對學習率進行了約束,但是在計算上進行了簡化。
Adagrad會累加之前所有梯度的平方,而Adadelata只需累加固定大小的項,並且也不直接存儲這些項,僅僅是計算對應的近似平均值。
gt=∇θJ(θ)nt=υ∗nt−1+(1−υ)(gt)2θt=θt−1−ηnt+ϵ√∗gtgt=∇θJ(θ)nt=υ∗nt−1+(1−υ)(gt)2θt=θt−1−ηnt+ϵ∗gt
在此處Adadelta還是依賴全局學習率的,然後作者又利用近似牛頓迭代法,做了一些改進:
E[g2]t=ρ∗E[g2]t−1+(1−ρ)∗(gt)2E[g2]t=ρ∗E[g2]t−1+(1−ρ)∗(gt)2
Δθt=−∑t−1r=1ΔθrE[g2]t+ϵ√Δθt=−∑r=1t−1ΔθrE[g2]t+ϵ
其中,E代表求期望。
此時可以看出Adadelta已經不依賴全局learning rate了。
【特點】
- 訓練初中期,加速效果不錯,很快。
- 訓練後期,反覆在局部最小值附近抖動。
6. RMSprop
RMSprop可以看做Adadelta的一個特例。
當 ρ=0.5ρ=0.5 時, E[g2]t=ρ∗E[g2]t−1+(1−ρ)∗(gt)2E[g2]t=ρ∗E[g2]t−1+(1−ρ)∗(gt)2就變爲求梯度平方和的平均數。
如果再求根的話,就變成RMS(Root Mean Squared,均方根):
RMS[g]t=E[g2]t+ϵ−−−−−−−−√RMS[g]t=E[g2]t+ϵ
此時,RMS就可以作爲學習率 ηη的一個約束:
Δθt=−ηRMS[g]t√∗gtΔθt=−ηRMS[g]t∗gt
比較好的一套參數設置爲:η=0.001,γ=0.9η=0.001,γ=0.9
【特點】
- 其實RMSprop依然依賴於全局學習率
- RMSprop的效果介於Adagrad和Adadelta之間
- 適合處理非平穩目標——對於RNN效果很好。
7. Adam
Adam(Adaptive Moment Estimation)本質上時帶有動量項的RMSprop。
mt=μ∗mt−1+(1−μ)∗gtnt=v∗nt−1+(1−v)∗(gt)2mt^=mt1−μtnt^=nt1−vtΔθt=−mt^nt^√+ϵ∗ηmt=μ∗mt−1+(1−μ)∗gtnt=v∗nt−1+(1−v)∗(gt)2mt^=mt1−μtnt^=nt1−vtΔθt=−mt^nt^+ϵ∗η
mt,ntmt,nt 分別是梯度的一階矩估計和二階矩估計,可以看作對期望E[g]t,E[g2]tE[g]t,E[g2]t的估計;
mt^,nt^mt^,nt^ 分別是對 mt,ntmt,nt 的校正,這樣可以近似爲對期望的無偏估計。
可以看出,直接對梯度的矩估計對內存沒有額外的要求,而且可以根據梯度進行動態調整,而−mt^nt^√+ϵ−mt^nt^+ϵ 對學習率形成一個動態約束,而且有明確範圍。
作者提出的默認的參數設置爲:μ=0.9,v=0.999,ϵ=10−8μ=0.9,v=0.999,ϵ=10−8
【特點】
- Adam梯度經過偏置校正後,每一次迭代學習率都有一個固定範圍,使得參數比較平穩。
- 結合了Adagrad善於處理稀疏梯度和RMSprop善於處理非平穩目標的優點
- 爲不同的參數計算不同的自適應學習率
- 也適用於大多非凸優化問題——適用於大數據集和高維空間。
8. Adamax
Adamax是Adam的一種變體,此方法對學習率的上限提供了一個更簡單的範圍。
nt=max(v∗nt−1,|gt|)Δθt=−mt^nt+ϵ∗ηnt=max(v∗nt−1,|gt|)Δθt=−mt^nt+ϵ∗η
Adamax的學習率邊界範圍更簡單
9. Nadam
Nadam類似於帶有Nexterov動量項的Adam。
gt^=gt1−∏ti=1μigt^=gt1−∏i=1tμi
mt=μt∗mt−1+(1−μt)∗gtmt=μt∗mt−1+(1−μt)∗gt
mt^=mt1−∏t+1i=1μimt^=mt1−∏i=1t+1μi
nt=v∗nt−1+(1−v)∗(gt)2nt=v∗nt−1+(1−v)∗(gt)2
nt^=nt1−vtmt^=(1−μt)∗gt^+μt+1∗mt^nt^=nt1−vtmt^=(1−μt)∗gt^+μt+1∗mt^
Δθt=−mt^nt^√+ϵ∗ηΔθt=−mt^nt^+ϵ∗η
可以看出,Nadam對學習率有更強的約束,同時對梯度的更新也有更直接的影響。
一般而言,在使用帶動量的RMSprop或Adam的問題上,使用Nadam可以取得更好的結果。
經驗之談
幾種算法下降過程的可視化
算法的梯度下降過程對比:
可以看到:
Adagrad,Adadelta和RMSprop都是非常快到達右邊的最優解,而這個時候Momentum和NAG纔開始下降,而且剛開始的下降速度很慢。但是很快NAG就會找到正確的下降方向並且更加速的接近最優解。
SGD下降的最慢了,但是下降的方向總是最正確的。
在鞍點(saddle point)處的對比:
可以看到:
SGD被困在鞍點了,沒法繼續優化。
SGD,Momentum和NAG都在鞍點來回晃動,但最終Momentum和NAG逃離了鞍點。
但是與此同時,Adagrad,RMSprop和Adadelta很快的就離開了鞍點。
優化算法的選擇
- 對於稀疏數據,儘量使用學習率可自適應的算法,不用手動調節,而且最好採用默認參數
- SGD通常訓練時間最長,但是在好的初始化和學習率調度方案下,結果往往更可靠。但SGD容易困在鞍點,這個缺點也不能忽略。
- 如果在意收斂的速度,並且需要訓練比較深比較複雜的網絡時,推薦使用學習率自適應的優化方法。
- Adagrad,Adadelta和RMSprop是比較相近的算法,表現都差不多。
- 在能使用帶動量的RMSprop或者Adam的地方,使用Nadam往往能取得更好的效果。
【學習率自適應的優化算法】:
Adagrad, Adadelta, RMSprop, Adam, Adamax, Nadam
優化SGD的其他策略
Shuffling and Curriculum Learning
Shuffling就是打亂數據,每一次epoch之後 shuffle一次數據,可以避免訓練樣本的先後次序影響優化的結果。
但另一方面,在有些問題上,給訓練數據一個有意義的順序,可能會得到更好的性能和更好的收斂。這種給訓練數據建立有意義的順序的方法被叫做Curriculum Learning。
Batch Normalization
爲了有效的學習參數,我們一般在一開始把參數初始化成0均值和單位方差。但是在訓練過程中,參數會被更新到不同的數值範圍,使得normalization的效果消失,從而導致訓練速度變慢或梯度爆炸等等問題(當網絡越來越深的時候)。
BN給每個batch的數據恢復了normalization,同時這些對數據的更改都是可還原的,即normalization了中間層的參數,又沒有丟失中間層的表達能力。
使用BN之後,我們就可以使用更高的學習率,也不用再在參數初始化上花費那麼多注意力。
BN還有正則化的作用,同時也削弱了對Dropout的需求。
Early Stopping
在訓練的時候我們會監控validation的誤差,並且會(要有耐心)提前停止訓練,如果驗證集的error沒有很大的改進。
Gradient noise
在梯度更新的時候加一個高斯噪聲:
gt,i=gt,i+N(0,σ2t)gt,i=gt,i+N(0,σt2)
方差值的初始化策略是:
σ2t=η(1+t)γσt2=η(1+t)γ
Neelakantan等人表明,噪聲使得網絡的魯棒性更好,而且對於深度複雜的網絡訓練很有幫助。
他們猜想添加了噪聲之後,會使得模型有更多機會逃離局部最優解(深度模型經常容易陷入局部最優解)