卷積神經網路(CNN)
引入:全連線神經網路在影像處理方面所遇到的困難
作為一幅影像,其中的資訊維度通常是很高的,在引數如此巨大的情況下,難以獲取足夠資料防止神經網路的欠擬合。因此我們需要一種運算方式來減小輸入全連線網路的特徵向量的維度。這種運算就是卷積運算。
一個完整的卷積神經網路通常由三部分構成,分別是卷積層(Conv)、池化層(Pool)和全連線層(FC)。
1.什麼是卷積?
-
卷積(convolution),指的是數字影像處理的卷積操作,簡單概括為對應相乘再相加,如圖
-
二維卷積
-
image代表原始的影像,卷積一般有卷積模板(或者叫卷積核),圖中黃色方塊右下角組成的3×3 的卷積核,該卷積核為:
\[\left[\begin{matrix} 1& 0& 1 \\ 0& 1& 0 \\ 1& 0& 1 \\ \end{matrix}\right] \]-
Valid convolution:可以看出在經過3×3 的卷積核卷積操作之後,生成的feature map尺寸和原影像不一樣,卷積操作隱含一個引數stride(步長),步長就是卷積核滑動的長度,這裡預設stride=1。假設原始影像尺寸為$M\times N \(,卷積核尺寸為\)W_{1} \times W_{2}$ ,步長stride=S,則feature map的尺寸為
\[((M−W_{1})/S+1)×((N−W_{2})/S+1) \]**(但是我們發現這樣的運算方式對影像邊緣的資訊利用較少,甚至經過多次卷積運算之後,原影像邊角的畫素資訊基本無法保留下來,那麼該怎麼去改善這樣的情況呢?)
-
Same convolution:我們需要引入padding的概念,也就是擴充套件畫素,這裡設定padding=1,(即原始影像上下左右擴充套件1個畫素,一般用0填充),則經過padding後的影像尺寸為\(7 \times 7\),再透過卷積則會得到$ 5\times 5$的feature map。則padding=P,則feature map輸出尺寸為
\[((M−W_{1}+2P)/S+1)×((N−W_{2}+2P)/S+1) \]*(括號內不能整除則需向下取整)
-
-
三維卷積
影像處理來講,影像資訊通常是三維的(每個畫素點包含RGB三通道值)。卷積核也需要相應地擴充維度,此時的卷積可以想象為下面的樣子。
三個維度的名稱分別為height×width×channels,卷積核與原影像的通道數必須保持一致。運算出的結果是一個4×4×1的矩陣。- 具體的運算規則:
將卷積核視為一個3×3×3的立方體,原影像可以看作一個6×6×3的槽。卷積核先放入原影像的左上角中,對應的27個數相乘後加和,得到輸出影像矩陣(1,1)畫素值,之後卷積核以一定步幅滑動,與二維卷積大同小異。
稍加思考可以發現,上述運算步驟可以分解為3個互不相關的二維卷積,得到3個4×4的輸出影像。三維卷積的結果只是將這3個二維卷積輸出結果疊加起來而已。
針對這種特性,並且由於不同通道間的互不相關,我們可以賦予卷積核上各通道以不同的功能。具體應用對RGB不同通道的不同處理。
*當然我們也可以使用多個卷積核來提取不同的特徵,如用兩個卷積核,我們就可以得到兩個$ 4\times 4\(的矩陣,將它們疊放在一起就可以得到維度\) 4 \times 4 \times 2$,也就是也就是說輸出影像的通道數取決於使用的卷積核的個數。這樣我們就可以檢測原影像的多種特徵,而這些特徵都將體現在輸出影像的各個通道中。
卷積層(ConvNet)
事實上,用多個卷積核對一個多通道影像做卷積運算,最後得到一個新的多通道影像的計算過程,就構成了卷積層的一個單元。而像下圖所示這樣將若干個單元串在一起,就得到了一個簡單但完整的卷積層。
其中\(n^{[i]}_H\),\(n^{[i]}_W\),\(n^{[i]}_C\)分別為每層影像的高、寬、通道數(原影像i=0),\(f^{[i+1]}\) ,\(s^{[i+1]}\),\(p^{[i+1]}\)分別是作用於第i層影像的卷積核的邊長、卷積步幅、Padding值,同時卷積核的個數決定了第i+1層影像的通道數\(n^{[i]}_C\)。
從上述例子裡我們可以看出,通常情況下,隨著卷積層深度的增加,影像的長寬逐漸減小,而通道數逐漸增大。經過上面的卷積層,影像的特徵量39×39×3=4563減小為7×7×40=1960,之後就可以將這1960個特徵量展開為一個長度為1960的向量,作為輸入向量X傳入全連線神經網路。或者會在這二者間加上一個池化層,這就涉及卷積神經網路的結構了。
非線性啟用ReLu:
-
ReLu啟用函式是在CNN中經常用到的,\(ReLu(x)=max(0,x)\),卷積層對原圖運算多個卷積產生一組線性啟用響應,而非線性啟用是對之前的結果進行非線性的響應。
-
是對卷積後的特徵圖進行有目的的提取,小於0的不是識別特徵,故記為0,而大於0的就是與卷積模板匹配的特徵保留下來。
池化層(Pooling Layers)
首先需瞭解池化層是如何工作的。
1.最大池化(Max pooling)
以最大池化為例,我們將一個4×4的原影像分割為4個2×2的子區域,每個子區域中提取最大值即可。
上面就是Max Pooling 的過程,其中藍色的是池化模板的尺寸為\(2\times 2\),池化也有stride步長,一般stride=2,最大池化就是取\(2 × 2\)特徵值中的最大值,然後以stride=2進行移動池化模板,遍歷完整個feature map。設原來feature map尺寸為\(M × N\),池化模板尺寸為\(W × W\) ,步長為S(一般取2),padding 為P(池化也可以先padding,不過要注意的是,在池化中通常不設定padding值,即p=0。),可以得到池化層的輸出尺寸公式:
多通道影像的池化也很容易想象,各通道分別做池化,再將結果疊放在一起。所以池化的輸入和輸出的通道數是一致的。
2.平均池化(Average Pooling)
與最大池化相比,我認為除了輸出取子區域內平均值而非最大值以外,沒有什麼不同,就不再贅述了。
與卷積過程中可以選取不同的卷積核引數相比,池化是一種固定的運算,在確定了超引數後它就不存在繼續調整或是訓練的需要了。
全連線層(FC)
-
上面討論過卷積和池化之後,深度學習CNN的神秘面紗也就被揭開,Deep主要體現在了網路的深度上,也就是許多的卷積層和池化層堆疊的結果,每一層都依據上述原理進行。
-
我們的目的是什麼,回頭看我們要提取影像的高層次特徵不就是為了識別出該影像是什麼嗎?也就是影像分類,那麼經過這麼多卷積和池化之後已經提取了高維特徵,下面就是對其進行分類了,這裡的分類就用的是全連線層,全連線層的作用就是對特徵進行維度上的改變來得到每個分類類別對應的機率值。
-
全連線層就是一個基本的神經網路
這邊需要提一下全連線層最後一層輸出使用的是Softmax分類函式,它可以將網路輸出變成一個機率分佈,且n類的機率相加等於1,這就很方便的可以判斷網路最終分類的結果。
也可以知道全連線層的輸入是將池化後的feature map
先進行了flatten
打平操作,然後再輸出到最後一層,之後透過Softmax函式輸出機率。
卷積層和全連線層的區別
-
全連線:它的每一個神經元都與上一層的神經元進行連線,故稱全連線,相鄰兩層神經元與神經元之間都是透過一個引數相連。
-
卷積層“區域性連線”、“引數共享”的思想:
前面的卷積層就肯定不是全連線了,他是“區域性連線”的思想,每一次只有3×3的卷積核與對應的影像進行相連,只不過這個卷積核透過步長在滑動。也就是說每次只有卷積核大小的影像與卷積核進行引數連線,而未連線的部分是透過將視窗滑動起來的方法進行後續的連線,這個思想就是“引數共享”,這裡的引數就是每個卷積核的值,對於同一個卷積核,在對影像進行卷積時,卷積核是不變的,所以引數可以共用。
CNN的反向傳播
-
在CNN中,我們需要訓練的就是那些卷積核的引數,訓練的方法仍然是之前神經網路的正向傳播和反向傳播演算法,只不過計算每一層的梯度和誤差時不一樣而已。
-
接下來我們只需知道卷積層、Pooling層的誤差以及對每個引數梯度該怎麼求。就可以進行訓練了。而CNN反向傳播演算法的詳細計算方法可以從這篇文章中借鑑<Convolutional Neural Networks backpropagation: from intuition to derivation – Grzegorz Gwardys (wordpress.com)>
-
首先對卷積層來說,\(\delta\)誤差是損失函式對於當前層未啟用輸出\(z^{l}\)的導數\(\delta^{l}(x,y)=\frac{\partial C}{\partial z^{l}}=\sigma^{'}(z^{l})\)
這邊我們用另一篇筆記——卷積神經網路(CNN)反向傳播演算法推導中的結論:
\[\delta^{l}=\delta^{l+1}*{\rm rot180}(w^{l+1})\odot\sigma^{'}(z^{l}) \]其中\({\rm rot180()}\)表示將矩陣旋轉180度,符號\(\odot\)為元素相乘。
而對每一層的誤差項,有
\[\frac{\partial C}{\partial w^{l}}=\delta^{l}*\sigma(z^{l-1}) \]\[\frac{\partial C}{\partial b^{l}}=\sum_{x}\sum_{y}\delta^{l} \] -
池化層的反向傳播
最大池化:記錄下最大值所在的位置。
平均池化:權重平均。
用公式來表示為
CNN的訓練
訓練的基礎演算法是梯度下降演算法
梯度下降常用的三種方法:隨機梯度SGD,Mini-batch梯度下降,BGD
區別:SGD每次需要1個樣本,BGD一次需要全部的樣本,而Mini-batch位於中間。
引數的更新:
CNN整個訓練過程
-
1.對神經網路進行初始化,定義好網路結構,設定好啟用函式,對卷積層的卷積核\(w\)、偏置\(b\)進行隨機初始化,對全連線層的權重矩陣\(W\)和偏置\(b\)進行隨機初始化。
設定好訓練的最大迭代次數,每個訓練batch的大小以及學習率\(\eta\). -
2.從訓練資料中取出一個batch的資料
-
3.從該batch資料中取出一個資料,包括輸入x以及對應的正確標註y.
-
4.將輸入x送入神經網路的輸入端,得到神經網路各層輸出引數\(z^{l}\)和\(a^{l}\)
-
5.根據神經網路的輸出和標註值y計算神經網路的損失函式Loss
-
6.計算損失函式Loss對輸出層的誤差\(\delta^{l}\)
-
7.利用相鄰層之間delta誤差的遞推公式求得每一層的delta誤差
全連線層:
\[\delta^{l}=(W^{l+1})^{T}\delta^{l+1}\odot\sigma^{'}(z^{l}) \]卷積層:
\[\delta^{l}=\delta^{l+1}*{\rm rot180}(w^{l+1})\odot\sigma^{'}(z^{l}) \]池化層:
\[\delta^{l}={\rm upsample(\delta^{l+1})}\odot\sigma^{'}(z^{l}) \] -
8.利用每一層的delta誤差求出損失函式對該層引數的導數
全連線層:
\[\frac{\partial L}{\partial w^{l}}=\delta^{l}(a^{l-1})^{T} \]\[\frac{\partial L}{\partial b^{l}}=\delta^{l} \]卷積層:
\[\frac{\partial L}{\partial w^{l}}=\delta^{l}*\sigma(z^{l-1}) \]\[ \]\[\frac{\partial L}{\partial b^{l}}=\sum_{x}\sum_{y}\delta^{l} \] -
9.將求得的導數加到該batch資料求得的導數之和上(初始化為0),跳轉到步驟3,直到該batch資料都訓練完畢
-
10.利用一個batch資料求得的導數之和,根據梯度下降法對引數進行更新
- 11.重複步驟2,直到到達指定的迭代次數。