神經網絡反向傳播的數學原理(轉)

若是能二秒內在腦殼裏解出下面的問題,本文便結束了。php

已知:[公式],其中[公式]編程

求:[公式][公式][公式]網絡



到這裏,請耐心看完下面的公式推導,無需長久內心建設。數據結構

首先,反向傳播的數學原理是「求導的鏈式法則」 :函數

[公式][公式][公式]的可導函數,則[公式]優化

接下來介紹3d

  • 矩陣、向量求導的維數相容原則
  • 利用維數相容原則快速推導反向傳播
  • 編程實現前向傳播、反向傳播
  • 卷積神經網絡的反向傳播

快速矩陣、向量求導

這一節展現如何使用鏈式法則、轉置、組合等技巧來快速完成對矩陣、向量的求導orm

一個原則維數相容,實質是多元微分基本知識,沒有在課本中找到下列內容,維數相容原則是我我的總結:教程

維數相容原則:經過先後換序、轉置 使求導結果知足矩陣乘法且結果維數知足下式:ci

若是[公式], [公式],那麼[公式]

利用維數相容原則解上例:

step1:把全部參數當作實數來求導,[公式]

依據鏈式法則有[公式][公式][公式]

能夠看出除了[公式][公式][公式]的求導結果在維數上連矩陣乘法都不能知足。

step2:根據step1的求導結果,依據維數相容原則作調整:先後換序、轉置

依據維數相容原則[公式],但[公式][公式][公式],天然得調整爲[公式]

同理:[公式],但 [公式][公式][公式],那麼經過換序、轉置咱們能夠獲得維數相容的結果[公式]

對於矩陣、向量求導:

  • 「當作一維實數使用鏈式法則求導,而後作維數相容調整,使之符合矩陣乘法原則且維數相容」是快速準確的策略;
  • 「對單個元素求導、再整理成矩陣形式」這種方式整理是困難的、過程是緩慢的,結果是易出錯的(不信你試試)。


如何證實通過維數相容原則調整後的結果是正確的呢?直覺!簡單就是美...

快速反向傳播

神經網絡的反向傳播求得「各層」參數[公式][公式]的導數,使用梯度降低(一階GD、SGD,二階LBFGS、共軛梯度等)優化目標函數。

接下來,展現不使用下標的記法([公式][公式]or[公式])直接對[公式][公式]求導,反向傳播是鏈式法則和維數相容原則的完美體現,對每一層參數的求導利用上一層的中間結果完成。

這裏的標號,參考UFLDL教程 - Ufldl

前向傳播:

[公式] (公式1)

[公式] (公式2)

[公式]爲第[公式]層的中間結果,[公式]爲第[公式]層的激活值,其中第[公式]層包含元素:輸入[公式],參數[公式][公式],激活函數[公式],中間結果[公式],輸出[公式]

設神經網絡的損失函數爲[公式](這裏不給出具體公式,能夠是交叉熵、MSE等),根據鏈式法則有:

[公式][公式]

這裏記 [公式],其中[公式] 、 [公式]可由 公式1 得出,[公式]加轉置符號[公式]是根據維數相容原則做出的調整。

如何求 [公式]? 可以使用以下遞推(需根據維數相容原則做出調整):

[公式]

其中[公式]、 [公式]

那麼咱們能夠從最頂層逐層往下,即可以遞推求得每一層的[公式]

注意:[公式]是逐維求導,在公式中是點乘的形式。

反向傳播整個流程以下:

1) 進行前向傳播計算,利用前向傳播公式,獲得隱藏層和輸出層 的激活值。

2) 對輸出層(第[公式]層),計算殘差:

[公式](不一樣損失函數,結果不一樣,這裏不給出具體形式)

3) 對於[公式]的隱藏層,計算:

[公式]

4) 計算各層參數[公式][公式]偏導數:

[公式]
[公式]


編程實現

大部分開源library(如:caffe,Kaldi/src/{nnet1,nnet2})的實現一般把[公式][公式]做爲一個layer,激活函數[公式]做爲一個layer(如:sigmoid、relu、softplus、softmax)。

反向傳播時分清楚該層的輸入、輸出即能正確編程實現,如:

[公式] (公式1)

[公式] (公式2)

 

(1)式AffineTransform/FullConnected層,如下是僞代碼:

注: out_diff = [公式] 是上一層(Softmax 或 Sigmoid/ReLU的 in_diff)已經求得:

[公式] (公式 1-1)

[公式] (公式 1-2)

[公式] (公式 1-3)

 

(2)式激活函數層(以Sigmoid爲例)

注:out_diff = [公式]是上一層AffineTransform的in_diff,已經求得,

[公式]

在實際編程實現時,in、out多是矩陣(一般以一行存儲一個輸入向量,矩陣的行數就是batch_size),那麼上面的C++代碼就要作出變化(改變先後順序、轉置,把函數參數的Vector換成Matrix,此時Matrix out_diff 每一行就要存儲對應一個Vector的diff,在update的時候要作這個batch的加和,這個加和能夠經過矩陣相乘out_diff*input(適當的轉置)獲得。

若是熟悉SVD分解的過程,經過SVD逆過程就能夠輕鬆理解這種經過乘積來作加和的技巧。

丟掉那些下標記法吧!

 

卷積層求導

卷積怎麼求導呢?實際上卷積能夠經過矩陣乘法來實現(是否旋轉無所謂的,對稱處理,caffe裏面是否是有image2col),固然也可使用FFT在頻率域作加法。

那麼既然經過矩陣乘法,維數相容原則仍然能夠運用,CNN求導比DNN複雜一些,要作些累加的操做。具體怎麼作還要看編程時選擇怎樣的策略、數據結構。

 

快速矩陣、向量求導之維數相容大法已成。

相關文章
相關標籤/搜索