卷積神經網絡,在圖像識別和天然語言處理中有很大的做用,講cnn的中文博客也很多,可是我的感受說的脈絡清晰清晰易懂的很少.python
無心中看到這篇博客,寫的很好,圖文並茂.建議英文好的直接去看原文.英文很差的就直接看我這篇,算是讀後總結吧.原文裏對數學原理的着墨很少,在這篇文章裏我會留着相關的標題,待往後慢慢補充這篇文章.git
以上是一個cnn的典型結構.包含如下3種結構github
這是數字8的圖片,圖片其實就是一堆像素點的組合,能夠理解爲一個M*N的矩陣,矩陣中每個元素的值就是像素值,取值從0-255.彩色的圖有RGB三個通道,能夠理解爲3個M*N矩陣.爲了簡化討論,咱們以灰度圖爲例,灰度圖是單通道的.算法
假設咱們有一個5*5的圖片網絡
咱們有一個3*3的矩陣,在CNN中,咱們稱之爲‘filter‘ or ‘kernel’ or ‘feature detector’。app
,ide
咱們用這個kenel對輸入的圖像作卷積,過程以下所示:函數
其中,卷積的過程,用filter與input的相應位置相乘再相加.獲得新的矩陣的對應元素的值.ui
而後滑動這個filter矩陣,滑動x個像素,x稱之爲步長stride(在這個例子中步長=1),算出下一個矩陣對應元素的值.不斷重複這個過程. 完整過程以下所示:this
卷積後獲得的這個3*3的矩陣稱之爲‘Activation Map’ or the ‘Feature Map‘.
卷積層完成了特徵提取.
不一樣的filter有不一樣的效果.好比上圖展現了邊緣檢測,銳化,模糊等等.
下圖很好的展現了cnn卷積操做作了什麼:
不一樣的filter提取出了圖片的不一樣角度的特徵,獲得了不一樣的特徵圖.注意將上述的圖片都理解爲一個一個的矩陣.
It is important to note that the Convolution operation captures the local dependencies in the original image.
depth與filter數量是一致的.不一樣的獨立的filter提取出不一樣的特徵. 好比以下,有3個filter對原始圖片進行處理,獲得的特徵圖能夠理解爲3個疊在一塊兒的矩陣.
步長是filter矩陣在輸入矩陣上每次滑動的距離.步長越大,最終獲得的特徵圖越小.
補零操做,在原始矩陣周圍補0. 添加補0的卷積叫wide convolution, 不添加補0的卷積叫 narrow convolution.
以原始圖像爲32*32,filter爲5*5爲例,不作補0的話,獲得的特徵圖矩陣大小爲28*28.在神經網絡的前幾層,咱們但願保留儘量多的信息,好提取更多的特徵.即咱們但願依然獲得一個32*32的矩陣.
https://adeshpande3.github.io/A-Beginner%27s-Guide-To-Understanding-Convolutional-Neural-Networks-Part-2/
Now, let’s take a look at padding. Before getting into that, let’s think about a scenario. What happens when you apply three 5 x 5 x 3 filters to a 32 x 32 x 3 input volume? The output volume would be 28 x 28 x 3. Notice that the spatial dimensions decrease. As we keep applying conv layers, the size of the volume will decrease faster than we would like. In the early layers of our network, we want to preserve as much information about the original input volume so that we can extract those low level features. Let’s say we want to apply the same conv layer but we want the output volume to remain 32 x 32 x 3. To do this, we can apply a zero padding of size 2 to that layer. Zero padding pads the input volume with zeros around the border. If we think about a zero padding of two, then this would result in a 36 x 36 x 3 input volume.
卷積爲何能夠提取特徵,背後的數學原理,往後補充
ReLU做用於卷積後獲得的特徵圖. 將矩陣中的負數替換爲0.
ReLU爲卷積神經網絡引入非線性.真實世界裏的數據絕大多數是非線性的(卷積是一種線性操做)
The purpose of ReLU is to introduce non-linearity in our ConvNet, since most of the real-world data we would want our ConvNet to learn would be non-linear (Convolution is a linear operation – element wise matrix multiplication and addition, so we account for non-linearity by introducing a non-linear function like ReLU)
對特徵圖中的每個像素作ReLU操做後的效果如上圖所示.
其餘的非線性函數還有tanh,sigmoid。可是實際使用中,大多狀況下ReLU效果更好.
上面通過多個filter卷積,以及ReLU處理以後,咱們獲得了多個特徵圖.
此時咱們想減少特徵矩陣的維度,可是又保留下最重要的特徵.和上面介紹的卷積過程相似,咱們定義一個空間池.池化操做有Max, Average, Sum etc.
Spatial Pooling (also called subsampling or downsampling) reduces the dimensionality of each feature map but retains the most important information. Spatial Pooling can be of different types: Max, Average, Sum etc.
下圖展現了用一個2*2的filter作最大池化後的效果:
下圖展現了實際的特徵圖作不一樣的池化操做的效果:
池化有如下4個做用
- makes the input representations (feature dimension) smaller and more manageable
- reduces the number of parameters and computations in the network, therefore, controlling overfitting [4]
- makes the network invariant to small transformations, distortions and translations in the input image (a small distortion in input will not change the output of Pooling – since we take the maximum / average value in a local neighborhood).
- helps us arrive at an almost scale invariant representation of our image (the exact term is 「equivariant」). This is very powerful since we can detect objects in an image no matter where they are located (read [18] and [19] for details).
全鏈接層是一個在輸出層使用了softmax激活函數的多層感知機.
卷積層和池化層的輸出的特徵圖矩陣,表明了輸入圖像的高層次特徵(high-level features).全鏈接層使用這些高層次特徵對輸入圖片進行分類.
除了用於分類,添加一個全鏈接層一般也是一種爲特徵組合添加非線性的方式.對分類任務來講,使用卷積和池化層輸出的特徵就已經能取得不錯的結果,可是把這些特徵組合到一塊兒,效果會更好.
全鏈接層輸出的分類機率之和爲1.這是由softmax保證的.
以上述圖片識別爲例,咱們要識別出來這張圖應該被分類爲dog/cat/boat/bird?
上文說過了,卷積層和池化層的做用是特徵提取,全鏈接層的做用是分類.
整個神經網絡的訓練過程以下:
這樣咱們的神經網絡的filter/parameters/weights這些就肯定下來了,當來了一個新的圖片,咱們就能夠按照前面說的卷積-池化-全鏈接這個過程處理圖片對其進行分類.
幾點要注意的:
這是一個1024個像素點(32*32)的圖片。
卷積層1有6個filter,每一個filter是5*5矩陣(stride=1)。 28*28
池化層1作2*2 max pooling(stride=2)。
能夠看出來作max pooling以後,圖片留下了最亮的點.
卷積層2有6個filter,每一個filter是5*5矩陣(stride=1)。
池化層2作2*2 max pooling(stride=2)。
接下來是3個全鏈接層
cnn識別手寫數字集
model = Sequential() model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same',activation ='relu', input_shape = (28,28,1))) model.add(Conv2D(filters = 64, kernel_size = (5,5),padding = 'Same', activation ='relu')) model.add(MaxPool2D(pool_size=(2,2))) model.add(Flatten()) model.add(Dense(256, activation = "relu")) model.add(Dropout(0.2)) model.add(Dense(10, activation = "softmax")) model.compile(optimizer = "SGD" , loss = "categorical_crossentropy", metrics=["accuracy"]) model.fit(X_train, Y_train, batch_size=100, verbose=1,epochs=5,validation_data=(X_val, Y_val))
完整代碼見https://github.com/sdu2011/nlp/blob/master/keras.ipynb.