Tensorflow-各種優化器總結與比較
優化器總結
機器學習中,有很多優化方法來試圖尋找模型的最優解。比如神經網路中可以採取最基本的梯度下降法。
梯度下降法(Gradient Descent)
梯度下降法是最基本的一類優化器,目前主要分為三種梯度下降法:標準梯度下降法(GD, Gradient Descent),隨機梯度下降法(SGD, Stochastic Gradient Descent)及批量梯度下降法(BGD, Batch Gradient Descent)。
標準梯度下降法(GD)
- 假設要學習訓練的模型引數為WW,代價函式為J(W)J(W),則代價函式關於模型引數的偏導數即相關梯度為ΔJ(W)ΔJ(W),學習率為ηtηt,則使用梯度下降法更新引數為:
- 從表示式來看,模型引數的更新調整,與代價函式關於模型引數的梯度有關,即沿著梯度的方向不斷減小模型引數,從而最小化代價函式。
- 基本策略可以理解為”在有限視距內尋找最快路徑下山“,因此每走一步,參考當前位置最陡的方向(即梯度)進而邁出下一步。可以形象的表示為:
評價:標準梯度下降法主要有兩個缺點:
- 訓練速度慢:每走一步都要要計算調整下一步的方向,下山的速度變慢。在應用於大型資料集中,每輸入一個樣本都要更新一次引數,且每次迭代都要遍歷所有的樣本。會使得訓練過程及其緩慢,需要花費很長時間才能得到收斂解。
- 容易陷入區域性最優解:由於是在有限視距內尋找下山的反向。當陷入平坦的窪地,會誤以為到達了山地的最低點,從而不會繼續往下走。所謂的區域性最優解就是鞍點。落入鞍點,梯度為0,使得模型引數不在繼續更新。
批量梯度下降法(BGD)
- 假設批量訓練樣本總數為nn,每次輸入和輸出的樣本分別為X(i),Y(i)X(i),Y(i),模型引數為WW,代價函式為J(W)J(W),每輸入一個樣本ii代價函式關於WW的梯度為ΔJi(Wt,X(i),Y(i))ΔJi(Wt,X(i),Y(i)),學習率為ηtηt,則使用批量梯度下降法更新引數表示式為:
其中,WtWt表示tt時刻的模型引數。 - 從表示式來看,模型引數的調整更新與全部輸入樣本的代價函式的和(即批量/全域性誤差)有關。即每次權值調整發生在批量樣本輸入之後,而不是每輸入一個樣本就更新一次模型引數。這樣就會大大加快訓練速度。
- 基本策略可以理解為,在下山之前掌握了附近的地勢情況,選擇總體平均梯度最小的方向下山。
評價:
- 批量梯度下降法比標準梯度下降法訓練時間短,且每次下降的方向都很正確。
隨機梯度下降法(SGD)
- 對比批量梯度下降法,假設從一批訓練樣本nn中隨機選取一個樣本isis。模型引數為WW,代價函式為J(W)J(W),梯度為ΔJ(W)ΔJ(W),學習率為ηtηt,則使用隨機梯度下降法更新引數表示式為:
- E(gt)=ΔJ(Wt)E(gt)=ΔJ(Wt),這裡雖然引入了隨機性和噪聲,但期望仍然等於正確的梯度下降。
- 基本策略可以理解為隨機梯度下降像是一個盲人下山,不用每走一步計算一次梯度,但是他總能下到山底,只不過過程會顯得扭扭曲曲。
評價:
- 優點:
- 雖然SGD需要走很多步的樣子,但是對梯度的要求很低(計算梯度快)。而對於引入噪聲,大量的理論和實踐工作證明,只要噪聲不是特別大,SGD都能很好地收斂。
- 應用大型資料集時,訓練速度很快。比如每次從百萬資料樣本中,取幾百個資料點,算一個SGD梯度,更新一下模型引數。相比於標準梯度下降法的遍歷全部樣本,每輸入一個樣本更新一次引數,要快得多。
- 缺點:
- SGD在隨機選擇梯度的同時會引入噪聲,使得權值更新的方向不一定正確。
- 此外,SGD也沒能單獨克服區域性最優解的問題
動量優化法
動量優化方法是在梯度下降法的基礎上進行的改變,具有加速梯度下降的作用。一般有標準動量優化方法Momentum、NAG(Nesterov accelerated gradient)動量優化方法。
NAG在Tensorflow中與Momentum合併在同一函式tf.train.MomentumOptimizer中,可以通過引數配置啟用。
Momentum
- 使用動量(Momentum)的隨機梯度下降法(SGD),主要思想是引入一個積攢歷史梯度資訊動量來加速SGD。
- 從訓練集中取一個大小為nn的小批量{X(1),X(2),...,X(n)}{X(1),X(2),...,X(n)}樣本,對應的真實值分別為Y(i)Y(i),則Momentum優化表示式為:
- 動量主要解決SGD的兩個問題:一是隨機梯度的方法(引入的噪聲);二是Hessian矩陣病態問題(可以理解為SGD在收斂過程中和正確梯度相比來回擺動比較大的問題)。
- 理解策略為:由於當前權值的改變會受到上一次權值改變的影響,類似於小球向下滾動的時候帶上了慣性。這樣可以加快小球向下滾動的速度。
NAG
- 牛頓加速梯度(NAG, Nesterov accelerated gradient)演算法,是Momentum動量演算法的變種。更新模型引數表示式如下:
- Nesterov動量梯度的計算在模型引數施加當前速度之後,因此可以理解為往標準動量中添加了一個校正因子。
- 理解策略:在Momentun中小球會盲目地跟從下坡的梯度,容易發生錯誤。所以需要一個更聰明的小球,能提前知道它要去哪裡,還要知道走到坡底的時候速度慢下來而不是又衝上另一個坡。計算Wt−αvt−1Wt−αvt−1可以表示小球下一個位置大概在哪裡。從而可以提前知道下一個位置的梯度,然後使用到當前位置來更新引數。
- 在凸批量梯度的情況下,Nesterov動量將額外誤差收斂率從O(1/k)(k步後)O(1/k)(k步後)改進到O(1/k2)O(1/k2)。然而,在隨機梯度情況下,Nesterov動量對收斂率的作用卻不是很大。
自適應學習率優化演算法
自適應學習率優化演算法針對於機器學習模型的學習率,傳統的優化演算法要麼將學習率設定為常數要麼根據訓練次數調節學習率。極大忽視了學習率其他變化的可能性。然而,學習率對模型的效能有著顯著的影響,因此需要採取一些策略來想辦法更新學習率,從而提高訓練速度。
目前的自適應學習率優化演算法主要有:AdaGrad演算法,RMSProp演算法,Adam演算法以及AdaDelta演算法。
AdaGrad演算法
思想:
- AdaGrad演算法,獨立地適應所有模型引數的學習率,縮放每個引數反比於其所有梯度歷史平均值總和的平方根。具有代價函式最大梯度的引數相應地有個快速下降的學習率,而具有小梯度的引數在學習率上有相對較小的下降。
演算法描述:
- AdaGrad演算法優化策略一般可以表示為:
假定一個多分類問題,ii表示第ii個分類,tt表示第tt迭代同時也表示分類ii累計出現的次數。η0η0表示初始的學習率取值一般為0.01,ϵϵ是一個取值很小的數(一般為1e-8)為了避免分母為0。WtWt表示tt時刻即第tt迭代模型的引數,gt,i=ΔJ(Wt,i)gt,i=ΔJ(Wt,i)表示tt時刻,指定分類ii,代價函式J(⋅)J(⋅)關於WW的梯度。 - 從表示式可以看出,對出現比較多的類別資料,Adagrad給予越來越小的學習率,而對於比較少的類別資料,會給予較大的學習率。因此Adagrad適用於資料稀疏或者分佈不平衡的資料集。
- Adagrad 的主要優勢在於不需要人為的調節學習率,它可以自動調節;缺點在於,隨著迭代次數增多,學習率會越來越小,最終會趨近於0。
RMSProp演算法
思想:
- RMSProp演算法修改了AdaGrad的梯度積累為指數加權的移動平均,使得其在非凸設定下效果更好。
演算法描述:
- RMSProp演算法的一般策略可以表示為:
- RMSProp借鑑了Adagrad的思想,觀察表示式,分母為E[g2]t+ϵ−−−−−−−−√E[g2]t+ϵ。由於取了個加權平均,避免了學習率越來越低的的問題,而且能自適應地調節學習率。
- RMSProp演算法在經驗上已經被證明是一種有效且實用的深度神經網路優化演算法。目前它是深度學習從業者經常採用的優化方法之一。
AdaDelta演算法
思想:AdaGrad演算法和RMSProp演算法都需要指定全域性學習率,AdaDelta演算法結合兩種演算法每次引數的更新步長即:
- 從表示式可以看出,AdaDelta不需要設定一個預設的全域性學習率。
評價:
- 在模型訓練的初期和中期,AdaDelta表現很好,加速效果不錯,訓練速度快。
- 在模型訓練的後期,模型會反覆地在區域性最小值附近抖動。
Adam演算法
思想:
- 首先,Adam中動量直接併入了梯度一階矩(指數加權)的估計。其次,相比於缺少修正因子導致二階矩估計可能在訓練初期具有很高偏置的RMSProp,Adam包括偏置修正,修正從原點初始化的一階矩(動量項)和(非中心的)二階矩估計。
演算法描述:
評價:Adam通常被認為對超引數的選擇相當魯棒,儘管學習率有時需要從建議的預設修改。
各種優化器的比較
終於結束的漫長的理論分析,下面對各種優化器做一些有趣的比較。
視覺化比較
(1) 示例一
上圖描述了在一個曲面上,6種優化器的表現,從中可以大致看出:
① 下降速度:
- 三個自適應學習優化器Adagrad、RMSProp與AdaDelta的下降速度明顯比SGD要快,其中,Adagrad和RMSProp齊頭並進,要比AdaDelta要快。
- 兩個動量優化器Momentum和NAG由於剛開始走了岔路,初期下降的慢;隨著慢慢調整,下降速度越來越快,其中NAG到後期甚至超過了領先的Adagrad和RMSProp。
② 下降軌跡:
- SGD和三個自適應優化器軌跡大致相同。兩個動量優化器初期走了“岔路”,後期也調整了過來。
(2) 示例二
上圖在一個存在鞍點的曲面,比較6中優化器的效能表現,從圖中大致可以看出:
- 三個自適應學習率優化器沒有進入鞍點,其中,AdaDelta下降速度最快,Adagrad和RMSprop則齊頭並進。
- 兩個動量優化器Momentum和NAG以及SGD都順勢進入了鞍點。但兩個動量優化器在鞍點抖動了一會,就逃離了鞍點並迅速地下降,後來居上超過了Adagrad和RMSProp。
- 很遺憾,SGD進入了鞍點,卻始終停留在了鞍點,沒有再繼續下降。
(3) 示例三
上圖比較了6種優化器收斂到目標點(五角星)的執行過程,從圖中可以大致看出:
① 在執行速度方面
- 兩個動量優化器Momentum和NAG的速度最快,其次是三個自適應學習率優化器AdaGrad、AdaDelta以及RMSProp,最慢的則是SGD。
② 在收斂軌跡方面
- 兩個動量優化器雖然執行速度很快,但是初中期走了很長的”岔路”。
- 三個自適應優化器中,Adagrad初期走了岔路,但後來迅速地調整了過來,但相比其他兩個走的路最長;AdaDelta和RMSprop的執行軌跡差不多,但在快接近目標的時候,RMSProp會發生很明顯的抖動。
- SGD相比於其他優化器,走的路徑是最短的,路子也比較正。
應用於簡單分類問題的比較
使用SGD優化器
#梯度下降:SGD優化器 train_step=tf.compat.v1.train.GradientDescentOptimizer(0.2).minimize(loss) # Iter 0,Testing Accuracy 0.9236 # Iter 1,Testing Accuracy 0.9449 # Iter 2,Testing Accuracy 0.9508 # Iter 3,Testing Accuracy 0.9527 # Iter 4,Testing Accuracy 0.9591 # Iter 5,Testing Accuracy 0.962 # Iter 6,Testing Accuracy 0.9643 # Iter 7,Testing Accuracy 0.9672 # Iter 8,Testing Accuracy 0.9675 # Iter 9,Testing Accuracy 0.9696 # Iter 10,Testing Accuracy 0.9702
自適應學習率-使用AdaGrad優化器
#使用自適應學習率,使用AdaGrad優化器 train_step=tf.compat.v1.train.AdagradOptimizer(0.2).minimize(loss) # Iter 0,Testing Accuracy 0.855 # Iter 1,Testing Accuracy 0.8647 # Iter 2,Testing Accuracy 0.957 # Iter 3,Testing Accuracy 0.9633 # Iter 4,Testing Accuracy 0.9683 # Iter 5,Testing Accuracy 0.9723 # Iter 6,Testing Accuracy 0.9707 # Iter 7,Testing Accuracy 0.9727 # Iter 8,Testing Accuracy 0.9748 # Iter 9,Testing Accuracy 0.9738 # Iter 10,Testing Accuracy 0.9752
使用RMSProp優化器
#使用自適應學習率:使用RMSProp優化器 train_step=tf.compat.v1.train.RMSPropOptimizer(0.02).minimize(loss) # Iter 0,Testing Accuracy 0.9007 # Iter 1,Testing Accuracy 0.9102 # Iter 2,Testing Accuracy 0.9165 # Iter 3,Testing Accuracy 0.9298 # Iter 4,Testing Accuracy 0.9373 # Iter 5,Testing Accuracy 0.9205 # Iter 6,Testing Accuracy 0.9306 # Iter 7,Testing Accuracy 0.9422 # Iter 8,Testing Accuracy 0.9297 # Iter 9,Testing Accuracy 0.9417 # Iter 10,Testing Accuracy 0.9359
使用Adam優化器
# 使用自適應學習綠:使用Adam優化器 train_step=tf.compat.v1.train.AdamOptimizer(0.02,0.9).minimize(loss) # Iter 0,Testing Accuracy 0.8112 # Iter 1,Testing Accuracy 0.8114 # Iter 2,Testing Accuracy 0.81 # Iter 3,Testing Accuracy 0.7948 # Iter 4,Testing Accuracy 0.8212 # Iter 5,Testing Accuracy 0.8145 # Iter 6,Testing Accuracy 0.8443 # Iter 7,Testing Accuracy 0.8678 # Iter 8,Testing Accuracy 0.8394 # Iter 9,Testing Accuracy 0.8934 # Iter 10,Testing Accuracy 0.8917
使用AdaDelta優化器
#使用自適應學習綠:使用AdaDelta優化器 train_step=tf.compat.v1.train.AdadeltaOptimizer(0.02).minimize(loss) # Iter 0,Testing Accuracy 0.4545 # Iter 1,Testing Accuracy 0.5644 # Iter 2,Testing Accuracy 0.7053 # Iter 3,Testing Accuracy 0.759 # Iter 4,Testing Accuracy 0.7785 # Iter 5,Testing Accuracy 0.7925 # Iter 6,Testing Accuracy 0.8028 # Iter 7,Testing Accuracy 0.8114 # Iter 8,Testing Accuracy 0.8165 # Iter 9,Testing Accuracy 0.82 # Iter 10,Testing Accuracy 0.8237
動量優化法-Momentum優化器
#使用動量優化法:Momentum優化器 train_step=tf.compat.v1.train.MomentumOptimizer(0.2,0.5).minimize(loss) # Iter 0,Testing Accuracy 0.8425 # Iter 1,Testing Accuracy 0.8539 # Iter 2,Testing Accuracy 0.9527 # Iter 3,Testing Accuracy 0.9588 # Iter 4,Testing Accuracy 0.9665 # Iter 5,Testing Accuracy 0.9697 # Iter 6,Testing Accuracy 0.9699 # Iter 7,Testing Accuracy 0.9724 # Iter 8,Testing Accuracy 0.9723 # Iter 9,Testing Accuracy 0.9719 # Iter 10,Testing Accuracy 0.9731
動量優化法-NAG優化器
#使用動量優化法:使用NAG優化器 train_step=tf.compat.v1.train.MomentumOptimizer(learning_rate=0.2,momentum=0.5,use_nesterov=True).minimize(loss) # Iter 0,Testing Accuracy 0.8483 # Iter 1,Testing Accuracy 0.8606 # Iter 2,Testing Accuracy 0.953 # Iter 3,Testing Accuracy 0.9558 # Iter 4,Testing Accuracy 0.9601 # Iter 5,Testing Accuracy 0.9657 # Iter 6,Testing Accuracy 0.9666 # Iter 7,Testing Accuracy 0.9683 # Iter 8,Testing Accuracy 0.9721 # Iter 9,Testing Accuracy 0.9721 # Iter 10,Testing Accuracy 0.9717
NAG在Tensorflow中與Momentum合併在同一函式tf.train.MomentumOptimizer中,可以通過引數配置啟用。
綜上,比較來說AdaGrad優化器和Momentum優化器相對來說比較好
&n