梯度下降算法

梯度下降算法

訓練神經網絡流程:
<1>獲得數據;
<2>通過計算圖前向傳播,獲得loss;
<3>反向傳播計算梯度,這個梯度能告訴我們如何去調整權重,最終能夠更好的分類圖片;
<4>用計算出的梯度去更新參數

(1)、梯度下降算法

  • 批量梯度下降(Batch gradient descent)

旨在每次使用全量的訓練集樣本來更新模型參數,即:θ=θ−η⋅∇θJ(θ)
僞碼如下:

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

nb_epochs是用戶輸入的最大迭代次數。使用全量的訓練集樣本計算損失函數loss_function的梯度params_grad,然後使用學習速率learning_rate朝着梯度相反方向去更新模型的每一個參數params。

批量梯度下降每次學習都使用整個訓練集,因此其優點在於每次更新都會朝着正確的方向進行,最後能夠保證收斂於極值點(凸函數收斂於全局極值點,非凸函數可能會收斂於局部極值點,屬於凸理論的問題了),但是其缺點在於每次學習時間過長,並且如果訓練集很大以至於需要消耗大量的內存,並且全量梯度下降不能進行在線模型參數更新。

  • 隨機梯度下降(Stochastic gradient descent)

旨在每次從訓練集中隨機選擇一個樣本來進行學習,即:θ=θ−η⋅∇θJ(θ;xi;yi)
僞碼如下:

for i in range(nb_epochs):
     np.random.shuffle(data)
     for example in data:
        params_grad = evaluate_gradient(loss_functon,example,params)

批量梯度下降算法每次都會使用全部訓練樣本,因此這些計算是冗餘的,因爲每次都使用完全相同的樣本集。而隨機梯度下降算法每次只隨機選擇一個樣本來更新模型參數,因此每次的學習是非常快速的,並且可以進行在線更新。

我們可以對不同的參數方案和他們如何快速優化有一個直觀的認識:

特別觀察一下SGD,紅色的那條線,從圖中可以看出SGD實際上是所有方法中最慢的一個,所以在實際中很少應用它,我們可以使用更好的方案。
那我們來分析一下SGD的問題,是什麼原因導致它的的速度這麼慢?
舉個栗子:

我們可以從水平方向上可以看出,它的梯度很是非常小的,因爲處於在一個比較淺的水平裏;但是垂直有很大的速率,因爲它是一個非常陡峭的函數,所以出現了這種狀況:

在這種情況下使用SGD,在水平方向上進行比較緩慢,而在垂直方向上進展的很快,所以產生了很大的上下震盪。

小批量梯度下降(Mini-batch gradient descent)

旨在綜合了 batch 梯度下降與 stochastic 梯度下降,在每次更新速度與更新次數中間取得一個平衡,其每次更新從訓練集中隨機選擇 m,m

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 

相對於隨機梯度下降,Mini-batch梯度下降降低了收斂波動性,即降低了參數更新的方差,使得更新更加穩定。相對於全量梯度下降,其提高了每次學習的速度。並且其不用擔心內存瓶頸從而可以利用矩陣運算進行高效計算。一般而言每次更新隨機選擇[50,256]個樣本進行學習,但是也要根據具體問題而選擇,實踐中可以進行多次試驗,選擇一個更新速度與更次次數都較適合的樣本數。mini-batch梯度下降可以保證收斂性,常用於神經網絡中。

(2)、梯度下降優化算法

梯度下降算法存在的問題:
1. 選擇一個合理的學習速率很難。如果學習速率過小,則會導致收斂速度很慢;如果學習速率過大,那麼就會阻礙收斂,即在極值點附近會震盪。
學習速率調整(又稱學習速率調度,Learning rate schedules),在每次更新過程中,改變學習速率,如退火。一般使用某種事先設定的策略或者在每次迭代中衰減一個較小的閾值。無論哪種調整方法,都需要事先進行固定設置,這便無法自適應每次學習的數據集特點。

2.模型所有的參數每次更新都是使用相同的學習速率。如果數據特徵是稀疏的或者每個特徵有着不同的取值統計特徵與空間,那麼便不能在每次更新中每個參數使用相同的學習速率,那些很少出現的特徵應該使用一個相對較大的學習速率。

3.對於非凸目標函數,容易陷入那些次優的局部極值點中,如在神經網路中。那麼如何避免呢。而更嚴重的問題不是局部極值點,而是鞍點。

  • Momentum

如果把要優化的目標函數看成山谷的話,可以把要優化的參數看成滾下山的石頭,參數隨機化爲一個隨機數可以看做在山谷的某個位置以0速度開始往下滾。目標函數的梯度可以看做給石頭施加的力,由力學定律知:F=m∗a,所以梯度與石頭下滾的加速度成正比。因而,梯度直接影響速度,速度的累加得到石頭的位置,對這個物理過程進行建模,可以得到參數更新過程爲

 # Momentum update
  v = momentum * v - learning_rate * dx # integrate velocity
  x += v # integrate position

