1. 程式人生 > 實用技巧 >Pytorch學習筆記08----優化器演算法Optimizer詳解(SGD、Adam)

Pytorch學習筆記08----優化器演算法Optimizer詳解(SGD、Adam)

1.優化器演算法簡述

首先來看一下梯度下降最常見的三種變形 BGD,SGD,MBGD,這三種形式的區別就是取決於我們用多少資料來計算目標函式的梯度,這樣的話自然就涉及到一個 trade-off,即引數更新的準確率和執行時間。

2.Batch Gradient Descent (BGD)

梯度更新規則:

BGD 採用整個訓練集的資料來計算 cost function 對引數的梯度:

缺點:

由於這種方法是在一次更新中,就對整個資料集計算梯度,所以計算起來非常慢,遇到很大量的資料集也會非常棘手,而且不能投入新資料實時更新模型。

for i in range(nb_epochs):
  params_grad = evaluate_gradient(loss_function, data, params)
  params = params - learning_rate * params_grad

我們會事先定義一個迭代次數 epoch,首先計算梯度向量 params_grad,然後沿著梯度的方向更新引數 params,learning rate 決定了我們每一步邁多大。

Batch gradient descent 對於凸函式可以收斂到全域性極小值,對於非凸函式可以收斂到區域性極小值。

3.Stochastic Gradient Descent (SGD)

梯度更新規則:

和 BGD 的一次用所有資料計算梯度相比,SGD 每次更新時對每個樣本進行梯度更新,對於很大的資料集來說,可能會有相似的樣本,這樣 BGD 在計算梯度時會出現冗餘,而SGD 一次只進行一次更新,就沒有冗餘,而且比較快,並且可以新增樣本。

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

看程式碼,可以看到區別,就是整體資料集是個迴圈,其中對每個樣本進行一次引數更新。

隨機梯度下降是通過每個樣本來迭代更新一次,如果樣本量很大的情況,那麼可能只用其中部分的樣本,就已經將theta迭代到最優解了,對比上面的批量梯度下降,迭代一次需要用到十幾萬訓練樣本,一次迭代不可能最優,如果迭代10次的話就需要遍歷訓練樣本10次。缺點是SGD的噪音較BGD要多,使得SGD並不是每次迭代都向著整體最優化方向。所以雖然訓練速度快,但是準確度下降,並不是全域性最優。雖然包含一定的隨機性,但是從期望上來看,它是等於正確的導數的。

缺點:

SGD 因為更新比較頻繁,會造成 cost function 有嚴重的震盪。

BGD 可以收斂到區域性極小值,當然 SGD 的震盪可能會跳到更好的區域性極小值處。

當我們稍微減小 learning rate,SGD 和 BGD 的收斂性是一樣的。

4.Mini-Batch Gradient Descent (MBGD)

梯度更新規則:

MBGD 每一次利用一小批樣本,即 n 個樣本進行計算,這樣它可以降低引數更新時的方差,收斂更穩定,另一方面可以充分地利用深度學習庫中高度優化的矩陣操作來進行更有效的梯度計算。

和 SGD 的區別是每一次迴圈不是作用於每個樣本,而是具有 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

超引數設定值: n 一般取值在 50~256

缺點:(兩大缺點)

  1. 不過 Mini-batch gradient descent 不能保證很好的收斂性,learning rate 如果選擇的太小,收斂速度會很慢,如果太大,loss function 就會在極小值處不停地震盪甚至偏離。(有一種措施是先設定大一點的學習率,當兩次迭代之間的變化低於某個閾值後,就減小 learning rate,不過這個閾值的設定需要提前寫好,這樣的話就不能夠適應資料集的特點。)對於非凸函式,還要避免陷於區域性極小值處,或者鞍點處,因為鞍點周圍的error是一樣的,所有維度的梯度都接近於0,SGD 很容易被困在這裡。(會在鞍點或者區域性最小點震盪跳動,因為在此點處,如果是訓練集全集帶入即BGD,則優化會停止不動,如果是mini-batch或者SGD,每次找到的梯度都是不同的,就會發生震盪,來回跳動。)
  2. SGD對所有引數更新時應用同樣的 learning rate,如果我們的資料是稀疏的,我們更希望對出現頻率低的特徵進行大一點的更新。LR會隨著更新的次數逐漸變小。

5.Adam:Adaptive Moment Estimation

這個演算法是另一種計算每個引數的自適應學習率的方法。相當於 RMSprop + Momentum

除了像 Adadelta 和 RMSprop 一樣儲存了過去梯度的平方 vt 的指數衰減平均值 ,也像 momentum 一樣保持了過去梯度 mt 的指數衰減平均值

如果 mt 和 vt 被初始化為 0 向量,那它們就會向 0 偏置,所以做了偏差校正,通過計算偏差校正後的 mt 和 vt 來抵消這些偏差:

梯度更新規則:

超引數設定值:
建議 β1 = 0.9,β2 = 0.999,ϵ = 10e−8

實踐表明,Adam 比其他適應性學習方法效果要好。

參考文獻:

https://www.cnblogs.com/guoyaohua/p/8542554.html