神經網絡之優化算法

先來回顧一下神經網絡的經典結構,如下圖所示:
在這裏插入圖片描述
一般神經網絡分爲:輸入層,隱藏層,輸出層。上圖中的連線代表的是神經網絡中的參數,參考下面的圖:
在這裏插入圖片描述

常用的激活函數有:
在這裏插入圖片描述

如果對上面的內容有疑惑的話,可以參考筆者的上一篇文章《談談對神經網絡的理解 “談談對神經網絡的理解”》,這裏不再贅述。

好了,下面進入正題。

損失函數的概念

在講優化算法之前,我們先要明確損失函數的概念,損失函數有很多種說法,中文也可以叫代價函數或者目標函數,英文中有 loss function, cost function, objective function. 實際上指得是同一個概念。

首先,神經網絡是用來解決實際問題的,我們以分類問題來舉例。假設我們要做圖片的貓狗分類,即輸入一張圖片,判斷是貓還是狗。

在這裏插入圖片描述

神經網絡只能輸出數值,沒辦法輸出概念,所以需要對貓狗概念做一個轉化,類似於數學建模。我們可以令網絡輸出爲 0 時代表貓,輸出爲 1 時代表狗。不過就像世界不是非黑即白一樣,有時候我們需要的也不是這樣一個非 0 即 1 的輸出,我們希望知道神經網絡認爲輸入圖片是狗的概率值,所以我們設計神經網絡的輸出爲 [0, 1] 之間的浮點數,其數值就代表輸入圖片是狗的概率。若輸入圖片是狗,我們希望神經網絡的輸出越大越好;反之,若輸入圖片是貓,則我們希望神經網絡的輸出越小越好。

前面我們是以定性的方式評判神經網絡的輸出(越大越好或越小越好),但計算機只認數字,所以我們要將定性評判方式改爲定量評判方式,即用損失函數來取代前面的越大越好或越小越小這樣的定性說法。

最簡單的損失函數的均方差損失函數(Mean Squared Error,MSE),如下所示:

在這裏插入圖片描述

其中,N 是樣本是數目,o 是神經網絡輸出,y 是真實值。那麼爲什麼用平方差來作爲誤差的衡量,而不是直接用差的絕對值呢?這是因爲絕對值在求導數時不方便,而平方計算求導數時簡單方便(至於爲什麼需要求導數,後文會講)。

使用均方差損失函數可以很容易的衡量神經網絡分類效果的好壞,當均方差爲 0 時,說明神經網絡 100% 分類正確,均方差越大,說明錯誤越多。

除了均方差損失函數,還有很多其他常用的損失函數,比如交叉熵損失函數(Cross entropy),這裏不展開細講,讀者只需要理解損失函數是對神經網絡輸出結果好壞的定量評判。針對不同的任務,我們會使用不同的損失函數。

損失函數可視化

爲了更好的理解損失函數的性質,我們可以對其進行可視化。前面我們知道,損失函數是對神經網絡輸出的定量評判,所以損失函數實際上是神經網絡參數的函數。受限於人類的感官,我們以二維情況舉例,假設神經網絡只有 w1, w2 兩個參數,即

在這裏插入圖片描述

其中,f 代表的神經網絡的運算集合。

