回顧一下梯度下降的過程:
假設當前神經網路有以下引數\(\theta = \{\omega_1,\omega_2,...,b_1,b_2,...\}\),那麼梯度下降就是計算損失函式對於每個引數的梯度,然後按照梯度更新公式來更新每一個引數。但在深度學習中引數量巨大,這樣計算時間過長,因此反向傳播就是來高效就計算出損失函式對於每個引數的梯度的。注意反向傳播並不是一個和梯度下降不同的訓練方法,它只是能夠更有效率就計算出損失函式對引數的梯度,來幫助梯度下降過程。
反向傳播
損失函式可以如下表示:
其中\(C^n(\theta)\)表示第n個樣本的輸出值和理想值之間的距離。那麼:
也就是將總體損失對引數的微分轉換成每一個樣本的距離對引數的微分的求和。
假設對於圖上網路:
其中:
- \(\frac{\partial z}{\partial w}\):稱為前向傳播(Forward pass),較為容易計算
- \(\frac{\partial C}{\partial z}\):稱為反向前進(Backward pass),較難計算
Forward pass
從上圖中我們可以很簡單地算出
也就是說對於每條邊或者說每個引數,它所連線的下一層的輸入對於該引數的求導就等於上一層在這條邊上的輸入,例如下圖:
所以前向傳播這一步可以很簡單的計算出來。
Bcakward pass
現在需要來考慮如何計算\(\frac{\partial C}{\partial z}\),假設前述z經過一個Sigmoid函式後得到a,那麼a作為下一層神經網的某一個輸入,因此就可以寫出:
而從上圖中也可以很清楚地看到**可以用微積分的知識轉換成上述公式,而其中對a的求導也可以結合我們上述的知識很容易的求解。因此現在就是如何求解C對兩個z的求導了。
但假設我們當前能夠透過某種方法知道了C對兩個z的求導,同時我們將網路進行些許轉換,如下:
根據那個公式我們可將網路反向過來,這有助於待會理解反向傳播。不過值得注意的是此處神經元結點對於輸入加權和後是乘上\(\sigma`(z)\),在z確定的時候(當輸入確定時z就確定了)可以看成常數,因此跟正向神經網路的非線性變化不同。
繼續計算C對兩個z的求導:
情況一:
假設\(z`\)和\(z``\)經過非線性變換後已經就是輸出了,那麼這種簡單的情況可以很簡單的寫出上面的計算式,也就很簡單的完成了我們對於引數梯度的計算工作。其中
情況二:
假設\(z`\)和\(z``\)後面仍然有很多未知的線性變化,但透過前述的講解我們可以明確只要知道了下一層的C對各個z的求導,那麼就一定可以算出當前層C對各個z的求導。因此只要不斷地往後推,找到某一層的z經過非線性變換後就是輸出,那麼就可以計算C對該層的z的求導(情況一),然後再往前推直到C對每一層的z的求導都算出來。
那麼在實際上的做法就是:
- 建立一個反向的神經網路,其結構相同權重引數相同,但是功能神經元結點的非線性變換變成了常數,就是之前的\(\sigma`(z)\),這需要先計算Forwardpass之後才可以計算(其中還需要計算\(\frac{\partial z}{\partial w}\))
- 計算損失函式C對最後一層的每個z的求導,那麼它們就是這個反向神經網路的輸入引數
- 再根據網路的不斷傳播就可以計算出最終結果
這就是反向傳播。