除了 MLP 以外,卷積神經網路(Convolutional Neural Network, CNN)也是一種經常被使用的神經網路。它的概念比較像是用濾波器模擬人眼的視野,經由一層一層的處理,來萃取從局部的邊緣、角點,到整體的物體、場景等特徵。因此,convolution 本身的操作,是由一塊小的矩陣(濾波器 filter,或者稱為卷積核 kernel)對一個大的矩陣(例如影像)進行滑動,每次將對應位置的元素相乘後再相加。以下圖為例,大矩陣的尺寸是 5 * 5,kernel 的尺寸是 2 * 2,每次移動一格後,會得到 (5-2+1) * (5-2+1) = 4 * 4 的輸出。當然,你也可以不要每次只移動一格,而是一次移動兩格、三格,甚至更多,這個就是 PyTorch 或其他常見工具裡的 stride 參數;而如果希望輸出的矩陣大小與輸入相同,也可以事先在輸入矩陣的四周補零(或其他數值,如果你使用的工具允許),我們稱之為 padding。若需要知道考慮 stride 大於 1、輸入有 padding,或甚至 dilation 等情況後的輸出大小,可以參考 PyTorch 等工具的官方文件

而在 CNN 中,一個 convolution layer 會由多個 kernels 所組成,因此輸出會是多個矩陣疊在一起,疊加的維度稱為 channel。若仍以影像為例,假設輸入是一張 100 * 100 * 3 的 RGB 影像(3 個 channels),並且使用 5 個 4 * 4 * 3 的 kernels(kernel 的 channel 數必須跟輸入影樣一樣)時,輸出會是一個 97 * 97 * 5 的特徵圖;輸出的每個 channel 都是由對應的一個 kernel 跟輸入影像做完整的 convolution 運算得到的。

上面圖片當中的下方的數字,用於影像時是依次代表訓練階段一次放幾張進去(batch size)、影像高度、影像寬度,以及該影像的 channel 數量;而用於 kernel 時則是 kernel 高度、kernel 寬度、輸入影像的 channel 數量,以及輸出影像的 channel 數量。需要注意的是,各家的深度學習工具為了效能等方面的考量,預設不一定是使用前述的維度順序;在目前較常見的工具中,主要是以 TensorFlow 會使用前述的順序(稱為 NHWC 或 channels-last),而其他工具例如 PyTorch,預設的影像維度順序是 batch size、該影像的 channel 數量、影像高度,以及影像寬度(稱為 NCHW 或 channels-first);預設的 kernel 維度順序則是輸出影像的 channel 數量、輸入影像的 channel 數量、kernel 高度,以及 kernel 寬度。

為了減少運算量和增強模型對微小位移的不變性等緣故,通常還會在卷積層之間加入池化(pooling)的運算,也就是在一小塊區域裡,只保留一個代表性的數值。比較常見的方法是取平均值或最大值來作為代表,分別稱為 average pooling 和 max pooling(具體的函式名稱,在各家工具當中可能有所不同)。以 max pooling 為例,若只考慮一個 channel,影像大小 4 * 4,以及 kernel(或稱 pooling window)大小 2 * 2 時,操作方式的示意如下:

在 pooling 運算中,當 stride = window size,但輸入大小不是 window size 的整數倍時,若其他參數使用預設,則多數工具的行為是將剩下的部分捨去,例如 7 * 7 大小的輸入,遇到 3 * 3 大小的 pooling window,則輸出大小會是 floor(7 / 3) * floor(7 / 3) = 2 * 2。若需要知道考慮 stride 不等於 window size、輸入有 padding,或甚至 dilation 等情況後的輸出大小,可以參考 PyTorch 等工具的官方文件