本文主要是藉助參考文獻1《Notes on Convolutional Neural Networks》的內容,以及博客【2】和【3】裏面的內容,對卷積神經網絡的推導做個梳理。
激活函數
logistic function
σ(x)=11+e−x
hyperbolic tangent
tanh(x)=e2x−1e2x+1
兩者之間的關係
tanh(x)=2σ(2x)−1
對激活函數求導,我們有
∂tanh(x)∂x=1−tanh(x)2
∂σ(x)∂(x)=σ(x)(1−σ(x))
Loss Function 及求導
一般定義pre-activation(輸出層神經單元用k表示):
ak=∑h∈HLwhkbh
所以對於輸出層,每個類別的概率可以用softmax函數來計算:
p(Ck|x)=eak∑Kk′=1eak′
ground truth 的類別z用個one-of-k維的向量來表示。這樣的話,目標label的概率爲
p(z|x)=∏k=1Kyzkk
對於損失函數,一般可以用negtative log likelihood
L(x,z)=−lnp(z|x) ,得到:
L(x,z)=(z−1)ln(1−y)−zlny
對於多分類的問題,可以有
L(x,z)=−∑k=1Kzklnyk
或者採用【1】中最小二乘形式的損失函數
EN=12∑n=1N∑k=1c(znk−ynk)2
znk (【1】用
znk 表示)是第n個實例的ground truth的對應第k個維度的label (0 or 1表示是否是這個類別).
從這個形式可以看出來,最小化差方形式的損失函數,等價於同時最大化truth label的概率,最小化false label的概率。而negtative log likelihood 只是最大化truth label的概率。
Loss function對output以及pre activation的求導:
∂L(x,z)∂yk=−zkyk
對於二分類的情況
∂L(x,z)∂y=−1−z1−y−zy=y−zy(1−y)
利用鏈式法則,可以得到對於pre-activation的導數
∂L(x,z)∂a=∂L(x,z)∂y∂y∂a=y(1−y) y−zy(1−y)=y−z
對於多分類的偏導,也可以使用類似的方式求偏導
∂L(x,z)∂ak=∑k′=1K∂L(x,z)∂yk′∂yk′∂ak
最後可以得到
∂L(x,z)∂ak=yk−zk
我們用上標
l 表示該蠶食是位於第
l 層,當前層,那麼當前層的輸出可以表示爲
xl=θ(al),al=Wlxl+bl
θ 是激活函數,可以取sigmoid
σ 或是
tanh 函數。
反向傳播
由於神經網絡是有多層,但是隻有輸出層纔有ground truth的label以及模型輸出,根據“誤差”向誤差減小方向調整權值。但是對於隱含層,沒有ground truth label,這就需要由輸出層將“誤差”傳播到隱含層。這裏的“誤差”,是損失函數對pre-activation的偏導,也可以看做損失函數對於bias b的敏感度:
δ=∂E∂b=∂E∂a∂a∂b
由
al=Wlxl+bl 知道,
∂a∂b=1 ,所以這個解釋也可以說的過去。下面是如何反向傳播
δ
δl=∂E∂xl∂xl∂al=∂xl∂al∑∂E∂al+1∂al+1∂xl=θ′(al)∘(Wl+1)Tδl+1
其中
∘ 表示element-wise product。
對於輸出層的
δ ,若是損失函數是negtative log,
δL=∂E∂a=y−z
粗體
y 是softmax的輸出概率,
z 是目標label的one-of-k 向量。
對於差方損失,
δ 可以得到
δL=θ′(al)∘(yn−zn)
有了
δ ,就可以通過鏈式法則來求得對於中間層的偏導:
∂E∂Wl=∂E∂al∂al∂Wl=δl(xl−1)T
ΔWl=−η∂E∂Wl
η 是學習速率,【1】中介紹實際中對於每個
Wij 都會有一個學習速率
ηij
卷積神經網絡
卷積神經網絡(CNN),含有兩種類型的網絡連接,卷積層和sub-sampling層。
卷積層
每個輸出層可以由多個輸入層卷積的組合得到,也就是說
xlj=θ(∑i∈Mjxl−1i∗klij+blj)
對於每個輸出層map的每個輸入層map,可以用不同的kernel
klij
Mj 表示第
j 輸出map的輸入map集合。
下采樣層
下采樣層每個輸出層是對對應輸入層的下采樣,所以輸入層輸出層都是N
xlj=θ(βljdown(xl−1j)+blj)
down(.) 表示下采樣,一般來說,這個函數會對一個
n×n 大小的block求和,然後乘以一個乘法 bias
β 和一個加法
b .
卷積層梯度的計算
類似於BP算法過程,首先是求得下一層敏感度和下一層權值的內積,然後做點乘。在CNN中,卷積層與sub-sampling層是依次挨着的。sub-sampling對nxn大小的block求和,可以看做權值是1。所以先要用nxn大小的全1矩陣與下一層敏感度矩陣做Kronecker積,完成權值相乘與上採樣,得到與當前層敏感度大小map。然後與激活函數導數做點乘。
當然,【1】中提到了下采樣之後用一個大小爲β 的標量相乘,看做下采樣層的權值都爲β ,所以這裏在計算完之後乘以一個β 。所以式子就是
δlj=βl+1j(θ′∘up(δl+1j))
其中,上採樣就是與全1矩陣做一個Kronecker積
up(x)=x⊗1n×n
這樣的話,對於特定map的敏感度求和就得到了對應的bias偏導
∂E∂bj=∑u,v(δlj)u,v
對權值求導就是該權值相連的前一層數據和和當前層的敏感度乘積,由於是共享權值,所以每個權值鏈接的不是單一輸入輸出,所以要對所有該權值連接的數據進行求和
∂E∂Wlij=∑u,v(δlj)u,v(pl−1i)u,v
按照【1】中的說法這裏單獨記錄kernel的每個權值在相鄰兩層的連接元素比較麻煩,但是由於kernel和out map以及input map都是矩形,而且卷積過程是順序操作,顯然可以用互相關來得到對應元素的乘積。可以使用matlab的卷積來進行互相關運算,只不過要先將數據進行翻轉。
可以這麼解釋,假設一個
k×k 大小的kernel和一個
N×N 大小的圖像進行卷積操作,生成的map是
(N−k+1)×(N−k+1) ,對於kernel上的每個weight,會和原來圖像的一個
(N−k+1)×(N−k+1) 大小的連續區域的所有元素進行乘積。假設
(1,1) 位置的kernel的weight,會和原來map(圖像)右下方
(N−k+1)×(N−k+1) 的區域每個元素乘積,然後貢獻到下層map的
(N−k+1)×(N−k+1) 的每個對應位置上。所以與(1,1)相關的元素是輸入層map的右下方的
(N−k+1)×(N−k+1) 和輸出層的
(N−k+1)×(N−k+1) 大小map。所以說反向傳播過程中的偏導計算可以使用互相關操作來完成,用matlab代碼:
∂E∂kli,j=rot180(conv2(xl−1i),rot180(δlj,′valid′))
注意到前面還有一個
rot180 操作,那是因爲(1,1)在輸入層map對應的是右下方
(N−k+1)×(N−k+1) 區域,所以互相關之後還是在右下方
(k,k) 位置,所以要旋轉180度得到(1,1)位置。
下采樣層梯度的運算
首先是計算敏感度map δlj ,由反向傳播計算下一層的敏感度δl+1j 計算,與kernel相乘然後與激活函數的導數做element-wise相乘。下一層是卷積操作,當前層map的每個元素通過kernel的不同鏈接與下一層的map的多個元素有鏈接。所以用下一層map敏感度與kernel進行互相關操作得到BP敏感度公式中權值和下層敏感度的乘積。
δlj=θ′(alj)∘conv2(δl+1j,rot180(kl+1j),′full′)
注意到這裏用的是full,在前向過程計算下層中,下層元素每維度少了
k−1,(n−k+1)×(n−k+1) ,所以對於邊緣,例如input map (1,1)位置,只和output map的(1,1)有關,所以需要用0補全然後再做互相關操作。
然後就是求參數
bj 和
βj 的偏導了。
bj 的偏導仍是把該層敏感度相加
∂E∂bj=∑u,v(δlj)u,v
然後求權值偏導,首先保存下采樣數據
dlj=down(xl−1j)
然後對所有相連的數據相乘求和
∂E∂βj=∑u,v(δlj∘dlj)u,v
學習特徵map的組合
現有的output map是由多個不同的map組合的,但是如何組合目前還是通過人工的方式進行選擇,如何自動地進行學習哪些input map可以組成哪些output map呢?
我們設定αij 是組成output map j時,input map i所佔有的權重,所以就有:
xlj=θ(∑i=1Ninαij(xl−1i∗kli+blj)
subject to
∑iαij=1, and 0≤αij≤1
αij 是一個概率,可以用softmax函數來表示
αij=exp(cij)∑kexp(ckj)
cij 表示對應的weight,由於這裏j都是一樣,所以可以把下班j省立
對
cj 求偏導
∂αk∂ci=δkiαi−αiαk
這裏的
δki 是指示函數,k==i時爲1,不等時爲0.
再求損失函數對
αi 的偏導
∂E∂αi=∂E∂al∂al∂αi=∑u,v(δl∘(xl−1i∗kli))u,v
然後合併起來
∂E∂ci=∑k∂E∂αk∂αk∂ci=αi(∂E∂αi−∑k∂E∂αkαk)
關於sparsity
加上1範數的regularization。
E~n=En+λ∑i.j|(αi,j)|
求導:
∂Ω∂ci=∑k∂Ω∂αk∂αk∂ci=λ(|αi|−αi∑k|αk|)
整個偏導公式:
∂E~n∂ci=∂En∂ci+∂Ω∂ci
參考文獻:
【1】Notes on Convolutional Neural Networks
【2】
http://blog.csdn.net/zouxy09/article/details/9993371
【3】
http://www.cnblogs.com/tornadomeet/p/3468450.html
【4】Supervised Learning with Recurrent Neural Networks