1. 程式人生 > >【Deep learning】卷積神經網路CNN演算法原理

【Deep learning】卷積神經網路CNN演算法原理

寫在前面

在上一篇【Deep learning】卷積神經網路CNN結構中我們簡單地介紹了CNN的結構。接下來我們看看這種結構的CNN模型是怎麼執行的,包括CNN的前向傳播和反向傳播演算法。

1.CNN前向傳播演算法

(1)輸入層前向傳播到卷積層

輸入層的前向傳播是CNN前向傳播演算法的第一步。一般輸入層對應的都是卷積層,因此我們標題是輸入層前向傳播到卷積層。

我們這裡還是以影象識別為例。先考慮最簡單的,樣本都是二維的黑白圖片。這樣輸入層X就是一個矩陣,矩陣的值等於圖片的各個畫素位置的值。這時和卷積層相連的卷積核W就也是矩陣。如果樣本都是有RGB的彩色圖片,這樣輸入X就是3個矩陣,即分別對應R,G和B的矩陣,或者說是一個張量。這時和卷積層相連的卷積核W就也是張量,對應的最後一維的維度為3.即每個卷積核都是3個子矩陣組成。同樣的方法,對於3D的彩色圖片之類的樣本,我們的輸入X可以是4維,5維的張量,那麼對應的卷積核W也是個高維的張量。不管維度多高,對於我們的輸入,前向傳播的過程可以表示為:


其中,上標代表層數,星號代表卷積,而b代表我們的偏倚, σ為啟用函式,這裡一般都是ReLU。

和DNN的前向傳播比較一下,其實形式非常的像,只是我們這兒是張量的卷積,而不是矩陣的乘法。同時由於W是張量,那麼同樣的位置,W引數的個數就比DNN多很多了。為了簡化我們的描述,本文後面如果沒有特殊說明,我們都預設輸入是3維的張量,即用RBG可以表示的彩色圖片。

這裡需要我們自己定義的CNN模型引數是:

    1) 一般我們的卷積核不止一個,比如有K個,那麼我們輸入層的輸出,或者說第二層卷積層的對應的輸入就K個。
    2) 卷積核中每個子矩陣的的大小,一般我們都用子矩陣為方陣的卷積核,比如FxF的子矩陣。
    3) 填充padding(以下簡稱P)
,我們卷積的時候,為了可以更好的識別邊緣,一般都會在輸入矩陣在周圍加上若干圈的0再進行卷積,加多少圈則P為多少。

    4) 步幅stride(以下簡稱S),即在卷積過程中每次移動的畫素距離大小。

(2)隱藏層前向傳播到卷積層

現在我們再來看普通隱藏層前向傳播到卷積層時的前向傳播演算法。

假設隱藏層的輸出是M個矩陣對應的三維張量,則輸出到卷積層的卷積核也是M個子矩陣對應的三維張量。這時表示式和輸入層的很像,也是:


和上一節唯一的區別僅僅在於,這裡的輸入是隱藏層來的,而不是我們輸入的原始圖片樣本形成的矩陣。

需要我們定義的CNN模型引數也和上一節一樣,這裡我們需要定義卷積核的個數K,卷積核子矩陣的維度F,填充大小P以及步幅S。

(3)隱藏層前向傳播到池化層

池化層的處理邏輯是比較簡單的,我們的目的就是對輸入的矩陣進行縮小概括。比如輸入的若干矩陣是NxN維的,而我們的池化大小是kxk的區域,則輸出的矩陣都是N/k × N/k維的。

這裡需要需要我們定義的CNN模型引數是:

    1)池化區域的大小k
    2)池化的標準,一般是MAX或者Average。

(4)隱藏層前向傳播到卷積層

由於全連線層就是普通的DNN模型結構,因此我們可以直接使用DNN的前向傳播演算法邏輯,即:

這裡的啟用函式一般是sigmoid或者tanh。經過了若干全連線層之後,最後的一層為Softmax輸出層。此時輸出層和普通的全連線層唯一的區別是,啟用函式是softmax函式。這裡需要需要我們定義的CNN模型引數是:    1)全連線層的啟用函式
    2)全連線層各層神經元的個數

