BP演算法的矩陣操作問題?

W=W-α*(dJ/dW)

求一個單個權值我會求,求權值的矩陣,每一個鏈式求導的結果要與原來權值的位置一一對應,怎麼安排矩陣?

反向更新權值的時候全是numpy矩陣操作,有時候需要轉置,有時候不需要,不是很明白,請大牛講一下

好幾層的權值要用循環去算,如何安排?


這個問題我記得知乎上有專門討論過。

一個非常聰明但是不深究本質的方法是,按照標量的鏈導法則去對張量求導,然後根據維度相容的性質去調整那些不可交換的操作的順序。(這個方法我在知乎上看到有人專門發文章講過,但是剛剛沒找到,要是有人知道希望幫忙補個鏈接。

具體方法如下:

比如 A_i 是第i層輸入, B_i 是第i層輸出。 B_i 經過 W_{i+1}b_{i+1} 的一個任意前向函數得到 A_{i+1}

比方說是多層感知器,那麼你腦子裡就記住某層輸入是 n 維,輸出 n 維,下一層輸入是 m 維,那麼這兩層之間的權值矩陣就是 m n 列的,記這一層權值矩陣的下表和輸入層數對應(也就是從2開始的。

反傳時,記第i層輸入導致的誤差為 delta_{i}

delta_i =frac{partial error}{partial A_i}= frac{partial error}{partial A_{i+1}} { frac {partial A_{i+1}}{partial B_i} } frac{partial B_i}{partial A_i}

delta_i =frac{partial error}{partial A_i}= frac{partial error}{partial A_{i+1}} { W_{i+1} } frac{partial B_i}{partial A_i}

但是,維數要相容

那麼順序就變成

delta_i =frac{partial error}{partial A_i}= (W_{i+1}^T frac{partial error}{partial A_{i+1}} ) cdot frac{partial B_i}{partial A_i}

當然了,這個其實是不太乾貨的做法。

正確的推導並不難於推出。

對任意的 k 考慮frac {partial error}{partial A_{i, k}}

frac {partial error}{partial A_{i, k}} = sum_{t} (frac {partial error}{partial A_{i+1, t}} frac{partial A_{i+1, t}}{partial B_{i, k}}) frac{partial B_{i,k}}{partial A_{i,k}}

嗯,MLP的前傳是 A_{i+1} = W_{i+1}B_i+b_{i+1} ,對所有 t 從上一層第 k 個到下一層第 t 個,

frac {partial error}{partial A_{i, k}} = sum_{t} (frac {partial error}{partial A_{i+1, t}} w_{t, k}) frac{partial B_{i,k}}{partial A_{i,k}}

你看到這裡其實就是內積里權值的一行乘後一層誤差的一列得到一個標量,再和另一個標量做乘積。

所以很簡單,之所以可以寫成矩陣操作,是可以通過歸納得到的。

如果你眼神不夠好,還沒看出來,我就說點廢話

首先

delta_{i+1} = frac{partial error}{partial A_{i+1} } = left[ egin{array}{} frac{partial error}{partial A_{i+1, 1} }\ frac{partial error}{partial A_{i+1}, 2} \ ;;;cdots \ frac{partial error}{partial A_{i+1,n} } end{array} 
ight]

i+1 層權值矩陣轉置後的第 k 行是

(W^T _{i+1})_k = left[ egin{array}{} w_{k,1}, w_{k,2},... ,w_{k,m}end{array}
ight]

對於第 i 層激活函數 f

frac{partial B_{i,k}}{partial A_{i,k}} = f

frac {partial error}{partial A_{i, k}} = ((W^T_{i+1})_k delta_{i+1}) f

然後想一下,把 k = 1..nn 個結果豎著疊起來。

delta_{i+1} = frac{partial error}{partial A_{i+1} } = left[ egin{array}{} ((W^T_{i+1})_1 delta_{i+1}) f

如上所示,證畢。


把權值的矩陣 (x) 拉成一維的,然後套用下圖的公式即可:

詳見 Deep Learning Book 第六章


代碼收好https://github.com/Ryanshuai/numpy_cnn

完整的cnn加反傳,優化器代碼。

不要用python循環寫,效率太低。

用numpy矩陣運算是在c層面上for循環。


剛好為這個事情糾結過。矩陣求導術(上),這個是我見過最優雅的方法了。fuck vectorization,這個是我拿求導術懟cs231n的cnn之前的網路BP,完全OK。cnn及之後的網路沒這麼簡單了,需要im2col等演算法。不過手推BP的意義在於加深理解,實際要用的話現在都是框架自動求了。


推薦閱讀:

BLAS簡介
學習機器學習時需要儘早知道的三件事
機器學習--感知機科普入門
Python · 神經網路(六)· 拓展
One-Page AlphaGo -- 10分鐘看懂AlphaGo的核心演算法

TAG:機器學習 | 神經網路 | Python庫 | numpy |