深度學習中的優化問題通常指的是:尋找神經網絡上的一組參數θ,它能顯著地降低代價函數J(θ)。針對此類問題,研究人員提出了多種優化算法,Sebastian Ruder 在《An overview of gradient descent optimizationalgorithms》(鏈接:https://arxiv.org/pdf/1609.04747.pdf )這篇論文中列出了常用優化算法的比較。主要優化算法有:GD、SGD、Momentum、Adagrad、Adadelta、RMSProp、Adam。
1 梯度下降法及其三個變種
1.1 BGD: Batch Gradient Descent
迭代規則:
BGD(批量梯度下降,這里的批量實際上是全部數據)每次迭代采用整個訓練集數據來計算損失函數J(θ)對參數θ的的梯度。
每次迭代的參數更新公式為:

優點:
由於每一步迭代使用了全部樣本,因此當損失函數收斂過程比較穩定。對於凸函數可以收斂到全局最小值,對於非凸函數可以收斂到局部最小值。
缺點:
每一步更新中,都要利用全部樣本計算梯度,計算起來非常慢,遇到很大量的數據集也會非常棘手,而且不能投入新數據實時更新模型。
1.2 SGD: Stochastic Gradient Descent
迭代規則:
SGD每次迭代利用每個樣本計算損失函數對θ的梯度。
公式為:

優點:
由於每次迭代只使用了一個樣本計算梯度,訓練速度快,包含一定隨機性,從期望來看,每次計算的梯度基本是正確的導數的。
缺點:
更新頻繁,帶有隨機性,會造成損失函數在收斂過程中嚴重震盪。
1.3 MBGD:Mini-Batch Gradient Descent
迭代規則:MBGD 每一次利用一小批樣本,即 n 個樣本進行計算梯度( n 一般取值在 50~256)。
公式為:

優點:可以降低參數更新時的方差,收斂更穩定,另一方面可以充分地利用深度學習庫中高度優化的矩陣操作來進行更有效的梯度計算。
缺點:不能保證很好的收斂性,learning rate 如果選擇的太小,收斂速度會很慢,如果太大,損失函數就會在極小值處不停地震盪甚至偏離。(有一種措施是先設定大一點的學習率,當兩次迭代之間的變化低於某個閾值后,就減小 learning rate,不過這個閾值的設定需要提前寫好,這樣的話就不能夠適應數據集的特點。)
這三種算法都可能陷入鞍點和平灘底部。
2 Momentum
梯度下降法容易被困在局部最小的溝壑處來回震盪,可能存在曲面的另一個方向有更小的值;有時候梯度下降法收斂速度還是很慢。動量法就是為了解決這兩個問題提出的。
更新公式:

當我們將一個小球從山上滾下來時,沒有阻力的話,它的動量會越來越大,但是如果遇到了阻力,速度就會變小。
加入的這一項,可以使得梯度方向不變的維度上速度變快,梯度方向有所改變的維度上的更新速度變慢,這樣就可以加快收斂並減小震盪。
超參數設定值: 一般 γ 取值0.5、0.9、0.99 左右。
優點:前后梯度一致的時候能夠加速學習;前后梯度不一致的時候能夠抑制震盪,越過局部極小值。(加速收斂,減小震盪。)
缺點:增加了一個超參數。
3 Adagrad:Adaptive gradient algorithm
AdaGrad是一種可以自動改變學習速率的優化算法,只需設定一個全局學習速率ϵ,每次迭代使用的學習速率與歷史梯度有關。
迭代算法:

優點:減少了學習率的手動調節。
缺點:分母會不斷積累,學習率就會減小並最終會變得非常小。(一開始就積累梯度平方會導致有效學習率過早過量減小)。
4 RMSProp
RMSProp 是 Geoff Hinton 提出的一種自適應學習率方法。RMSprop 和 Adadelta(這里沒有介紹)都是為了解決 Adagrad 學習率急劇下降問題的。
迭代規則:

引入一個衰減系數,讓r每次都以一定的比例衰減,類似於Momentum中的做法。衰減系數使用的是指數加權平均,旨在消除梯度下降中的擺動,與Momentum的效果一樣,某一維度的導數比較大,則指數加權平均就大,某一維度的導數比較小,則其指數加權平均就小,這樣就保證了各維度導數都在一個量級,進而減少了擺動。允許使用一個更大的學習率。
優點:相比於AdaGrad,這種方法更好的解決了深度學習中過早的結束學習的問題;適合處理非平穩目標,對RNN效果很好。
缺點:引入的新的超參:衰減系數ρ;依然依賴於全局學習速率。
5 Adam: Adaptive Moment Estimation
Adam本質上是帶有動量項的RMSProp,它利用梯度的一階矩估計和二階矩估計動態調整每個參數的學習率。Adam的優點主要在於經過偏置矯正后,每一次迭代學習率都有個確定范圍,使得參數比較平穩。
迭代規則:

優點:Adam 比其他適應性學習方法效果要好。適用於多數情況。
缺點:復雜。
6 如何選擇優化算法
1 對於稀疏數據,盡量使用學習率可自適應的優化方法,不用手動調節,而且最好采用默認值。
2 SGD通常訓練時間更長,但是在好的初始化和學習率調度方案的情況下(很多論文都用SGD),結果更可靠。
3 如果在意更快的收斂,並且需要訓練較深較復雜的網絡時,推薦使用學習率自適應的優化方法。
7 TensorFlow中的優化器
| 優化器名稱 | 文件路徑 |
| Adadelta | tensorflow/python/training/adadelta.py |
| adagrad | tensorflow/python/training/adagrad.py |
| adagrad Dual Averaging | tensorflow/python/training/adagrad_da.py |
| Adam | tensorflow/python/training/adam.py |
| Ftrl | tensorflow/python/training/ftrl.py |
| Gradient Descent | tensorflow/python/training/gradient_descent.py |
| Momentum | tensorflow/python/training/momentum.py |
| Proximal Adagrad | tensorflow/python/training/proximal_adagrad.py |
| Proximal Gradient Descent | tensorflow/python/training/proximal_gradient_descent.py |
| Rmsprop | tensorflow/python/training/rmsprop.py |
| Synchronize Relicas | tensorflow/python/training/sync_reolicas_optimizer.py |
