当我们在谈深度学习时,到底在谈论什么(二)--转
原文地址:http://suanfazu.com/t/topic/13742
上一次的分享我們提到了神經網絡的幾個基本概念,其中提到了隨機梯度下降(SGD)算法是神經網絡學習(或者更通用的,一般性參數優化問題)的主流方法。概念上,神經網絡的學習非常簡單,可以被歸納為下面的步驟:
(a) 構造神經網絡結構(選擇層數、激活函數等)
(b) 初始化構造出的神經網絡參數
(c) 對于給定的訓練樣本與當前的,計算梯度
(d) 通過(隨機)梯度下降算法更新。
例如,不考慮任何正則化因子情況的最簡單參數更新為
神經網絡的初學者往往會發現,上述四個步驟當中,對于給定樣本,計算其梯度是最?不直觀?的一個步驟。本文我們玻森(bosonnlp.com)的討論就圍繞解決梯度的核心算法:后向傳播?算法來展開。
首先理清一個概念,步驟(d)的梯度下降算法是一種優化算法,而我們要討論的后向傳播算法,是計算步驟(c)中所需要梯度的一種算法。下面的討論,我們首先完成單參數(即只有一個參數需要學習)的特例情況下的推導,進而通過?動態規劃(Dynamic programming)?思想,將其推導泛化到多變量的情況。需要注意的是,雖然后向傳播概念上并不復雜,所用到的數學工具也很基本,但由于所涉及的變量較多、分層等特點,在推導的時候需要比較仔細,類似繡花。
單參數情況
特例
在討論后向傳播算法之前,我們簡單回顧一下單變量微積分中的求導規則。來看個例子,假設我們有一個極端簡化的網絡,其中只有一個需要學習的參數,形式如下
并且假設損失函數Cost為平方誤差(MSE)。
假設我們只有一個訓練樣本。因為這個形式非常簡單,我們試試將樣本直接帶入損失函數:
顯然當時,我們可以讓損失函數為0,達到最優。下面讓我們?假裝?不知道最優解,考慮如何用梯度下降方法來求解。假設我們猜為最優,帶入計算得到
嗯,不算太壞的一個初始值。讓我們計算其梯度,或者損失函數關于的導數。
設置學習率參數,我們可以通過梯度下降方法來不斷改進,以達到降低損失函數的目的。三十個迭代的損失函數變化如下:
生成上圖采用的是如下Python代碼
import matplotlib.pyplot as plt
w0, eta, n_iter = 2, 0.02, 30
gradient_w = lambda w: 2*(w**3)
cost = lambda w: 0.5*(w**4)
costs = []
w = w0
for i in range(n_iter):
costs.append(cost(w))
w = w – eta*gradient_w(w) # SGD
plt.plot(range(n_iter), costs)
可以發現,經過30次迭代后,我們的參數從初始的2改進到了0.597,正在接近我們的最優目標。
對于一般的情況
回憶一下,上面的結果是基于我們給定?下得到的,注意這里我們假設輸入信號為常量。我們將上面的求解步驟做一點點泛化。
重復上面的求解
關于w求導,
注意,上面求導用到了?鏈式法則(Chain Rule),即
或者寫成偏導數形式:
對于一般性損失函數的情況
上式推導基于損失函數為平方最小下得出,那么我們再泛化一點,對于任意給定的可導損失函數,其關于的梯度:
其中是損失函數關于的導數。實際上這個形式很通用,對于?任意?特定的損失函數和神經網絡的激活函數,都可以通過這個式子進行梯度計算。譬如,對于一個有三層的神經網絡
同樣通過鏈式法則,
上式看上去比較復雜,我們可以在符號上做一點簡化。令每一層網絡得到的激活函數結果為,即, 那么:
即:不論復合函數本身有多么復雜,我們都可以將其導數拆解成每一層函數的導數的乘積。
上面的推導我們給出了當神經網絡僅僅被一個可學習參數所刻畫的情況。一句話總結,在單參數的網絡推導中,我們真正用到的唯一數學工具就是?鏈式法則。實際問題中,我們面對的參數往往是數以百萬計的,這也就是為什么我們無法采用直覺去“猜”到最優值,而需要用梯度下降方法的原因。下面我考慮在多參數情況下,如何求解梯度。
多參數情況
首先,不是一般性的,我們假設所構建的為一個層的神經網絡,其中每一層神經網絡都經過線性變換和非線性變換兩個步驟(為簡化推導,這里我們略去對bias項的考慮):
定義網絡的輸入,而作為輸出層。一般的,我們令網絡第層具有個節點,那么。注意此時我們網絡共有個參數需要優化。
為了求得梯度,我們關心參數關于損失函數的的導數:,但似乎難以把簡單地與損失函數聯系起來。問題在哪里呢?事實上,在單參數的情況下,我們通過鏈式法則,成功建立第一層網絡的參數與最終損失函數的聯系。譬如,,的改變影響函數的值,而連鎖反應影響到的函數結果。那么,對于值的改變,會影響,從而影響。通過的線性變換(因為),的改變將會影響到每一個。
將上面的過程寫下來:
可以通過上式不斷展開進行其梯度計算。這個方式相當于我們枚舉了?每一條?改變對最終損失函數影響的?路徑。通過簡單使用鏈式法則,我們得到了一個?指數級?復雜度的梯度計算方法。稍仔細觀察可以發現,這個是一個典型的遞歸結構(為什么呢?因為定義的是一個遞歸結構),可以采用動態規劃(Dynamic programming)方法,通過記錄子問題答案的進行快速求解。設用于動態規劃的狀態記錄。我們先解決最后一層的邊界情況:
上式為通用形式。對于Sigmoid, Tanh等形式的element-wise激活函數,因為可以寫成的形式,所示上式可以簡化為:
即該情況下,最后一層的關于的導數與損失函數在導數和最后一層激活函數在的導數相關。注意當選擇了具體的損失函數和每層的激活函數后,與也被唯一確定了。下面我們看看動態規劃的?狀態轉移?情況:
成功建立與的遞推關系,所以整個網絡的可以被計算出。在確定了后,我們的對于任意參數的導數可以被簡單表示出:
至此,我們通過鏈式法則和動態規劃的思想,不失一般性的得到了后向傳播算法的推導。
轉載于:https://www.cnblogs.com/davidwang456/articles/5607057.html
總結
以上是生活随笔為你收集整理的当我们在谈深度学习时,到底在谈论什么(二)--转的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 当我们在谈深度学习时,到底在谈论什么(一
- 下一篇: 当我们在谈深度学习时,到底在谈论什么(三