卷積神經網路(Convolutional neural network, CNN) — CNN運算流程

Tommy Huang
7 min readMar 27, 2018

--

MATLAB範例,

一般網路文章都以LeNet-5當作範例,這部份我先不用LeNet-5當例子來說,因為如果不懂CNN流程/運算就看LeNet-5,應該只會更頭痛吧(雖然LeNet-5結構不難)。

本篇文章主要是介紹CNN運作時的細節部分,所以我會我會先舉一個8*8的圖要分成兩類的範例來介紹。此CNN範例只做一次卷積(2個kernel maps)、一次池化(Pooling)、和一個全聯節層(Fully connection,hidden layer 1層,output為兩類,所以output nodes為兩個),結構如下:

此範例CNN的流程圖
此範例CNN的示意圖,第二層出現的Map 1和Map 2為Kernel Maps用來做卷積運算,激活函數我先不放到圖片去講,因為他只是在feature map部份做個非線性轉換。

卷積部份(Convolution):

卷積運算的mask一般稱為kernel map,其數量是可以調整的,在此舉兩個3x3的kernel maps。

一般在影像上,捲積運算後會再加上激活函數(activation function),進行非線性轉換,之後得到的圖片會稱為特徵圖(feature map)。

Feature map{i} = original Data * Kernel Map{i} (*為卷積運算)

池化部份(Pooling):

池化法會根據feature map的結果去做pooling,然後得到的就是降維的特徵圖。此例為2x2的Pooling。

Flatten部份:

因為做完卷積運算和池化法後得到的特徵圖還是一個2-D的圖片,到全連接層前要先轉成1-D的陣列。(如果做完卷積或是池化後結構是1x1的feature map,此步驟可以省略)

全連接層部份(Fully connection):

這邊等於一般神經網路,請參照MLP

Input node: Flatten後的結果,此例為18個nodes。

Hidden layer: 1層 5個nodes

Output node: 2個輸出結果。

解析CNN

卷積神經網路實線的重點之一就是權重共享(Shared Weight)這件事情,下左圖,透過卷積運算的方法達到Local connected neural nets。

權重共享(Shared Weight)就是假設每個輸出的結果權重都是一樣的,這樣就大幅簡少訓練模型時的參數。

在卷積部份參數量是根據我設計的kernel map數量和大小決定的,此範例為(3*3)*2=18 (此篇先不考慮bias存在)。

從全連接層可以得知一般的神經網路(MLP/DNN),在node之間是有完全連線起來的,每一條線上都有ㄧ個參數(weight)需要靠訓練得到。所以全連接層所有weight數為Input node*hidden node+hidden node*output node=18*5+5*2=100,請參考上圖"範例CNN的示意圖"。

神經網路的學習網路架構框好後

所有參數/weight都是靠資料學習推導來的,不是try出來的。

早期影像方面的算法(機器學習)都是

影像→特徵擷取(方法有SIFT、HOG等)→分類。

特徵擷取(方法有SIFT、HOG等)是try出來的。問題是特徵擷取這部份需要有非常專業的專家知識,必須知道什麼是對此分類問題重要的特徵,從影像中擷取出來後在做分類。但事實上專家的知識也是有盲點的,從大量資料(big data)中或許可以突破這個盲點,進而早到更合適的特徵。

因此深度學習就是可以克服這個問題,其結構為

影像→深度學習(特徵擷取+分類)。

卷積神經網路中的「卷積」就是特徵擷取的方法,此部份必須靠大量資料的特性不斷的反覆學習,在學習中盡可能滿足設立的條件,達到目標。所以在用深度學習時通常希望訓練樣本數可以非常大,這樣電腦在學習Kernel map時才能靠著的optimizer(通常用Stochastic Gradient Descent,SGD)利用倒傳遞(backpropagation)學習更有效得到適合的答案。

PS: 如果樣本數小就必須依靠前人的貢獻來達到相同的目的(關鍵字:遷移學習,transfer learning)。

當有兩層卷積層時,Feature Map會?

上面是介紹只有一層卷積層的情況,但當有兩層卷積層,那Feature map會變更多嗎?答案是會。

一般網路找到的例子都是
輸入是1個channel的圖,然後用一個3×3 Kernel Map做卷積
所以這篇文章一開始有寫錯,我去仔細看tensorflow的code發現我當初這邊的寫法寫錯了(2018/08/28修正)。

卷積層的個數參數是跟輸入channel有關,基本上輸入channel有幾個,每個kernel map大小就是 k × k × channel數。
所以假設輸入影像有(R, G, B)三個channel,進行一次10個5×5的Kernel Map,就會有5×5×3×10=750個參數。

本例子假設輸入一張影像(R, G, B),所以輸入為 3個channel的4×4影像

1st卷積層(Conv. 1)
設定2個3×3的kernel map,但卷積層Kernel的深度是跟輸入channel有關,所以Kernel Map的深度為3,每個kernel map實際大小為3×3×3(上一層的channel數),因此每個channel會各自對Kernel Map的不同深度各自做卷積,最後三個卷積結果再作Pixel-wise sum,所以1st卷積層(Conv. 1)輸出的影像就會有2張(4×4)。
此例: 1st卷積結果=Image(R)*kernel map(:,:,1)+ Image(G)*kernel map(:,:,2)+ Image(B)*kernel map(:,:,3)

2nd卷積層(Conv. 2)
設定3個3×3的kernel map,但卷積層Kernel的深度是跟輸入channel有關,所以Kernel Map的深度為2,每個kernel map實際大小為3×3×2(上一層的channel數),所以2nd卷積層(Conv. 2)輸出的影像就會有3張(4×4)。

* 此圖例的主要是要視覺化說明卷積在設定不同filter數量時,kernel map和輸入輸出的feature map變化,所以我是假設輸入和輸出feature map是一樣大,實質上此例的卷積運算pad=1 (因為kernel size=3),這樣卷積後輸出的feature map大小才會跟輸入一樣。 pad設定請看此篇文章

如果內容有打錯,或是字有錯誤,麻煩跟我說一下,感謝。

--

--

Tommy Huang
Tommy Huang

Written by Tommy Huang

怕老了忘記這些吃飯的知識,開始寫文章記錄機器/深度學習相關內容。Medium現在有打賞功能(每篇文章最後面都有連結),如果覺得寫的文章不錯,也可以Donate給個Tipping吧。黃志勝 Chih-Sheng Huang (Tommy), mail: chih.sheng.huang821@gmail.com