全連線神經網路(Fully connected neural network)處理影象最大的問題在於全連線層的引數太多。引數增多除了導致計算速度減慢,還很容易導致過擬合問題。所以需要一個更合理的神經網路結構來有效地減少神經網路中引數的數目。而卷積神經網路(Convolutional Neural Network,CNN)可以做到。
1. 卷積神經網路構成
圖 1:卷積神經網路
- 輸入層
整個網路的輸入,一般代表了一張圖片的畫素矩陣。圖 1中最左側三維矩陣代表一張輸入的圖片,三維矩陣的長、寬代表了影象的大小,而三維矩陣的深度代表了影象的色彩通道(channel)。黑白圖片的深度為 1,RGB 色彩模式下,圖片的深度為 3。
- 卷積層
CNN 中最為重要的部分。與全連線層不同,卷積層中每一個節點的輸入只是上一層神經網路中的一小塊,這個小塊常用的大小有 3×3 或者 5×5。一般來說,通過卷積層處理過的節點矩陣會變的更深。
- 池化層(Pooling)
池化層不改變三維矩陣的深度,但是可以縮小矩陣的大小。池化操作可以認為是將一張解析度高的圖片轉化為解析度較低的圖片。通過池化層,可以進一步縮小最後全連線層中節點的個數,從而到達減少整個神經網路引數的目的。池化層本身沒有可以訓練的引數。
- 全連線層,最後一層啟用函式使用 softmax。
經過多輪卷積層和池化層的處理後,在CNN的最後一般由1到2個全連線層來給出最後的分類結果。經過幾輪卷積和池化操作,可以認為影象中的資訊已經被抽象成了資訊含量更高的特徵。我們可以將卷積和池化看成自動影象提取的過程,在特徵提取完成後,仍然需要使用全連線層來完成分類任務。
對於多分類問題,最後一層啟用函式可以選擇 softmax,這樣我們可以得到樣本屬於各個類別的概率分佈情況。
2. 卷積層
2.1 filter
卷積神經網路結構中最重要的部分,過濾器(filter),如圖 2中黃色和橙色的 3×3×3 矩陣所示。具體卷積操作如何進行,可以參考 Convolutional Neural Networks (CNNs / ConvNets) 中的 Convolution Demo 或者參考圖 3。
圖 2:卷積操作
filter 可以將當前層神經網路上的一個子節點矩陣轉化為下一層神經網路上的一個單位節點矩陣。單位節點矩陣制的是長和寬都是 1,但深度不限的節點矩陣。
進行卷積操作,需要注意 filter 的個數 $K$、filter 的尺寸 $F$、卷積步長 stride 的大小 $S$ 以及 padding 的大小 $P$。圖 2 中 $K = 2$,$F = 3$,$S = 1$,$P = 0$。
常用的 filter 尺寸有 3×3 或 5×5,即圖 2 黃色和橙色矩陣中的前兩維,這個是人為設定的;filter 的節點矩陣深度,即圖 2 黃色和橙色矩陣中的最後一維(filter 尺寸的最後一維),是由當前層神經網路節點矩陣的深度(RGB 影象節點矩陣深度為 3)決定的;卷積層輸出矩陣的深度(也稱為 filter 的深度)是由該卷積層中 filter 的個數決定,該引數也是人為設定的,一般隨著卷積操作的進行越來越大。
圖 2中 filter 的尺寸為 3×3×3,filter 的深度為 2。
卷積操作中,一個 3×3×3 的子節點矩陣和一個 3×3×3 的 filter 對應元素相乘,得到的是一個 3×3×3 的矩陣,此時將該矩陣所有元素求和,得到一個 1×1×1 的矩陣,將其再加上 filter 的 bias,經過啟用函式得到最後的結果,將最後的結果填入到對應的輸出矩陣中。輸出矩陣中第一個元素 $g(0, 0, 0)$ 的計算如下所示:
\begin{equation} g(0, 0, 0) = f( \sum_{x = 0}^2\sum_{y=0}^2\sum_{z=0}^2a_{x,y,z} × w_{x,y,z}^{(0)} + b^{(0)} ) \end{equation}
公式(1)中,$a_{x,y,z}$ 表示當前層的一個子節點矩陣,即 6×6×3 矩陣中左上角 3×3×3 部分; $w_{x,y,z}^{(0)}$ 表示第一個 filter 的權重,即第一個 filter 每個位置的值;$b^{(0)}$ 表示第一個 filter 的偏置 bias,是一個實數;$f$ 表示啟用函式,如 ReLU 啟用函式。
“卷積層結構的前向傳播過程就是通過將一個 filter 從神經網路當前層的左上角移動到右下角,並且在移動中計算每一個對應的單位矩陣得到的。”
圖 3:卷積操作流程
(注意:圖 2 和 圖 3 神經網路當前層輸入不一樣,圖 2 是 6×6×3,而圖 3 是5×5×3 再加上 $P = 1$ 的 padding。)
圖 3 中,卷積步長 $S = 2$,padding的大小 $P = 1$。
2.2 padding
padding,顧名思義,就是在影象周圍進行填充,常用 zero padding,即用 0 來填充。當 $P = 1$ 時,在影象周圍填充一圈;當 $P = 2$ 時,填充兩圈。
Q: Why padding?
A: Two reasons: 1) shrinking output: 隨著卷積操作的進行,影象會越來越小; 2) throwing away information from the edges of the images: filter 對圖片邊緣資訊和內部資訊的重視程度不一樣,有些邊緣資訊 filter 只經過一次,而內部資訊會被經過多次,換句話說,如果不進行 padding,那麼下一層中受邊緣資訊影響的畫素會少於受內部資訊影響的畫素。
Q: Valid and Same convolutions?
A: "valid": no padding;
"Same": Pad so that output size is the same as the input size.
2.3 stride
卷積步長 stride 就是像在圖 3 中 filter 一次移動的步子,圖 3 中 stride 的大小 $S = 2$。
卷積步長只對輸入矩陣的長和寬這兩個維度有效。
卷積層輸出矩陣的大小 $\mbox{size}_{output}$ 與輸入圖片大小 $N$、 filter 的尺寸 $F$、padding 的大小 $P$、卷積步長 $S$ 都有關。(假設輸入的圖片是方形的)
\begin{equation} \mbox{size}_{output}= \lfloor \frac{N + 2P - F}{S} \rfloor + 1\end{equation}
當 $ S \neq 1$ 時,可能存在 $\frac{N + 2P - F}{S}$ 不是整數的情況,這個時候對 $\frac{N + 2P - F}{S}$ 取下整或者使用整除。
依據《TensorFlow實戰Google深度學習框架》,$\mbox{size}_{output}$ 也可以寫成如下形勢:
\begin{equation} \mbox{size}_{output}= \lceil \frac{N + 2P - F + 1 }{S} \rceil \end{equation}
公式(2)和(3)最後的結果會是一樣。
3. 池化層
池化層可以非常有效地縮小矩陣的尺寸(主要減少矩陣的長和寬,一般不會去減少矩陣深度),從而減少最後全連線層中的引數。“使用池化層既可以加快計算速度也有防止過擬合問題的作用。”
與卷積層類似,池化層的前向傳播過程也是通過一個類似 filter 的結構完成的。不過池化層 filter 中的計算不是節點的加權和,而是採用更加簡單的最大值或者平均值運算。使用最大值操作的池化層被稱為最大池化層(max pooling),這是使用最多的池化層結構。使用平均值操作的池化層被稱為平均池化層(average pooling)。
與卷積層的 filter 類似,池化層的 filter 也需要人工設定 filter 的尺寸、是否使用全 0 填充 以及 filter 移動的步長等設定,而且這些設定的意義也是一樣的。
卷積層和池化層中 filter 的移動方式是相似的,唯一的區別在於卷積層使用的 filter 是橫跨整個深度的,而池化層使用的 filter 隻影響一個深度上的節點。所以池化層的過濾器除了在長和寬兩個維度移動之外,它還需要在深度這個維度移動。也就是說,在進行 max 或者 average 操作時,只會在同一個矩陣深度上進行,而不會跨矩陣深度進行。
圖 4:max pooling
圖 4 中,池化層 filter 的尺寸為 2×2,即 $F = 2$,padding 大小 $P = 0$,filter 移動的步長 $S = 2$。
池化層一般不改變矩陣的深度,只改變矩陣的長和寬。
池化層沒有 trainable 引數,只有一些需要人工設定的超引數。
4. 卷積神經網路的特點
- 區域性連線(稀疏連線,sparsity of connections):卷積層輸出矩陣上的某個位置只與部分輸入矩陣有關,而不是全部的輸入矩陣。卷積層輸出的某個特徵可能只和輸入圖片的某一部分相關,和其它位置的資訊沒有任何關聯,區域性連線可以讓特徵只關注其應該關注的部分。同時也減少了神經網路的引數。
- 引數共享(parameter sharing):同一卷積層中 filter 的引數是共享的,一個 filter 無論在哪個位置進行卷積操作,filter 矩陣中的值都是一樣的。(當然同一層不同的 filter 引數不一樣,不同層之間 filter 的引數也不一樣。)共享 filter 的引數可以使得影象中的內容不受位置的影響。以MNIST手寫數字識別為例,無論數字“1”出現在左上角還是右下角,圖片的種類的都是不變的。共享卷積層 filter 的引數還可以巨幅減少神經網路上的引數。
圖 2 中卷積層擁有的 trainable 引數數目為 3×3×3×2+2,其中 “3×3×3” 表示 filter 的尺寸, “×2” 表示 filter 的深度/個數,“+2” 表示 2 個 filter 的 bias。卷積層的引數要遠遠小於同等情況下的全連線層。而且卷積層引數的個數和輸入圖片的大小無關,這使得卷積神經網路可以很好地擴充套件到更大的影象資料上。
卷積層 trainable 引數的個數只和 filter 的尺寸(包括長、寬和單個 filter 矩陣的深度)、filter 的深度(個數)相關。單個 filter 矩陣的深度也就是輸入圖片的 channel 數(或者說,輸入圖片矩陣的深度)。
池化層沒有 trainable 引數。
註釋:本文中的“trainable 引數”指的是在深度學習模型中可以通過梯度下降更新的引數,比如每個 filter 矩陣中的值、filter 的 bias;而超引數是模型在執行之前人為設定好的引數,比如 filter 尺寸中的長和寬、filter 的深度、filter 移動的步長、padding 的大小。
References
Convolutional Neural Networks (CNNs / ConvNets)
Course 4 Convolutional Neural Networks by Andrew Ng
《TensorFlow實戰Google深度學習框架》