本文只討論CNN中的卷積層的結構與計算,不討論步長、零填充等概念,代碼使用keras。
一些名詞:
卷積核,別名“過濾器”、“特征提取器”。
特征映射,別名“特征圖”。
至於神經元和卷積核在CNN中的區別,可以看參考7(結合參考6)中Lukas Zbinden 寫的答案:···“The neuron here represents the dot product of that filter with the input region (omitting bias and activation function here for simplicity)”······“Behind each entry (1x1x1) in the 3D output volume there is a neuron whose weights (i.e. the filter) were multiplied with a part of the input defined by the receptive field of that neuron to produce that entry.” ·····“the neuron in a CNN is only applied to a local spatial region of the input (i.e. its receptive field), not to the entire input as in an MLP. Further, the weights of that neuron are not unique, they are shared between all neurons producing one 2D activation map (i.e. N such maps are equivalent to the aforementioned 3D output volume where N is the number of output channels, i.e. a hyperparameter). Consider the filter that slides over the entire input to produce one such 2D activation map, that is the filter shared among all neurons that participate in producing all the entries making up that 2D activation map.”
准確地說,一個卷積層由一組卷積核組成。
基礎卷積操作(參考4):
這里的矩陣B就是卷積核,特別地,矩陣B也稱作Sobel算子,用於提取垂直特征。
實際上,這里的卷積與圖像處理、信號處理中的卷積並不一樣,CNN中的卷積是簡化了的卷積,又稱“互相關”操作。以下引用自參考3:
“在機器學習和圖像處理領域,卷積的主要功能是在一個圖像(或某種特征) 上滑動一個卷積核(即濾波器),通過卷積操作得到一組新的特征.在計算卷積 的過程中,需要進行卷積核翻轉.在具體實現上,一般會以互相關操作來代替卷 積,從而會減少一些不必要的操作或開銷.”
而在CNN的卷積層中,我們會在以上的計算(有時也可以再加上一個標量偏置b)之后,使用一個激活函數,以使得CNN具有學習非線性映射的能力。
接下來看一下CNN中卷積層的結構:
用一個卷積核在一個二維圖像上進行卷積操作后得到一個二維的特征映射。
(參考1第230、231頁)
(參考2第320頁)
通過前兩張圖可以看出,對於一幅單通道二維圖像(M*N)應用某個卷積核(a*a),將得到一個二維的特征映射(M' * N')。而對一幅單通道二維圖像(M*N)應用一組卷積核(a*a*D)(一個卷積層)(含有D個不同的卷積核),則得到一組二維特征映射(M' * N' * D)。(假定卷積核是正方形的)
那么如果圖像是如上所示的三通道RGB二維圖像,經過某個卷積核的卷積操作后,得到的特征映射是什么樣的呢?
這里根據:
(參考3第113頁)(這里作者將激活函數包含於卷積層中)此處輸入特征映射xd應該對應於三通道RGB圖像中的每個通道,而三維卷積核Wp的概念應該對應於參考5中的說神經元:
“Example 1. For example, suppose that the input volume has size [32x32x3], (e.g. an RGB CIFAR-10 image). If the receptive field (or the filter size) is 5x5, then each neuron in the Conv Layer will have weights to a [5x5x3] region in the input volume, for a total of 5*5*3 = 75 weights”(斯坦福則講ReLu層分開敘述,實際上是一樣的)
參考2第321頁
我們可以知道,使用卷積層中的某個卷積核,將其分別作用於圖像的三個通道上進行卷積,得到3個子特征映射,再在圖像通道維度(3)上相加求和,得到總的特征映射(M' * N' * 3)(可再加上一個標量偏置b)。然后經過一個激活函數,得到最終的特征映射。
(參考5:“The connections are local in space (along width and height), but always full along the entire depth of the input volume.”)
類似地,可以知道,對於處於網絡中間的那些卷積層(輸入是上一個卷積層的輸出特征映射組(M'*N'*d)),他們的卷積操作也是一樣的。
下面根據keras代碼看一下實際應該怎么寫:(參考6)
model = Sequential() model.add(Conv2D(32, kernel_size=(5, 5), strides=(1, 1), activation='relu', input_shape=input_shape)) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) model.add(Conv2D(64, (5, 5), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) model.add(Dense(1000, activation='relu')) model.add(Dense(num_classes, activation='softmax'))
對應的網絡結構為:
現在便很容易理解Conv2D中的參數了:
model.add(Conv2D(32, kernel_size=(5, 5), strides=(1, 1), activation='relu', input_shape=input_shape))
32即在這個卷積層中使用32個卷積核(過濾器),卷積核尺寸為5*5,橫向縱向步長均為1,激活函數為relu。其最終輸出的特征映射組的深度也必然是32.
本文為個人學習筆記,如有謬誤,敬請指出,謝謝。
參考:
1、The Deep Learning with Keras Workshop: An Interactive Approach to Understanding Deep Learning with Keras, 2nd Edition
2、機器學習實戰——基於Scikit-learn和Tensorflow
3、《神經網絡與深度學習》邱錫鵬
4、The Deep Learning Workshop: Learn the skills you need to develop your own next-generation deep learning models with TensorFlow and Keras
5、https://cs231n.github.io/convolutional-networks/
6、https://adventuresinmachinelearning.com/keras-tutorial-cnn-11-lines/
7、https://www.quora.com/What-is-a-neuron-in-the-context-of-Convolutional-Neural-Network