數據挖掘入門系列教程(十一點五)之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,肯定是拿該照片與已有的標準XO照片進行對比,哪一個相似度高,則就認為新的照片是屬於哪一個類別。對比對於人類來說很簡單,但是,對於電腦來說,應該怎麼對比呢?

電腦可以進行遍歷圖片的每一個像素點的像素值,然後與標準圖片的像素值進行比較,但是毋庸置疑,這樣肯定是不行的,比如說在下圖中電腦就認為只有中間的是一樣的,其它四個角都不同,因此可能會得出這張圖片不是X這個結論。

但是我們肯定是希望不管在平移,旋轉,還是變形的情況下,CNN模型都可以識別出來。

so,我們將比較範圍由像素點擴大到某一個範圍,在CNN模型中,會比較兩張圖片的的各個局部,這些局部稱之為特徵(features)。

每一個feature都是一張小圖,也就是更小的二維矩陣。這些特徵會捕捉圖片中的共同要素。以X圖片為例,它最重要的特徵就是對角線和中間的交叉。也就是說,任何叉叉的線條或中心點應該都會符合這些特徵。

那麼如何判斷一張圖片中是否有相符合的特徵,然後符合的特徵有多少個,這裡我們使用數學的方法卷積(convolution)進行操作,這個也就是CNN名字的由來。

卷積層(Convolution Layer)

下面我還是將以識別X作為例子來講解一下如何進行進行卷積。卷積的目的是為了計算特徵與圖片局部的相符程度。

計算的步驟如下:

\[\frac{(1 \times 1) + (-1\times -1) + (-1\times -1) + (-1\times -1) + (1\times 1) + (-1\times -1)+ (-1\times -1) + (-1\times -1) + (1\times 1)}{9} = 1s
\]

如果我們將這個\(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\),則:

\[W_{2}=\left(W_{1}-F+2 P\right) / S+1\\
H_{2}=\left(H_{1}-F+2 P\right) / S+1 \\
D_{2}=K
\]

Relu激勵層

整流線性單位函數(Rectified Linear Unit, ReLU),又稱修正線性單元, 是一種人工神經網路中常用的激勵函數(activation function),通常指代以斜坡函數及其變種為代表的非線性函數。數學表達式為:

\[\begin{equation}f(x)=\max (0, x)\end{equation}
\]

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\),則:

\[\begin{equation}\begin{aligned}
&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)進行訓練預測。

參考