本文作為自己學習李宏毅老師2021春機器學習課程所做筆記,記錄自己身為入門階段小白的學習理解,如果錯漏、建議,還請各位博友不吝指教,感謝!!
CNN理解角度一
圖像的表達形式
對於一個Machine來說,一張輸入的圖像其實是一個三維的Tensor。
如上圖所示,三個維度分別表示圖像的寬、高和Channel的數目。彩色圖像的每一個pixel都是由RGB 三個顏色所組成的,所以3個Channel就分別代表了RGB三個顏色,寬和高表示了這張圖像中像素的數目(即:100×100)
之前提到的網絡(例:Fully Connected Network)的輸入都是一個向量,那如何將一張有三個維度的圖像數據輸入到網絡中呢?一個直接的方法就是將這個三維的Tensor拉直成一個向量,如下圖所示:
圖中拉直后的向量的長度為100×100×3,其中每一維里存的數值表示某一個pixel在某個顏色上的強度。如果我們使用Fully Connected Network來實現我們的目標,假設這個Network的第一個隱藏層中有1000個Neuron。我們將上圖中的向量輸入到這個網絡,那么第一層中就有\(3 \times 10^7\)個參數,如下圖所示:
隨着網絡層數增多,參數也增多,網絡的彈性增強,也就更容易出現過擬合(Overfitting)問題,而且訓練的效率也會變低。所以,如何減少網絡的參數是我們使用圖像數據訓練模型要解決的一個問題。除了上述參數太多的問題,在使用Fully Collected Network處理圖像信息時,也會有無法提取圖像的局部不變性特征的問題。
局部不變性特征:自然圖像中的物體都具有局部不變性特征,比如尺度縮放、平移、旋轉等操作不影響其語義信息。而全連接前饋網絡很難提取這些局部不變形特征,一般需要進行數據增強來提高性能。
所以Fully Collected Network並不適合直接拿來處理圖像信息,需要做進一步的簡化。我們可以先考慮用於影像辨識的類神經網絡是如何對一張圖片中的動物進行分類的。
假設如上圖所示,用於圖像分類的類神經網絡是通過綜合檢測到的一些重要的patterns,來進行分類的,例如:
- 某個神經元看到了鳥嘴的pattern。
- 某個神經元看到了鳥的眼睛的pattern。
- 某個神經元看到了鳥爪的pattern。
類神經網絡綜合檢測到的這些patterns,最后得出結論,圖像中的生物是一只鳥。這樣的話,就沒必要將一整張圖像作為類神經網絡中每個神經元的輸入。只需要將圖像中的一小部分輸入到神經元中,就可以檢測到某些重要的patterns。
感受野(Receptive Field)
對於上邊提到的以檢測patterns的方式來處理圖像信息的方法,在CNN中設置有感受野(Receptive Field),並由一組神經元來處理這個感受野提取的圖像信息。一般來說,感受野是要考慮所有Channels上的信息的。這樣在描述感受野時,只要說明它的寬×高(即Kernel Size)就可以了。
在影像辨識中Kernel Size一般設為3×3,比較大的Kernel Size一般為7×7或者9×9。
如上圖所示,以一個藍色的神經元負責處理左上角感受野中的圖像信息為例。而這個神經元要完成的工作就是:
- 將感受野中\(3 \times 3 \times 3\)的數值拉直,變成一個27維的向量,作為藍色神經元的輸入。
- 這個神經元會給向量中每一個Dimension一個Weight,所以有27個參數。
- 再加上Bias得到輸出,作為下一層神經元的輸入。
將上圖中的Receptive Field向右移動一格,就獲得了另一個Receptive Field,這個移動的量稱為Stride。Stride是一個由我們自己設置的超參數(Hyper parameter),一般設為1或2。這樣我們就可以從左到右,從上到下移動來獲取不同的Receptive Field,如下圖所示:
當Receptive Field從左向右移動超出圖像Tensor的邊界時,我們可以用0進行填充(padding)。當然,也可以使用整張圖像中所有值的平均值或者邊界上的數值來做padding。
權值共享
雖然,感受野對用於圖像處理的網絡做了初步的簡化,仍會有讓網絡的參數變得非常多的情況。
如上圖所示,當表示鳥嘴的pattern出現在圖像的不同區域時,按照上邊的設置感受野的方法,我們可以在每個位置都放一個檢測鳥嘴pattern的感受野來進行處理。這些不同位置上檢測鳥嘴pattern的感受野,都做着同樣的工作,這不僅造成了冗余,而且隨着要處理的patterns的數量增多,網絡的參數量也會變得非常的大。
對於這個問題,我們可以通過讓負責不同感受野(Receptive Field)的神經元共享權值來解決。
如上圖所示,在兩個神經元與輸入數據的連接中,兩個顏色相同的連接所代表的參數weight是一樣的。這樣,兩個神經元雖然負責處理不同位置上的感受野,但是參數是一樣的,即都處理同樣的pattern。
在上邊提到過,一個感受野提取的信息,其實是由一組神經元來進行處理的。那這些神經元是怎么共享權值的呢?
兩組神經元之間的共享權值可以如上圖所示理解,即顏色相同的兩個神經元的參數是一樣的,而這些參數被稱作Filter。這里個人理解,每種顏色的神經元負責處理一種pattern,即一個Filter負責提取一個特征。
以上就是李宏毅老師從根據圖像的特性,對網絡進行簡化的角度來解釋的CNN。
CNN理解角度二
以下是李宏毅老師從Filter的角度來理解CNN網絡。
如上圖所示,在Convolution Layer中含有一排Filter,每一個Filter是一個3×3×channel的Tensor(Tensor中存儲着Filter所對應的參數值,也就是Model中的Parameter,具體的Parameter的值是需要通過gradient decent來得到的),其作用就是要提取圖像中的某一個pattern。以一張黑白色的圖像(即圖像的信息中Tensor的Channel=1),並假設Filter中存儲的參數都已知。表示Filter提取圖像中pattern的過程:
我們將第一個Filter中的參數,與左上角中的數值做內積運算得出一個值,注意這里的內積計算方式如下所示:
設Filter的移動距離(Stride)為1,使其從左到右,從上到下移動,計算出經過所有位置的值來,如下圖所示:
那Filter提取它所對應pattern是怎么體現出來的呢?
如上圖所示,Filter 1檢測的是對角線為1的這種pattern。當它遇到這種對角線為1的pattern時,計算出的值在Tensor中是最大的,所以可以看到兩個藍色框框出來的最大值3。假設Convolutional Layer中有64個Filter,當所有的Filter都完成內積計算后,最終會得到一個channel=64的Tensor,稱為Feature Map,也可以理解為另一張新的圖像,這個Feature Map將輸入到后續的網絡中進一步處理:
Pooling
匯聚層(Pooling Layer)也叫子采樣層(Subsampling Layer),其作用是進行特征選擇,降低特征數量,從而減少參數數量。
卷積層雖然可以顯著的減少網絡中連接的數量,但特征映射組中的神經元個數並沒有顯著減少。如果后面接一個分類器,分類器的輸入維度依然很高,很容易過擬合。可以在卷積層之后加上一個匯聚層,從而降低特征維數,避免過擬合。
具體的做法:假設匯聚層的輸入特征映射組為\(\mathcal{X} \in \mathbb{R}^{M \times N \times D}\),對於其中每一個特征映射\(X^d \in \mathbb{R}^{M \times N}, 1 \le d \le D\),將其划分為很多區域\(R_{m,n}^d\),\(1 \le m \le M'\),\(1 \le n \le N'\),這些區域可以重疊,也可以不重疊。匯聚(Pooling)是指對每個區域進行下采樣(Down Sampling)得到一個值,作為這個區域的概括。
常見的匯聚函數有兩種:
- 最大匯聚(Maximum Pooling或Max Pooling):對於一個區域\(R^d_{m,n}\),選擇這個區域內所有神經元的最大活性值作為這個區域的表示,即
其中\(x_i\)為區域\(R_k^d\)內每個神經元的活性值。
- 平均匯聚(Mean Pooling):一般是取區域內所有神經元活性值的平均值,即
以Max Pooling為例:
如上圖所示,我們首先將4×4的Tensor划分為4個2×2的小區域,每個區域中取最大值作為代表,組成最終的2×2的匯聚結果,如下圖所示:
Pooling操作,本身是沒有參數的,所以它不是一個Layer,里邊也沒有要學習的weight。通常來說Convolution和Pooling是交替使用的,也就是做幾次Convolution后,接着做一次Pooling。因為Pooling可以把圖像減小,所以它可以起到減少網絡參數量的作用。另外,因為Pooling是會損失一些信息,所以我們在處理細微圖像信息的網絡中使用Pooling,是會對網絡的性能造成影響的。
參考資料:
《神經網絡與深度學習》 邱錫鵬
https://github.com/unclestrong/DeepLearning_LHY21_Notes
