卷積神經網路(CNN)模型結構

劉建平Pinard發表於2017-03-01

    在前面我們講述了DNN的模型與前向反向傳播演算法。而在DNN大類中,卷積神經網路(Convolutional Neural Networks,以下簡稱CNN)是最為成功的DNN特例之一。CNN廣泛的應用於影象識別,當然現在也應用於NLP等其他領域,本文我們就對CNN的模型結構做一個總結。

    在學習CNN前,推薦大家先學習DNN的知識。如果不熟悉DNN而去直接學習CNN,難度會比較的大。這是我寫的DNN的教程:

深度神經網路(DNN)模型與前向傳播演算法

深度神經網路(DNN)反向傳播演算法(BP)

深度神經網路(DNN)損失函式和啟用函式的選擇

深度神經網路(DNN)的正則化

1. CNN的基本結構

    首先我們來看看CNN的基本結構。一個常見的CNN例子如下圖:

    圖中是一個圖形識別的CNN模型。可以看出最左邊的船的影象就是我們的輸入層,計算機理解為輸入若干個矩陣,這點和DNN基本相同。

    接著是卷積層(Convolution Layer),這個是CNN特有的,我們後面專門來講。卷積層的啟用函式使用的是ReLU。我們在DNN中介紹過ReLU的啟用函式,它其實很簡單,就是$ReLU(x) = max(0,x)$。在卷積層後面是池化層(Pooling layer),這個也是CNN特有的,我們後面也會專門來講。需要注意的是,池化層沒有啟用函式。

    卷積層+池化層的組合可以在隱藏層出現很多次,上圖中出現兩次。而實際上這個次數是根據模型的需要而來的。當然我們也可以靈活使用使用卷積層+卷積層,或者卷積層+卷積層+池化層的組合,這些在構建模型的時候沒有限制。但是最常見的CNN都是若干卷積層+池化層的組合,如上圖中的CNN結構。

    在若干卷積層+池化層後面是全連線層(Fully Connected Layer, 簡稱FC),全連線層其實就是我們前面講的DNN結構,只是輸出層使用了Softmax啟用函式來做影象識別的分類,這點我們在DNN中也有講述。

    從上面CNN的模型描述可以看出,CNN相對於DNN,比較特殊的是卷積層和池化層,如果我們熟悉DNN,只要把卷積層和池化層的原理搞清楚了,那麼搞清楚CNN就容易很多了。

2. 初識卷積

    首先,我們去學習卷積層的模型原理,在學習卷積層的模型原理前,我們需要了解什麼是卷積,以及CNN中的卷積是什麼樣子的。

    大家學習數學時都有學過卷積的知識,微積分中卷積的表示式為:$$S(t) = \int x(t-a)w(a) da$$

    離散形式是:$$s(t) = \sum\limits_ax(t-a)w(a)$$

    這個式子如果用矩陣表示可以為:$$s(t)=(X*W)(t)$$

    其中星號表示卷積。

    如果是二維的卷積,則表示式為:$$s(i,j)=(X*W)(i,j) = \sum\limits_m \sum\limits_n x(i-m,j-n) w(m,n)$$

    在CNN中,雖然我們也是說卷積,但是我們的卷積公式和嚴格意義數學中的定義稍有不同,比如對於二維的卷積,定義為:$$s(i,j)=(X*W)(i,j) = \sum\limits_m \sum\limits_n x(i+m,j+n) w(m,n)$$

    這個式子雖然從數學上講不是嚴格意義上的卷積,但是大牛們都這麼叫了,那麼我們也跟著這麼叫了。後面講的CNN的卷積都是指的上面的最後一個式子。

    其中,我們叫W為我們的卷積核,而X則為我們的輸入。如果X是一個二維輸入的矩陣,而W也是一個二維的矩陣。但是如果X是多維張量,那麼W也是一個多維的張量。

