深度學習 - MNIST - CNN 卷積神經網絡練習
CNN(Convolution Neural Network Convnet) 卷積神經網絡,見Wiki解釋其結構包括:
1.卷積層(含線性整流激活)
想像你有一個5×5矩陣表示的圖片,然後你用一個3×3的矩陣在圖片中滑動。每當3×3矩陣經過的點就用原矩陣中被覆蓋的矩陣和這個矩陣相乘。這樣一來,我們可以使用一個值來表示當前窗口中的所有點。
如圖,卷積特徵矩陣中的每一個項都和原圖中的一個區域相關。
在圖中像窗口一樣移動的叫做核。核一般都是方陣,可以選擇5*5或3*3,對於小圖片來說,一般選用3×3的矩陣就可以了。每次窗口移動的距離叫做步幅。值得注意的是,一些圖片在邊界會被填充零,如果直接進行卷積運算的話會導致邊界處的數據變小(當然圖片中間的數據更重要)。
卷積層的主要目的是濾波。當我們在圖片上操作時,我們可以很容易得檢查出那部分的模式,這是由於我們使用了濾波,我們用權重向量乘以卷積之後的輸出。當訓練一張圖片時,這些權重會不斷改變,而且當遇到之前見過的模式時,相應的權值會提高。來自各種濾波器的高權重的組合讓網絡預測圖像的內容的能力。就是為什麼在CNN架構圖中,卷積步驟由一個框而不是一個矩形表示;第三維代表濾波器。
2.池化層(Pooling Layer)
池化層和卷積層很類似,也是用一個矩陣在圖上移動,通常是(2*2)矩陣,這樣輸出後的矩陣大小會變1/4。與卷積層不同的地方就是池化層中核和圖片窗口的操作不再是線性的。
最大池化(Max_pooling)和平均池化(AV_pooling)是最常見的池化函數。最大池化選取當前核覆蓋的圖片窗口中最大的數,而平均池化則是選擇圖片窗口的均值。
圖片為Max_pooling 操作範例。
3.dropout層 - 見深度學習 - IMDb數據集 - 過擬合
#載入mnist數據,並做預處理,符合模型的輸入形狀 from keras.datasets import mnist (train_images, train_labels), (test_images, test_labels) = mnist.load_data() train_images = train_images.reshape((60000, 28, 28, 1)) train_images = train_images.astype('float32') / 255 test_images = test_images.reshape((10000, 28, 28, 1)) test_images = test_images.astype('float32') / 255
#準備標籤 from keras.utils import to_categorical train_labels = to_categorical(train_labels) test_labels = to_categorical(test_labels)
#建構CNN網絡 from keras import layers from keras import models model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Dropout(0.5)) #加入dropout層,預防過擬合 model.add(layers.Conv2D(64, (3, 3), activation='relu'))以上為小型卷積神經網絡
將神經網絡輸出攤平成向量,最後用softmax將輸入轉成10等分概率輸出。
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
看以下model 每經過一層之後的形狀變化,可以大概知道卷積層(Conv2D)、池化層(Pooling)
大概做了甚麼事。
>>>model.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
1. conv2d_1 (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
2. max_pooling2d_1 (MaxPooling2 (None, 13, 13, 32) 0
_________________________________________________________________
3. conv2d_2 (Conv2D) (None, 11, 11, 64) 18496
_________________________________________________________________
4. max_pooling2d_2 (MaxPooling2 (None, 5, 5, 64) 0
_________________________________________________________________
5. dropout_1 (Dropout) (None, 5, 5, 64) 0
_________________________________________________________________
6. conv2d_3 (Conv2D) (None, 3, 3, 64) 36928
_________________________________________________________________
7. flatten_1 (Flatten) (None, 576) 0
_________________________________________________________________
8. dense_1 (Dense) (None, 64) 36928
_________________________________________________________________
9. dense_2 (Dense) (None, 10) 650
=================================================================
Total params: 93,322
1. 從輸入data開始,輸入形狀為(28,28,1) 像素28*28的圖片,經過第一層後卷積神經將28*28的圖片由3*3的小圖尺寸局部提取特徵(26*26個),存入至32個通道。
2. 經過池化層後,像單邊素大小變為一半(13*13),後面3.4.略...。
Max_pooling 圖像概念 :見wiki
5. 為dropout層,將隨機隱藏1半的空間網絡,降低過擬合的情形。
6. 略...
7. Flatten層,將(3, 3, 64) 3D張量形狀的網絡攤平存進1D張量形狀,共576(3*3*64)個向量,
最後,就是熟悉的優化器、損失函數、指標的選擇。
#選擇優化器、損失函數、指標 model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
開始訓練
#丟進fit訓練 model.fit(train_images, train_labels, epochs=5, batch_size=64)
最後測試模型表現
#模型在測試data的表現 scores = model.evaluate(test_images, test_labels, ) print('scores = ',scores)
scores = [0.024447711960464948, 0.9919]
測試精度到達99.19%
沒有留言:
張貼留言