代碼中v指代速度,其計算過程中有一個超參數momentum,稱爲動量(momentum)。雖然名字爲動量,其物理意義更接近於摩擦,其可以降低速度值,降低了系統的動能,防止石頭在山谷的最底部不能停止情況的發生。如果沒有momentum * v,那麼小球就永遠都不會停下了,會在平面上滾動,不會有能量的損失,損失函數就很難最小化。動量的取值範圍通常爲[0.5, 0.9, 0.95, 0.99],一種常見的做法是在迭代開始時將其設爲0.5,在一定的迭代次數(epoch)後,將其值更新爲0.99。

加上動量項就像從山頂滾下一個球,球往下滾的時候累積了前面的動量(動量不斷增加),因此速度變得越來越快,直到到達終點。同理,在更新模型參數時,對於那些當前的梯度方向與上一次梯度方向相同的參數,那麼進行加強,即這些方向上更快了;對於那些當前的梯度方向與上一次梯度方向不同的參數,那麼進行削減,即這些方向上減慢了。即在陡峭的方向上削弱這些動盪,在一致的淺的方向激勵此過程。因此可以獲得更快的收斂速度與減少振盪。

  • Adagrad

Adagrad也是一種基於梯度的優化算法。

cache += dx**2
x += - learning_rate * dx / (np.sqrt(cache) + le-7)

相比於SGD,增加了個附加變量—-cache來放縮梯度,並且是不停的增加這一附加變量。這裏的變量cache是一個聯合矢量,和主向量是一樣大的,因爲cache在每一維度計算其相應梯度的平方和,我們將這些cache構造起來,然後逐項用這一函數去除以cache的平方,使得對每個參數自適應不同的學習速率,對稀疏特徵,得到大的學習更新,對非稀疏特徵,得到較小的學習更新,因此該優化算法適合處理稀疏特徵數據。

So,舉個栗子 :

Adagrad在垂直方向上的梯度會加到cache中,然後相應的會除以越來越大的數,所以在垂直方向上會得到越來越小的更新。當我們在垂直方向上看到許多大的梯度,Adagrad就會衰減學習速率,使垂直方向的更新步長越來越小。在水平方向上的梯度是很小的,所以分母會變小,相比於垂直方向,水平方向更新更快。這就是對每個參數自適應不同的學習速率,針對不同梯度方向的補償措施。

  • Adam

Adam也是一種不同參數自適應不同學習速率方法,它是Adagrad算法和Momentum算法的結合:

# Adam
m = beta1 * m + (1-beta1) * dx
v  = beta2 * v  + (1-beta2) * (dx**2)
x += - learning_rate * m / (np.sqrt(v)) + le-7)

m與v分別是梯度的帶權平均和帶權有偏方差,初始爲0向量,在衰減因子(衰減率)β1,β2接近於1時,m和v接近於0。爲了改進這個問題,對m與v進行偏差修正(bias-corrected),偏差修正取決於時間步長t:

# Adam
m = beta1 * m + (1-beta1) * dx
v  = beta2 * v  + (1-beta2) * (dx**2)
m /= 1-beta1**t
v /= 1-beta2**t
x += - learning_rate * m / (np.sqrt(v)) + le-7)
  • 牛頓法

牛頓法是二階收斂,梯度下降是一階收斂,所以牛頓法就更快。如果更通俗地說的話,比如你想找一條最短的路徑走到一個盆地的最底部,梯度下降法每次只從你當前所處位置選一個坡度最大的方向走一步,牛頓法在選擇方向時,不僅會考慮坡度是否夠大,還會考慮你走了一步之後,坡度是否會變得更大。所以,可以說牛頓法比梯度下降法看得更遠一點,能更快地走到最底部。

從幾何上說,牛頓法就是用一個二次曲面去擬合你當前所處位置的局部曲面,而梯度下降法是用一個平面去擬合當前的局部曲面,通常情況下,二次曲面的擬合會比平面更好,所以牛頓法選擇的下降路徑會更符合真實的最優下降路徑。

紅色的牛頓法的迭代路徑,綠色的是梯度下降法的迭代路徑。

迭代公式:

我們可以通過公式可以看出二階收斂的優勢,沒有學習速率,沒有超參數,只要知道方向和曲率,就能達到近似的最低值。但在實際應用中,牛頓法不是很受歡迎,在迭代公式中的H是指Hessian矩陣,比如你有1億的數據,Hessian矩陣是1億行和1億列,計算量巨大。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章