分別以 w1, w2 爲 x, y 軸,用顏色代表 Loss 大小,可以在二維平面畫出損失函數的圖像,如下所示:[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-RWeREJ6f-1572681941001)(http://km.oa.com/files/photos/pictures//20190119//1547885188_94.png)]
中間的黑色代表損失函數最小的位置,也是我們的優化目標。

優化(Optimization)

神經網絡優化問題實際是尋找損失平面上的最低點過程。有一個很好的比喻:想象你處在半山腰,優化過程就是你到達山底的過程,如下圖所示。

在這裏插入圖片描述

如果我們有地圖的話,我們可以非常簡單的直奔山底而去,但非常可惜,你的周圍是一篇黑暗,你只能看清腳下,其他地方是什麼樣子一概不清楚,這種情況下我們該怎樣找到山底呢?

最簡單的辦法就是隨機搜索:不斷地隨機走,記錄走過的最低位置。實現起來也非常簡單:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-AWTswCl9-1572681941001)(http://km.oa.com/files/photos/pictures//20190119//1547891194_82.png)]
但很明顯,這不是一個好辦法,費時費力還不一定有好效果。

再仔細想一想,想最快的到達最低點,我們該怎麼做呢?如果我們看清周圍的環境,我們肯定會選擇向下走,而不是向上走,用數學語言來說,我們會選擇斜率最大的方向走,如下圖所示。

在這裏插入圖片描述

在沒有地圖的情況下,沿斜率最大的方向走是一種貪心算法,不一定能到達全局最優,但一定可以收斂到局部最優解。

梯度下降

前面提到的沿斜率最大的方向走其實有一個更加專業的說法,叫做“梯度下降法”。學過微積分就知道函數導數的定義爲:

在這裏插入圖片描述

梯度的定義爲該點在各個維度導數最大的方向。

我們只要沿着負梯度方向走,就能最快的收斂到最低點,在損失平面的示例如下圖所示。

在這裏插入圖片描述

所以,當我們處在損失平面的一個位置時,先求出這個位置的梯度方向,然後我們只需要沿着負梯度方向前進就可以了。但是,這裏還有一個問題,方向我們確定了,我們該走多遠呢,或者說步長是多少?
這個問題主要有兩種解決辦法,一種是指定步長;一種是自適應步長。對應的也有很大不同的優化算法,下面逐一進行講解。

另外,步長其實也有一個更加專業的說法,叫做 “學習率(Learning Rate)”,通常喜歡用 η 表示。

Batch Gradient Descent

批量梯度下降,每次取全部的樣本計算梯度,然後再更新參數,其學習率是固定的,參數更新公式爲:

在這裏插入圖片描述
其中 θ 是網絡參數, η 表示學習率,J 是損失函數,▽ 是求導符號。上面的公式就表示在負梯度方向更新參數。

Stochastic gradient descent,SGD

隨機梯度下降, 每次取 1 個樣本計算梯度,公式爲:

在這裏插入圖片描述

因爲每次只計算一個樣本,所以 SGD 計算非常快並且適合線上更新模型。但是,頻繁地更新參數也使得損失函數抖動非常厲害,如下圖。
在這裏插入圖片描述

Mini-batch gradient descent

小批量梯度下降,綜合前面兩種算法,每次取一個小批量樣本計算梯度,公式如下:
在這裏插入圖片描述

每次取小批量樣本訓練是訓練神經網絡的標準做法,小批量樣本大小一般叫做 batch size,數值從 8 到 2048 都有,屬於可調節的超參數。這種做法的好處是:

  • 相比較 SGD 增加了一次更新使用的訓練數據量,使得目標函數收斂得更加平穩;
  • 可以使用矩陣操作對每批數據進行計算,大大提升了算法的效率。

前面三種都是標準梯度下降法,只是在每次計算的樣本大小上做文章。下面的優化算法可以理解爲在 Mini-Batch GD 的基礎加入一些 trick,解決 Mini-Batch GD 存在的一些問題。

Momentum

實際中,我們遇到的目標函數往往在不同的維度上梯度相差很大,比如在下面的函數等高線圖中可以看出函數在縱向上要比橫向陡峭得多。

在這裏插入圖片描述

SGD 等基本梯度下降算法並不知道這些,因爲 y 方向梯度大 x 方向梯度小所以它們會在 y 方向上不斷搖擺而沿 x 方向緩慢移動,但是我們知道在 y 方向的震盪是無用的只有 x 方向的纔在不斷接近最優點。

Momentum 是模擬物理裏動量的概念,積累之前的動量來替代真正的梯度。公式如下:

在這裏插入圖片描述

其中,γ 是動量因子,一般取 0.9。

由於目標函數在 y 方向上搖擺,所以前後兩次計算的梯度在 y 方向上相反,所以相加後相互抵消,而x方向上梯度方向不變,所以x方向的梯度是累加的,其效果就是損失函數在 y 方向上的震盪減小了,而更加迅速地從 x 方向接近最優點。
在這裏插入圖片描述
也可以把這個過程和在斜坡放一個球讓其滾下類比:當從斜坡頂端釋放一個小球時,由於重力的作用小球滾下的速度會越來越快;與此類似,衝量的作用會使相同方向的梯度不斷累加,不同方向的梯度相互抵消,其效果就是逼近最優點的速度不斷加快。

Nesterov Accelerated Gradient(NAG)

想象小球從山坡上滑落,它的速度沿着山坡不斷加快,然而這並不是令我們滿意的結果,當小球接近山谷(最優點)時,它已經有了很大的速度,很可能會再次衝向山谷的另一邊,而錯過了最優點。我們需要一顆更加“聰明”的小球,它能夠感知坡度的變化,從而在它再次衝上山坡之前減速而避免錯過山谷。

Nesterov accelerated gradient(NAG)就是一種讓小球變“聰明”的方法。NAG 公式如下:
在這裏插入圖片描述

其中,γ 是動量因子,一般取 0.9。

跟上面 Momentum 公式的唯一區別在於,梯度不是根據當前參數位置 θ,而是根據先走了本來計劃要走的一步後,達到的參數位置 θ - γv_t-1 後計算出來的。

對於這個改動,很多文章給出的解釋是,能夠讓算法提前看到前方的地形梯度,如果前面的梯度比當前位置的梯度大,那我就可以把步子邁得比原來大一些,如果前面的梯度比現在的梯度小,那我就可以把步子邁得小一些。這個大一些、小一些,都是相對於原來不看前方梯度、只看當前位置梯度的情況來說的。

NAG 本質上是多考慮了目標函數的二階導信息,所以可以加速收斂。其實所謂“往前看”的說法,在牛頓法這樣的二階方法中也是經常提到的,比喻起來是說“往前看”,數學本質上則是利用了目標函數的二階導信息。

在這裏插入圖片描述

如上圖所示,Momentum 首先計算一個梯度(短的藍色向量),然後在前一步的更新方向上進行一個大的跳躍(長的藍色向量)。Nesterov 首先在前一步的更新方向上進行一個大的跳躍(棕色向量),然後在跳躍後的點計算梯度(紅色向量),得到最終更新方向(綠色向量)。

分析上面的原理可知,當“小球”將要衝上山坡的另一面時,紅色線表示的預測梯度方向發生改變,從而將棕色向量往回拉達到了“減速”的效果。
在這裏插入圖片描述

Adagrad

前面講的都是學習率固定的優化算法,Adagrad 是第一個自適應學習的優化算法。

Adagrad 是一種適合處理稀疏特徵的梯度更新算法,它對稀疏特徵採用高的更新速率,而對其他特徵採用相對較低的更新速率。Dean 等人發現 Adagrad 能很好地提高 SGD 的魯棒性,它已經被谷歌用來訓練大規模的神經網絡。

Adagrad 公式爲:

在這裏插入圖片描述

G 爲對角矩陣,對角元素爲該維度參數的梯度平方和。寫成向量形式:

在這裏插入圖片描述

Adagrad 的優點是自適應學習率,Adagrad 主要缺點是累加了參數的歷史梯度的平方,所以到後期學習率會越來越小,最後無法再學習到新的信息。下面介紹的算法就是來解決這個問題的。

Adadelta

Adadelta 主要解決了 Adagrad 算法中學習率衰減過快的問題,它不再累加參數所有的歷史梯度平方和,轉而設定一個窗口 w,只求前 w 個歷史梯度平方的平均數,並且也不直接存儲這些項,僅僅是近似計算對應的平均值。即:
在這裏插入圖片描述
ρ 參數類似於 Momentum 的動量項,一般取爲 0.9,Adadelta 的更新項爲

在這裏插入圖片描述

分母是 Root Mean Squared(RMS),所以上式可以記爲:

在這裏插入圖片描述

The authors note that the units in this update (as well as in SGD, Momentum, or Adagrad) do not
match, i.e. the update should have the same hypothetical units as the parameter. To realize this, they first define another exponentially decaying average, this time not of squared gradients but of squared parameter updates: (關於這一段的具體解釋參考 Adadelta 論文 3.2 節)

在這裏插入圖片描述

Δθ 的 RMS 爲

在這裏插入圖片描述

Adadelta 的更新公式爲

在這裏插入圖片描述

可以看出 Adadelta 不依賴全局學習率。

RMSprop

RMSprop 是 Geoff Hinton 提出的,與 Adadelta 類似,也是爲了解決 Adagrad 學習率單調下降的問題。RMSprop 和 Adadelta 是同時獨立提出來的。

RMSprop 跟 Adadelta 的第一版公式相同,更新公式爲:

在這裏插入圖片描述

Hinton 建議 γ 參數設爲 0.9,學習率 n 設爲 0.001。

Adam

Adam(Adaptive Moment Estimation)本質上是帶有動量項的 RMSprop,它利用梯度的一階矩估計和二階矩估計動態調整每個參數的學習率。Adam 的優點主要在於經過偏置校正後,每一次迭代學習率都有個確定範圍,使得參數比較平穩。

mt and vt are estimates of the first moment (the mean) and the second moment (the uncentered
variance) of the gradients respectively, hence the name of the method. As mt and vt are initialized as vectors of 0’s, the authors of Adam observe that they are biased towards zero, especially during the initial time steps, and especially when the decay rates are small (i.e. 1 and 2 are close to 1).

在這裏插入圖片描述

They counteract these biases by computing bias-corrected first and second moment estimates: (由於當 β1, β2 接近於1時,上面兩項接近 0,所以用下面的式子進行偏差修正)
在這裏插入圖片描述
They then use these to update the parameters just as we have seen in Adadelta and RMSprop, which yields the Adam update rule:

在這裏插入圖片描述

作者建議 β1 默認 0.9,β2 默認 0.999,ε 默認 10^-8。

Adam 應該是目前最流行的優化算法,效果非常穩定。

Adamax

Adam vt 的更新使用了梯度的二範式,可以推廣爲 p 範式的形式:

在這裏插入圖片描述

p 很大時,數值不穩定,所以 1-範式,2-範式比較常用。但是無窮範式也是數值穩定的,Adamax 就是用的無窮範式:

Adamax 的參數更新公式爲:

在這裏插入圖片描述
作者建議 β1 默認 0.9,β2 默認 0.999,η 默認 0.002。

優化算法可視化

下圖展示了各個算法在 loss 等高線上的優化過程。
在這裏插入圖片描述

可以看到,Adagrad, Adadelta, RMSprop 收斂最快。SGD, Momentum, NAG 開始的方向都是錯誤的,但 NAG 最先找到正確的方向。

下圖展示了各個算法在鞍點的情況。

在這裏插入圖片描述
SGD, Momentum, NAG 很難逃離鞍點,而 Adagrad, Adadelta, Rmsprop 能夠迅速逃離。

參考

https://zhuanlan.zhihu.com/p/22252270
https://zhuanlan.zhihu.com/p/32230623
https://zhuanlan.zhihu.com/p/22810533
http://wowx.info/posts/401226963/
http://cs231n.github.io/optimization-1/
https://zhuanlan.zhihu.com/p/21486826 衝量,解釋的很好
https://github.com/hsmyy/zhihuzhuanlan/blob/master/momentum.ipynb 畫圖
http://ruder.io/optimizing-gradient-descent/index.html
http://cs231n.github.io/neural-networks-3/
http://ruder.io/deep-learning-optimization-2017/
https://distill.pub/2017/momentum/

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