李宏毅深度學習筆記 https://datawhalechina.github.io/leeml-notes
李宏毅深度學習視頻 https://www.bilibili.com/video/BV1JE411g7XF
背景
梯度下降
假設有很多參數\(\theta\)
選擇一組初始值\(\theta^0\)
計算\(\theta^0\)對loss function的gradient,也就是計算loss function 對每個網絡里面的參數\(w_1,w_2,...,b_1,b_2...\)的偏微分
更新參數為\(\theta^1\)
在神經網絡里,有很多參數,比如做語音識別系統,神經網絡通常有7,8層,每層1000個神經元,有上百萬個參數。所以\(\Delta L(\theta)\)是個上百萬長的向量。反向傳播就是用來高效求解這些參數的方法,是梯度下降在神經網絡里的延伸。
鏈式法則
反向傳播使用到了鏈式法則
反向傳播
定義一個\(y^n\) 和\(\hat{y}^n\)的距離function \(C^n\),\(C^n\)大說明loss大,參數不好
定義\(L(\theta)\)為總損失函數,對\(w\)偏微分,相當於\(C^n\)對\(w\)的偏微分之和
Forward pass
考慮一個神經元的正向傳播,在計算\(z\)的同時已經可以很容易的知道對\(w\)的偏微分
把損失對參數的偏微分\(\large \frac{\partial C}{\partial w}\)看成兩個部分:
- \(\large \frac{\partial z}{\partial w}\):forward pass
- \(\large \frac{\partial C}{\partial z}\):backward pass
\(\large \frac{\partial z}{\partial w}\)就是看w前面接的的是什么,\(w_1\)前面接的是\(x_1\),微分后就是\(x_1\)
第一層隱藏層對\(w\)的偏微分是輸入層input
第二層隱藏層對\(w\)的偏微分是第一層的output
注意這里都是\(z\)對\(w\)的偏微分,隱藏層的output=\(\sigma(z)\)
Backward pass
z通過激活函數得到a,還要經過之后復雜的process才能得到C
通過鏈式法則做拆解,假設激活函數是sigmoid,那么\(a=\sigma(z)\) ,\(a\)乘以某個\(w_3\)再加上其他一大堆值得到\(z'\) ,是下一個神經元激活函數的input,同樣有\(w_4,z''\)
\(\large \frac{\partial a}{\partial z}\)是sigmoid的微分
\(a\)通過\(z',z''\)去影響C,假設\(a\)后面的層只有兩個神經元,則\(\large \frac{\partial C}{\partial a}\)拆解為兩項,如果有1000個神經元,則拆解為1000項之和
在計算的時候我們可以先假設知道\(\large \frac{\partial C}{\partial z'},\frac{\partial C}{\partial z''}\)的值
從另外一個觀點看\(\large \frac{\partial C}{\partial z}\)
想象成一個新的神經元,\(\large \frac{\partial C}{\partial z'},\frac{\partial C}{\partial z''}\) 是input,\(w_3,w_4\)是對應的權重,再加上一個常數\(\sigma'(z)\)(因為forward pass 的時候z已經算出來了)
之前假設知道\(\large \frac{\partial C}{\partial z'},\frac{\partial C}{\partial z''}\)的值,但最終還是要計算的
情況一:如果要計算的神經元層已經是output層了,通過鏈式法則就可以計算
\(\large \frac{\partial y_1}{\partial z'}\)只要知道紅色神經元的激活函數即可
\(\large \frac{\partial C}{\partial y_1}\)則取決於cost function
情況二:要計算的神經元層不是output層,后面還有其他東西
例如
\(z'\) 通過激活函數得到\(a'\) ,乘以一個權重加上其他東西得到\(z_a,z_b\),再丟進另外兩個激活函數里
如果我們知道\(\large \frac{\partial C}{\partial z_a},\frac{\partial C}{\partial z_b}\),就可以計算\(\large \frac{\partial C}{\partial z'},\frac{\partial C}{\partial z''}\)
類似之前的計算方式,但是又會出現同樣的問題,要去計算\(\large \frac{\partial C}{\partial z_a},\frac{\partial C}{\partial z_b}\)
如果層數很多,會覺得這樣計算很麻煩,要從第一個隱藏層算到輸出層
可以轉換思路,從后面output算起
先算\(z_5,z_6\)的偏微分,再去算\(z_3,z_4\)的偏微分,這樣會覺得簡單一點,因為算\(z_3,z_4\)的偏微分需要用到\(z_5,z_6\)的偏微分
\(z_3,z_4\)怎么用到\(z_5,z_6\)的偏微分?
像之前討論的
\(z_5,z_6\)的偏微分乘以權重和\(\sigma'(z_3),\sigma'(z_4)\),算出\(z_3,z_4\)的偏微分,再乘以權重和\(\sigma'(z_1),\sigma'(z_2)\)算出\(z_1,z_2\)的偏微分
這個步驟就是backward pass
相當於建立了一個新的神經網絡,forward pass的激活函數是sigmoid,算backward pass的時候就是建立一個反向的神經網絡,激活函數就是\(\sigma'(z)\)
總結
反向傳播怎么做?
1.做一個forward pass,同時可以算出\(z對w\)的偏微分
2.做一個backward pass,通過把\(C對z\)的偏微分作為input 反向做一個神經網絡