數據挖掘入門系列教程(十一點五)之CNN網路介紹
在前面的兩篇部落格中,我們介紹了DNN(深度神經網路)並使用keras實現了一個簡單的DNN。在這篇部落格中將介紹CNN(卷積神經網路),然後在下一篇部落格中將使用keras構建一個簡單的CNN,對cifar10
數據集進行分類預測。
CNN簡介
我們可以想一個例子,假如我們現在需要對人進行識別分類,根據我們人類的思維,我們肯定是比較他的👀是不是一樣的,👃是不是一樣大小,是不是雙(or 三)下巴。換句話來說,我們的判斷標準是一個可視的範圍。
CNN就是受到了人類視覺神經系統的啟發,使用卷積核來代替人類中的視野,這樣既能夠降低計算量,又能夠有效的保留影像的特徵,同時對圖片的處理更加的高效。我們可以想一想前面介紹的DNN網路,它是將一個一個的像素點進行計算的,毋庸置疑,這樣必然會帶來參數的膨脹,比如說cifar-10中一張32*32*3的影像,第一個隱藏層的中的單個神經元就有\(32 \times 32 \times 3 = 3072\)個權重,似乎挺小的,但是如果圖片的像素再大一點,則參數會飛速猛增,同時參數增加的同時就會導致過擬合。
下圖是我使用DNN網路去訓練cifar-10得到的結果,可以明顯的看到過擬合:
而CNN就是將DNN中複雜的問題簡單化(實際上更複雜,但是參數簡單化了)。這裡借用Easyai的幾張圖和幾段話:
在下面的場景中,有⚪是1,否則就是0,⚪的位置不同,產生的數據也就不同,但是從視覺的角度上面來說,兩張圖的內容是差不多的,只在於⚪的位置的不同罷了。
而 CNN 解決了這個問題,他用類似視覺的方式保留了影像的特徵,當影像做翻轉,旋轉或者變換位置時,它也能有效的識別出來是類似的影像。
下面是一張來自cs231n中一張識別汽車的圖,使用的是CNN網路,裡面包含了CNN網路的網路層:
在上圖中的CNN網路中,網路層有一下類型:
- CONV:卷積層,進行卷積計算然後求和。
- Relu:激勵層,激勵函數為Relu
- POOL:池化層
- FC:全連接層
可以很明顯的看到,CNN網路與DNN網路有相似,也有不同。在CNN網路中,使用了卷積層和池化層,最後才使用全連接層,而卷積層就是CNN的核心。但是在DNN網路中全部都是全連接層。
下面將對這幾層進行介紹,其中參考了YouTube上How Convolutional Neural Networks work這個影片。該影片有條件的建議去看一看,講的還是蠻形象生動的。
我們以識別一張照片是X
還是O
作為我們的識別目的:
我們如何識別一張新的圖片是X
還是O
,肯定是拿該照片與已有的標準X
和O
照片進行對比,哪一個相似度高,則就認為新的照片是屬於哪一個類別。對比對於人類來說很簡單,但是,對於電腦來說,應該怎麼對比呢?
電腦可以進行遍歷圖片的每一個像素點的像素值,然後與標準圖片的像素值進行比較,但是毋庸置疑,這樣肯定是不行的,比如說在下圖中電腦就認為只有中間的是一樣的,其它四個角都不同,因此可能會得出這張圖片不是X
這個結論。
但是我們肯定是希望不管在平移,旋轉,還是變形的情況下,CNN模型都可以識別出來。
so,我們將比較範圍由像素點擴大到某一個範圍,在CNN模型中,會比較兩張圖片的的各個局部,這些局部稱之為特徵(features)。
每一個feature都是一張小圖,也就是更小的二維矩陣。這些特徵會捕捉圖片中的共同要素。以X
圖片為例,它最重要的特徵就是對角線和中間的交叉。也就是說,任何叉叉的線條或中心點應該都會符合這些特徵。
那麼如何判斷一張圖片中是否有相符合的特徵,然後符合的特徵有多少個,這裡我們使用數學的方法卷積(convolution)進行操作,這個也就是CNN名字的由來。
卷積層(Convolution Layer)
下面我還是將以識別X
作為例子來講解一下如何進行進行卷積。卷積的目的是為了計算特徵與圖片局部的相符程度。
計算的步驟如下:
\]
如果我們將這個\(3 \times 3\)的特徵矩陣沿著該圖片以stide = 1(也就是每次滑動一格),可以得到一個\(7 \times 7\)的矩陣,最終得到的結果如下圖所示:
很容易理解,卷積之後的結果越接近1,則相當與對應位置與特徵feature越接近。分別與三個特徵進行卷積的結果如下所示,得到了feature map:
這裡是一張來自cs231n的一張卷積示意圖:
不過這裡與上面不同的是,它並沒有取平均值,同時加上了一個偏置\(b\),同時最後的結果是三個的的卷積的和。並且加上了一個padding(也就是外面那一層灰色取0的地方)
設輸入的為\(W_1 \times H_1 \times D_1\),卷積核的大小是\(F \times F\),卷積核的數量是\(K\),padding的大小是\(P\),stride步為\(S\),輸出的矩陣的大小是\(W_2 \times H_2 \times D_2\),則:
H_{2}=\left(H_{1}-F+2 P\right) / S+1 \\
D_{2}=K
\]
Relu激勵層
整流線性單位函數(Rectified Linear Unit, ReLU),又稱修正線性單元, 是一種人工神經網路中常用的激勵函數(activation function),通常指代以斜坡函數及其變種為代表的非線性函數。數學表達式為:
\]
Relu激勵層的工作流程如下所示:
將卷積層的輸出通過激勵層後的結果如下:
這一層還是蠻簡單的,可能大家會發現,在深度神經網路中,sigmoid激活函數就很少使用了,這是因為sigmoid函數太小了,在多層神經網路下會出現」梯度消失「現象。
池化(Pooling)
池化層就更加的簡單了,池化層可以大幅度的降低數據的維度。池化層多種,下面介紹兩種簡單常用的:
- 平均池化(
average pooling
):計算影像區域的平均值作為該區域池化後的值。 - 最大池化(
max pooling
):選影像區域的最大值作為該區域池化後的值。
那麼池化是怎麼操作的呢,下面是最大池化進行操作的示意圖:
池化層也就是從一定的範圍(也就是池化層的大小)中選出一個(或者計算出一個)值作為這個區域範圍的代表。
對所有的feature map都進行池化,最後的結果如下:
因為最大池化(max-pooling)保留了每一個小塊內的最大值,所以它相當於保留了這一塊最佳的匹配結果(因為值越接近1表示匹配越好)。這也就意味著它不會具體關注窗口內到底是哪一個地方匹配了,而只關注是不是有某個地方匹配上了。這也就能夠看出,CNN能夠發現影像中是否具有某種特徵,而不用在意到底在哪裡具有這種特徵。這也就能夠幫助解決之前提到的電腦逐一像素匹配的死板做法。
設輸入的為\(W_1 \times H_1 \times D_1\),池化層的大小是\(F \times F\),stride步為\(S\),輸出的矩陣的大小是\(W_2 \times H_2 \times D_2\),則:
&W_{2}=\left(W_{1}-F\right) / S+1\\
&H_{2}=\left(H_{1}-F\right) / S+1\\
&D_{2}=D_{1}
\end{aligned}\end{equation}
\]
結合卷積層、激勵層、池化層
我們將前面所講的卷積層,激勵層,池化層進行結合,所得:
加大網路的層數就得到了深度神經網路:
全連接層(Fully connected layers)
通過前面得卷積,池化操作,我們成功得將數據進行了降維,得到降維後的數據後,我們在將其放入全連接層中,就可以得到最終得結果。
還是以上面識別X為例子:
我們稱之這一層為全連接層。
當然全連接層也可以有多個:
綜上,所有得結構我們可以表達為:
同時我們可以與CS231n的圖片作比較,兩者是一樣的。
總結
這一篇部落格主要是介紹了每一層的功能,以及每一層工作的原理,但是並沒有對其數學公式繼續寧推導,如果想更多的了解CNN的前向和反向傳播演算法,可以去參考這一篇部落格。
在下一篇部落格中,將介紹使用CNN對cifar-10(也可能是cifar-100)進行訓練預測。