CNN前向傳播演算法小結:


2. CNN反向傳播演算法

對於CNN反向傳播,首先要理解DNN反向傳播演算法。舉個栗子:


現在外面把同樣的思想用到CNN中,很明顯,CNN有些不同的地方,不能直接去套用DNN的反向傳播演算法的公式。

要套用DNN的反向傳播演算法到CNN,有幾個問題需要解決:
    1)池化層沒有啟用函式,這個問題倒比較好解決,我們可以令池化層的啟用函式為σ(z)=z,即啟用後就是自己本身。這樣池化層啟用函式的導數為1.
    2)池化層在前向傳播的時候,對輸入進行了壓縮,那麼我們現在需要向前反向推導δl−1,這個推導方法和DNN完全不同。
    3) 卷積層是通過張量卷積,或者說若干個矩陣卷積求和而得的當前層的輸出,這和DNN很不相同,DNN的全連線層是直接進行矩陣乘法得到當前層的輸出。這樣在卷積層反向傳播的時候,上一層的δl−1遞推計算方法肯定有所不同。
    4)對於卷積層,由於W使用的運算是卷積,那麼從δl推匯出該層的所有卷積核的W,b的方式也不同。

從上面可以看出,問題1比較好解決,但是問題2,3,4就需要好好的動一番腦筋了,而問題2,3,4也是解決CNN反向傳播演算法的關鍵所在。另外大家要注意到的是,DNN中的al,zl都只是一個向量,而我們CNN中的al,zl都是一個張量,這個張量是三維的,即由若干個輸入的子矩陣組成。

下面我們就針對問題2,3,4來一步步研究CNN的反向傳播演算法。

在研究過程中,需要注意的是,由於卷積層可以有多個卷積核,各個卷積核的處理方法是完全相同且獨立的,為了簡化演算法公式的複雜度,我們下面提到卷積核都是卷積層中若干卷積核中的一個。

(1)已知池化層的δl,推導上一隱藏層的δl−1

我們首先解決上面的問題2,如果已知池化層的δl,推匯出上一隱藏層的δl−1。

在前向傳播演算法時,池化層一般我們會用MAX或者Average對輸入進行池化,池化的區域大小已知。現在我們反過來,要從縮小後的誤差δl,還原前一次較大區域對應的誤差。

在反向傳播時,我們首先會把δl的所有子矩陣矩陣大小還原成池化之前的大小,然後如果是MAX,則把δl的所有子矩陣的各個池化局域的值放在之前做前向傳播演算法得到最大值的位置。如果是Average,則把δl的所有子矩陣的各個池化局域的值取平均後放在還原後的子矩陣位置。這個過程一般叫做upsample。

用一個例子可以很方便的表示:假設我們的池化區域大小是2x2。δl的第k個子矩陣為:


由於池化區域為2x2,我們先將δlk做還原,即變成:


如果是MAX,假設我們之前在前向傳播時記錄的最大值位置分別是左上,右下,右上,左下,則轉換後的矩陣為:


如果是Average,則進行平均:轉換後的矩陣為:



(2)已知卷積層的δl,推導上一隱藏層的δl−1

對於卷積層的反向傳播,我們首先回憶下卷積層的前向傳播公式:


在DNN中,我們知道δl−1和δl的遞推關係為:


因此要推匯出δl−1和δl的遞推關係,必須計算∂zl/∂zl−1的梯度表示式。


這裡的式子其實和DNN的類似,區別在於對於含有卷積的式子求導時,卷積核被旋轉了180度。即式子中的rot180(),翻轉180度的意思是上下翻轉一次,接著左右翻轉一次。在DNN中這裡只是矩陣的轉置。那麼為什麼呢?由於這裡都是張量,直接推演引數太多了。我們以一個簡單的例子說明為啥這裡求導後卷積核要翻轉。

假設我們l−1層的輸出al−1是一個3x3矩陣,第l層的卷積核Wl是一個2x2矩陣,採用1畫素的步幅,則輸出zl是一個2x2的矩陣。我們簡化bl都是0,則有

太難了.....

看不下去了.....

先佔個坑....

下次回來看....