激活函數與優化器算法(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)

 

目錄

一、在神經網絡中爲什麼要使用激活函數呢?

激活函數:

ReLU

Leaky ReLU

Sigmoid

tanh

softmax

二、優化算法

1.批量梯度下降:

2.隨機梯度下降:

3. mini-batch梯度下降:

4.改進的梯度下降算法:

5.Nesterov Accelerated Gradient                          ​

6.Adagrad (Adaptive gradient algorithm)

補充:指數加權平均

7.Adadelta

8.RMSprop

8.Adam:Adaptive Moment Estimation

三.如何選擇優化算法

參考:


PyTorch框架中有一個非常重要且好用的包:torchvision,該包主要由3個子包組成,分別是:torchvision.datasets、torchvision.models、torchvision.transforms:https://pytorch.org/docs/master/torchvision/transforms.html#conversion-transforms

一、在神經網絡中爲什麼要使用激活函數呢?

現實中輸入和輸出之間的關係通常並非線性。如果神經網絡的架構僅由線性算法組成,那麼它很難計算出非線性行爲。所以我們要在每層的結尾加上一個激活函數

不同的激活函數有不同的特點。選取不當會導致梯度變得非常小,就是通常所說的梯度消失問題。

另外還存在一種相反的問題,就是梯度爆炸,當梯度值過大時,網絡會變得非常不穩定。

激活函數:

ReLU

max(0,x):如果輸入大於0,則輸出等於輸入。否則,輸出爲0。

它的輸出範圍從0到無窮大。這意味着它的輸出可能會變得非常大,可能存在梯度爆炸問題。它還有個問題是左側完全平坦,可能導致梯度消失。

ReLU計算簡單,是神經網絡內層最常用的激活函數。

Leaky ReLU

將ReLU函數的前半段用0.01x代替。

Sigmoid(邏輯函數)

1/(1+e-x)

這個函數非常適合將輸入分爲兩類。它的形狀很緩和,因此它的梯度能得到很好的控制。

主要的缺點是,在極端情況下,函數輸出變得非常平坦。這意味着它存在梯度消失的問題。

tanh(雙曲正切函數)

(2 / (1+e-2x)) - 1

它與Sigmoid非常相似。函數曲線更陡峭,因此它的輸出也將更強大。缺點與Sigmoid類似。

tan -1反正切函數

softmax

e-x / Sum(e-x)

輸出範圍介於0和1之間。

Softmax將輸入歸一化爲概率分佈。它將輸入壓縮爲0到1範圍,就像Sigmoid。

它通常在多分類場景中的輸出層,Softmax確保每個類的概率之和爲1。

二、優化算法

1.批量梯度下降:

我們知道曲面上方向導數的最大值的方向就代表了梯度的方向,因此我們在做梯度下降的時候,應該是沿着梯度的反方向進行權重的更新,可以有效的找到全局的最優解。這個 \theta_i 的更新過程可以描述爲

                                                      

[n表示的是步長或者說是學習率(learning rate)]

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

在每次更新時用所有樣本,要留意,在梯度下降中,對於 \theta_i 的更新,所有的樣本都有貢獻,也就是參與調整 \theta .其計算得到的是一個標準梯度,對於最優化問題,凸問題,也肯定可以達到一個全局最優。因而理論上來說一次更新的幅度是比較大的。如果樣本不多的情況下,當然是這樣收斂的速度會更快啦。但是很多時候,樣本很多,更新一次要很久,這樣的方法就不合適啦。

2.隨機梯度下降:

在每次更新時用1個樣本,可以看到多了隨機兩個字,隨機也就是說我們用樣本中的一個例子來近似我所有的樣本,來調整θ,因而隨機梯度下降是會帶來一定的問題,因爲計算得到的並不是準確的一個梯度,對於最優化問題,凸問題,雖然不是每次迭代得到的損失函數都向着全局最優方向, 但是大的整體的方向是向全局最優解的,最終的結果往往是在全局最優解附近。但是相比於批量梯度,這樣的方法更快,更快收斂,雖然不是全局最優,但很多時候是我們可以接受的,所以這個方法用的也比上面的多。下圖是其更新公式:

                                             

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

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

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

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

3. mini-batch梯度下降:

在每次更新時用b個樣本,其實批量的梯度下降就是一種折中的方法,他用了一些小樣本來近似全部的,其本質就是我1個指不定不太準,那我用個30個50個樣本那比隨機的要準不少了吧,而且批量的話還是非常可以反映樣本的一個分佈情況的。在深度學習中,這種方法用的是最多的,因爲這個方法收斂也不會很慢,收斂的局部最優也是更多的可以接受!

                                             

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

總的來說,隨機梯度下降一般來說效率高,收斂到的路線曲折,但一般得到的解是我們能夠接受的,在深度學習中,用的比較多的是mini-batch梯度下降。不過Mini-batch gradient descent 不能保證很好的收斂性,learning rate 如果選擇的太小,收斂速度會很慢,如果太大,loss function 就會在極小值處不停地震盪甚至偏離。(有一種措施是先設定大一點的學習率,當兩次迭代之間的變化低於某個閾值後,就減小 learning rate,不過這個閾值的設定需要提前寫好,這樣的話就不能夠適應數據集的特點。)

4.改進的梯度下降算法:

Momentum 通過加入 γv_t−1 ,可以加速 SGD, 並且抑制震盪

                                                                              

è¿éåå¾çæè¿°

當我們將一個小球從山上滾下來時,沒有阻力的話,它的動量會越來越大,但是如果遇到了阻力,速度就會變小。
加入的這一項,可以使得梯度方向不變的維度上速度變快,梯度方向有所改變的維度上的更新速度變慢,這樣就可以加快收斂並減小震盪。