3. CNN中的卷積層

    有了卷積的基本知識,我們現在來看看CNN中的卷積,假如是對影象卷積,回想我們的上一節的卷積公式,其實就是對輸入的影象的不同區域性的矩陣和卷積核矩陣各個位置的元素相乘,然後相加得到。

    舉個例子如下,圖中的輸入是一個二維的3x4的矩陣,而卷積核是一個2x2的矩陣。這裡我們假設卷積是一次移動一個畫素來卷積的,那麼首先我們對輸入的左上角2x2區域性和卷積核卷積,即各個位置的元素相乘再相加,得到的輸出矩陣S的$S_{00}$的元素,值為$aw+bx+ey+fz$。接著我們將輸入的區域性向右平移一個畫素,現在是(b,c,f,g)四個元素構成的矩陣和卷積核來卷積,這樣我們得到了輸出矩陣S的$S_{01}$的元素,同樣的方法,我們可以得到輸出矩陣S的$S_{02},S_{10},S_{11}, S_{12}$的元素。

     最終我們得到卷積輸出的矩陣為一個2x3的矩陣S。

    再舉一個動態的卷積過程的例子如下:

    我們有下面這個綠色的5x5輸入矩陣,卷積核是一個下面這個黃色的3x3的矩陣。卷積的步幅是一個畫素。則卷積的過程如下面的動圖。卷積的結果是一個3x3的矩陣。

    上面舉的例子都是二維的輸入,卷積的過程比較簡單,那麼如果輸入是多維的呢?比如在前面一組卷積層+池化層的輸出是3個矩陣,這3個矩陣作為輸入呢,那麼我們怎麼去卷積呢?又比如輸入的是對應RGB的彩色影象,即是三個分佈對應R,G和B的矩陣呢?

     在史丹佛大學的cs231n的課程上,有一個動態的例子,連結在這。建議大家對照著例子中的動圖看下面的講解。

    大家開啟這個例子可以看到,這裡面輸入是3個7x7的矩陣。實際上原輸入是3個5x5的矩陣。只是在原來的輸入周圍加上了1的padding,即將周圍都填充一圈的0,變成了3個7x7的矩陣。
    例子裡面使用了兩個卷積核,我們先關注於卷積核W0。和上面的例子相比,由於輸入是3個7x7的矩陣,或者說是7x7x3的張量,則我們對應的卷積核W0也必須最後一維是3的張量,這裡卷積核W0的單個子矩陣維度為3x3。那麼卷積核W0實際上是一個3x3x3的張量。同時和上面的例子比,這裡的步幅為2,也就是每次卷積後會移動2個畫素的位置。
    最終的卷積過程和上面的2維矩陣類似,上面是矩陣的卷積,即兩個矩陣對應位置的元素相乘後相加。這裡是張量的卷積,即兩個張量的3個子矩陣卷積後,再把卷積的結果相加後再加上偏倚b。
    7x7x3的張量和3x3x3的卷積核張量W0卷積的結果是一個3x3的矩陣。由於我們有兩個卷積核W0和W1,因此最後卷積的結果是兩個3x3的矩陣。或者說卷積的結果是一個3x3x2的張量。
    仔細回味下卷積的過程,輸入是7x7x3的張量,卷積核是兩個3x3x3的張量。卷積步幅為2,最後得到了輸出是3x3x2的張量。如果把上面的卷積過程用數學公式表達出來就是:$$s(i,j)=(X*W)(i,j) + b = \sum\limits_{k=1}^{n\_in}(X_k*W_k)(i,j) +b$$
    其中,$n\_in$為輸入矩陣的個數,或者是張量的最後一維的維數。$X_k$代表第k個輸入矩陣。$W_k$代表卷積核的第k個子卷積核矩陣。$s(i,j)$即卷積核$W$對應的輸出矩陣的對應位置元素的值。
    通過上面的例子,相信大家對CNN的卷積層的卷積過程有了一定的瞭解。
    對於卷積後的輸出,一般會通過ReLU啟用函式,將輸出的張量中的小於0的位置對應的元素值都變為0。

4. CNN中的池化層

    相比卷積層的複雜,池化層則要簡單的多,所謂的池化,個人理解就是對輸入張量的各個子矩陣進行壓縮。假如是2x2的池化,那麼就將子矩陣的每2x2個元素變成一個元素,如果是3x3的池化,那麼就將子矩陣的每3x3個元素變成一個元素,這樣輸入矩陣的維度就變小了。
    要想將輸入子矩陣的每nxn個元素變成一個元素,那麼需要一個池化標準。常見的池化標準有2個,MAX或者是Average。即取對應區域的最大值或者平均值作為池化後的元素值。
    下面這個例子採用取最大值的池化方法。同時採用的是2x2的池化。步幅為2。
    首先對紅色2x2區域進行池化,由於此2x2區域的最大值為6.那麼對應的池化輸出位置的值為6,由於步幅為2,此時移動到綠色的位置去進行池化,輸出的最大值為8.同樣的方法,可以得到黃色區域和藍色區域的輸出值。最終,我們的輸入4x4的矩陣在池化後變成了2x2的矩陣。進行了壓縮。
 

5. CNN模型結構小結

    理解了CNN模型中的卷積層和池化層,就基本理解了CNN的基本原理,後面再去理解CNN模型的前向傳播演算法和反向傳播演算法就容易了。下一篇我們就來討論CNN模型的前向傳播演算法。
 

(歡迎轉載,轉載請註明出處。歡迎溝通交流: liujianping-ok@163.com) 

參考資料:

1) Neural Networks and Deep Learning by By Michael Nielsen

2) Deep Learning, book by Ian Goodfellow, Yoshua Bengio, and Aaron Courville

3) UFLDL Tutorial

4)CS231n Convolutional Neural Networks for Visual Recognition, Stanford

相關文章