反向傳播神經網路推導中給出了複雜的bp公式。從頭看這篇多年的部落格的公式,我都有點被繞暈了。現在在這裡我可以從矩陣計算的角度去演示乙個全連線神經網路的計算過程,這樣更簡潔明瞭。
如上圖,是乙個簡單的分類全連線神經網路,每一根線表示權重相乘。如果沒看透這個計算關係,那麼我們很容易這樣設計程式:每乙個節點都製作乙個class類,每個類節點要與其他類節點有連線關係,要傳遞資料,要計算梯度誤差。這樣做出來的神經網路靈活性很強,但是真的是太複雜了!不靠譜!
假設我們只研究兩層資料之間的關係,每根線代表乙個權重乘法。設權重為w1
ij,前一層資料是x1
i ,後一層資料為x2
j ,那麼後一層每乙個資料就是x2
i=∑i
x1iw
1ij+
b1i 。為了形象表示資料從左向右傳遞的過程,我寫成 [x
11x1
2...
]⎡⎣⎢
⎢w11
jw12
j...
⎤⎦⎥⎥
+b11
如果我們擴充套件計算整個全連線層,就可以得到簡單的矩陣計算:[x
11x1
2...
]⎡⎣⎢
w111w
121..
.w112
w122.
....
.⎤⎦⎥
+[b1
1b12
...]
=[x2
1x22
...]
→x1w
1+b1
=x2
所以,乙個全連線層,實際上就是乙個矩陣乘法和乙個矩陣加法,資料都是向量,權重引數可以用矩陣表示,計算過程能夠編碼為乙個layer類,即乙個神經網路層。相應的,啟用層其實就是對資料向量,逐個元素進行計算,即ac
tiva
tion
(x2)
=[f(
x21)
f(x2
2)..
.]這兩種操作都可以向量化,在gpu中跑的飛快;cpu使用mkl和blas庫也可以大大加速計算。
下面關鍵就是如何計算梯度來修正權重,梯度下降法的定義是θn
ew=θ
old−
∂f∂θ
。矩陣求導的公式(注意上標2並不是平方,是序號)是:∂x
2∂w1
=(x1
)t∂e
∂b1=
i 設損失函式為e。
好了,假設我隨便做乙個神經網路,包含一層全連線層fc
1:xf
c1=x
inpu
twfc
1+bf
c1,一層sigmoid啟用層si
g:xs
ig=s
igmo
id(x
fc1)
,一層全連線層,最後只輸出乙個結果fc
2:y=
xfc2
=xsi
gwfc
2+bf
c2,損失函式是euclidean損失函式e=
12∑(
y′i−
yi)2
,求和是因為我們可能一次性計算乙個批次的資料,即乙個batch,把多次計算的誤差全部加起來。
輸出層誤差梯度為:δ4
=∂e∂
xfc2
=∑(y
′i−y
i)fc2層要計算w、b的梯度,和乙個向上傳遞的梯度:δ3
=∂e∂
wfc2
=∂e∂
xfc2
∂xfc
2∂wf
c2=x
tsig
∑(y′
i−yi
)=xt
sigδ
4∂e∂
bfc2
=∑(y
′i−y
i)=δ
4δup
3=δ4
wtfc
2 sig層不包含w、b,只上傳梯度:δu
p2=∂
xsig
∂xfc
1δup
3=xs
ig.∗
(1−x
sig)
.∗δu
p3.*是元素相乘。這只是乙個過渡層。
fc1層函式梯度:δ1
=∂e∂
wfc1
=∂e∂
xfc2
∂xfc
2∂xs
ig∂x
sig∂
xfc1
∂xfc
1∂wf
c1=x
tinp
utδu
p2∂e
∂bfc
1=∂e
∂xfc
2∂xf
c2∂x
sig∂
xsig
∂xfc
1∂xf
c1∂b
fc1=
δup2
歸納總結一下:
* 設當前層序號為n,輸入資料為xn
,下一層向上傳遞的梯度為δu
pn+1
,則當前層w更新梯度為xt
nδup
n+1 ,b更新梯度為δu
pn+1
,向上傳遞的梯度為δu
pn+1
wtn
* 如果當前層不包含w,b,例如啟用層,則上傳向上傳遞梯度即可
* 輸出層的梯度由損失函式定義。
李巨集毅機器學習筆記 五 全連線神經網路
1 x 1x1 和x2 x 2x2 1x 1 x1 的變換和輸入到x 2x 2 x2 的變換,之後再用x 1x 1 x1 和x 2x 2 x2 來使用邏輯回歸來得到我們想要的結果。當然,這裡有個細節就是紅框畫出來的部分,我們的分析中,作為線性變換,實際上相當於直接是讓z1 x1 z 1 x 1 z1...
python學習 動手寫第乙個類
俗話說 好記性不如爛筆頭 真正開始寫類的時候才發現那是相當累啊。一 題目 編寫乙個類,實現簡單的棧。資料的操作按照先進後出 filo 的順序。主要成員函式為put item 實現資料item插入棧中 get 實現從棧中取乙個資料。二 準備工作 開始之前要做些準備工作,主要是熟悉點規範吧,以後慢慢正規...
第07課 專案實戰 自己動手寫乙個神經網路模型
為了簡化操作,我們直接構造一批資料集。說明 本文所有 均在 jupyter notebook 中編寫實現。import numpy as np import matplotlib.pyplot as plt matplotlib inline r np.random.randn 200 0.8 x1...