5.Nesterov Accelerated Gradient

用 θ−γv_t−1 來近似當做參數下一步會變成的值,(和動量方法進行對比)

                             

 

藍色是 Momentum 的過程,會先計算當前的梯度,然後在更新後的累積梯度後會有一個大的跳躍。
而 NAG 會先在前一步的累積梯度上(brown vector)有一個大的跳躍,然後衡量一下梯度做一下修正(red vector),這種預期的更新可以避免我們走的太快。

                                       

在更新梯度時順應 loss function 的梯度來調整速度,並且對 SGD 進行加速

我們還希望可以根據參數的重要性而對不同的參數進行不同程度的更新。

 

6.Adagrad (Adaptive gradient algorithm)

 這個算法就可以對低頻的參數做較大的更新對高頻的做較小的更新,也因此,對於稀疏的數據它的表現很好,很好地提高了 SGD 的魯棒性,例如識別 Youtube 視頻裏面的貓,訓練 GloVe word embeddings,因爲它們都是需要在低頻的特徵上有更大的更新。

 梯度更新規則:

 

其中 g 爲:t 時刻參數 θ_i 的梯度

如果是普通的 SGD, 那麼 θ_i 在每一時刻的梯度更新公式爲:

但這裏的 learning rate η 也隨 t 和 i 而變:

其中 G_t 是個對角矩陣, (i,i) 元素就是 t 時刻參數 θ_i 的梯度平方和。

Adagrad 的優點是減少了學習率的手動調節

超參數設定值:一般η選取0.01

缺點:

它的缺點是分母會不斷積累,這樣學習率就會收縮並最終會變得非常小。

補充:指數加權平均

指數加權平均本質上就是一種近似求平均的方法。

我們現在直接給出公式: v_{t}=\beta*v_{t-1}+(1-\beta)\theta_{t}

通過上面表達式,我們可以看到,V100等於每一個時刻天數的溫度值再乘以一個權值。本質就是以指數式遞減加權的移動平均。各數值的加權而隨時間而指數式遞減,越近期的數據加權越重,但較舊的數據也給予一定的加權。(也就是式子中的θ100的權值比θ1的權值大)而在我們的普通平均數求法,它的每一項的權值都是一樣的,如果有n項,權值都爲1/n。

 

我們可以看到指數加權平均的求解過程實際上是一個遞推的過程,那麼這樣就會有一個非常大的好處,每當我要求從0到某一時刻(n)的平均值的時候,我並不需要像普通求解平均值的作爲,保留所有的時刻值,類和然後除以n。

而是只需要保留0-(n-1)時刻的平均值和n時刻的溫度值即可。也就是每次只需要保留常數值,然後進行運算即可,這對於深度學習中的海量數據來說,是一個很好的減少內存和空間的做法。(也就是我們可以直接記錄之前數據的平均值,然後利用當前數據乘以一個權值加上之前的平均值近似求平均值)

偏差修正

由以上證明可以看出,每個最新數據值,依賴於以前的數據結果。

一般令第一個數值爲0,即v0=0;但此時初期的幾個計算結果就會與真實的平均值有較大偏差,具體如下:

7.Adadelta

這個算法是對 Adagrad 的改進,

和 Adagrad 相比,就是分母的 G 換成了過去的梯度平方的衰減平均值,指數衰減平均值

這個分母相當於梯度的均方根 root mean squared (RMS),在數據統計分析中,將所有值平方求和,求其均值,再開平方,就得到均方根值 ,所以可以用 RMS 簡寫:

其中 E 的計算公式如下,t 時刻的依賴於前一時刻的平均和當前的梯度:

(指數加權平均的思路)

梯度更新規則:

此外,還將學習率 η 換成了 RMS[Δθ],這樣的話,我們甚至都不需要提前設定學習率了:

超參數設定值:  γ 一般設定爲 0.9

8.RMSprop

RMSprop 是 Geoff Hinton 提出的一種自適應學習率方法。

RMSprop 和 Adadelta 都是爲了解決 Adagrad 學習率急劇下降問題的

梯度更新規則:

RMSprop 與 Adadelta 的第一種形式相同:(使用的是指數加權平均,旨在消除梯度下降中的擺動,與Momentum的效果一樣,某一維度的導數比較大,則指數加權平均就大,某一維度的導數比較小,則其指數加權平均就小,這樣就保證了各維度導數都在一個量級,進而減少了擺動。允許使用一個更大的學習率η)

 

超參數設定值:

Hinton 建議設定 γ 爲 0.9, 學習率 η 爲 0.001。

9.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 比其他適應性學習方法效果要好。

三.如何選擇優化算法

如果數據是稀疏的,就用自適用方法,即 Adagrad, Adadelta, RMSprop, Adam。

RMSprop, Adadelta, Adam 在很多情況下的效果是相似的。

Adam 就是在 RMSprop 的基礎上加了 bias-correction 和 momentum,

隨着梯度變的稀疏,Adam 比 RMSprop 效果會好。

整體來講,Adam 是最好的選擇

很多論文裏都會用 SGD,沒有 momentum 等。SGD 雖然能達到極小值,但是比其它算法用的時間長,而且可能會被困在鞍點

如果需要更快的收斂,或者是訓練更深更復雜的神經網絡,需要用一種自適應的算法。

 

參考:

https://www.zhihu.com/question/264189719 如何理解隨機梯度下降

http://sofasofa.io/tutorials/python_gradient_descent/  自己動手用python寫梯度下降

https://blog.csdn.net/tsyccnh/article/details/76270707 深度學習優化函數詳解(4)-- momentum 動量法

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

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