梯度下降是優化神經網絡和機器機器學習算法的首選優化方法。本文重度參考SEBASTIAN RUDER的文章。對于英文比較好的同學請直接閱讀原文。本文只為個人的學習總結,難免有所欠缺和不足。
一、梯度下降變種
根據訓練數據集的大小,梯度下降有三種變體,但是本質是一樣的,不一樣的是每次使用多少條樣本。如果內存一次可以計算所有樣本的梯度,稱為:批梯度下降(Batch gradient descent);如果內存一次只允許一個樣本,稱為:隨機梯度下降(Stochastic gradient descent);大部分時候,內存一次是可以計算部分樣本的,稱為:最小批梯度下降(Mini-batch gradient descent)。三種變體的數據表達如下:
1.1批梯度下降(Vanilla gradient descent,又稱Batch gradient descent)
1.2隨機梯度下降(Stochastic gradient descent)
1.3最小批梯度下降(Mini-batch gradient descent)
注意,在其他地方并沒對上述三種變體做嚴格區別,統稱為SGD(隨機梯度下降),下文其余部分,我們也不加區分,統稱為SGD
二、梯度下降的幾種優化方法
傳統的梯度下降法不能保證一個很好的收斂,而且有一些挑戰需要被解決。
- 選擇這個合適的學習率是比較困難的。特別是對一個新的模型和新數據集時候,我們是不知道選擇什么樣的學習率是合適的。只能不斷的去嘗試。
- 學習率調度算法可以在訓練的過程中去調整模型的學習率。模型一開始的時候可以使用大一點的學習率,后面再使用小一點的學習率去微調模型。更好的方法是一開始也用一個小的學習率去warm-up訓練,讓參數先適應數據集。但是無論哪種學習率調度算法都需要預先定義調度算法,這種方法也是沒有辦法很好的適應模型的特征的、
- 對每一個參數都使用同樣的學習率是不合適的。對于稀疏的數據或者特征非常不均衡的數據。最好是使用不同學習率學習不同頻率的特征。
- 另外的挑戰是對于高階非凸的損失函數,往往會陷于局部極值點。還有一種鞍點的情況,模型也是很難學習的。此時損失函數在各個方向的梯度接近于0。SGD是很難逃脫與鞍點或者局部極值點的。
針對上面的一些問題,慢慢出現了一些針對梯度下降的優化方法。
在介紹SGD變種之前。先給出各個變種的一般范式。后天的各個變種優化方法都離不開這個范式。
(1)計算目標函數關于參數的梯度
(2)根據歷史梯度計算一階和二階動量(二階指的是梯度的平方)
(3)更新模型參數
2.1 動量法(Momentum)
做一個簡單的推導。
發現,參數
Adagrad
SGD、SGD-M都是相同的學習率更新參數。但是對于高頻出現的特征我們希望用更小的學習率更新參數。所以提出了自適應梯度更新方法Adagrad。Adagrad對于低頻出現的特征我們希望用更大的學習率更新參數。所以在稀疏數據的場景下Adagrad表現較好。Adagrad中的ada是adapt(自適應)的意思
其中表示
過去所有時刻梯度平方和,注意分母是帶根號的,不帶根號效果會很差。
缺點:分母會越來越大,導致最后的學習率是無窮小的值。這樣模型就學不到東西了。
RMSprop
從表達是可以看出RMSprop是為了解決Adagrad中學習率會越來越小的問題。RMSprop處理使用之前的累計額梯度平方和還使用了當前時刻的梯度平方。這樣就會防止學習率越來越小。
Adam
Adam可以認為是RMSprop和Momentum的結合。
其中
由于都是趨向于1的數,所以開始時刻
趨向于0的一端,導致一開始的時候梯度很小。所以作者Adam對上面的公式做了偏差矯正(bias-corrected)。公式如下
即在原來的基礎上除以。 那么
, 隨著t的變大,
趨向于1。即
趨向于
。
最終參數更新表達如下:
所以理論上Adam優化方法是比較好的優化方法。即加了動量,針對不同參數又使用了不同的學習率。當時在目前很多開源的代碼中,很多了大佬還是使用了SGD-M方法,并沒有使用Adam。關于這一點歡迎大家一起討論。
放一張經典的圖