1. 程式人生 > >keras與卷積神經網路(CNN)實現識別minist手寫數字

keras與卷積神經網路(CNN)實現識別minist手寫數字

在本篇博文當中,筆者採用了卷積神經網路來對手寫數字進行識別,採用的神經網路的結構是:輸入圖片——卷積層——池化層——卷積層——池化層——卷積層——池化層——Flatten層——全連線層(64個神經元)——全連線層(500個神經元)——softmax函式,最後得到分類的結果。Flatten層用於將池化之後的多個二維陣列展開成一維陣列,再灌入全連線層的神經元當中。

首先導包:

import keras
from keras import layers
from keras import models

建立神經網路的順序模型:

model = models.Sequential()

新增神經網路的結構(三組卷積層,池化層。一個flatten層,以及兩個全連線層),啟用函式我一般喜歡使用relu,當然你也可以使用sigmoid,tanh這兩個啟用函式,更改我的程式碼即可。由於是手寫數字,最後的softmax一共只能夠有十個數字,因此輸出寫10.啟用函式使用softmax。其他都是relu。

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.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(500, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

神經網路搭建完畢,開始導minist手寫數字,對數字進行分類,分為訓練集和驗證集,同時將數字進行reshape,程式碼如下:

from keras.datasets import mnist
from keras.utils import to_categorical
(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
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

緊接著選擇需要進行梯度下降的優化器,常見的有adagrad,adam,rmsprop等等,這裡選擇了rmsprop。損失函式loss function這裡選擇了Cross Entropy,也就是交叉熵(因為最後是一個softmax函式進行分類,我們常常用交叉熵來衡量模型的準確度,這個計算起來比較方便,也比較有道理)。模型fit的過程當中我選擇了mini—batch小批量梯度下降法,用這個方法比較適合電腦,如果使用所有資料進行梯度下降,那麼電腦跑很久才能夠完成,如果使用小批量梯度下降,電腦則可以自動進行平行計算,時間減少。迭代次數我選擇了10次,每一個mini——batch的批量為128,這個無所謂,這個引數適中即可,不可太大也不能太小。程式碼如下:

model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=10, batch_size=128)

輸出:

Epoch 1/10
60000/60000 [==============================] - 42s 703us/step - loss: 0.0192 - acc: 0.9940
Epoch 2/10
60000/60000 [==============================] - 42s 706us/step - loss: 0.0166 - acc: 0.9945
Epoch 3/10
60000/60000 [==============================] - 43s 724us/step - loss: 0.0146 - acc: 0.99580s - loss: 0.0145 - acc: 0.9
Epoch 4/10
60000/60000 [==============================] - 43s 720us/step - loss: 0.0129 - acc: 0.9960
Epoch 5/10
60000/60000 [==============================] - 43s 718us/step - loss: 0.0130 - acc: 0.9962
Epoch 6/10
60000/60000 [==============================] - 44s 728us/step - loss: 0.0105 - acc: 0.9966
Epoch 7/10
60000/60000 [==============================] - 44s 737us/step - loss: 0.0095 - acc: 0.9969
Epoch 8/10
60000/60000 [==============================] - 44s 728us/step - loss: 0.0101 - acc: 0.9972
Epoch 9/10
60000/60000 [==============================] - 44s 735us/step - loss: 0.0085 - acc: 0.9974
Epoch 10/10
60000/60000 [==============================] - 45s 743us/step - loss: 0.0081 - acc: 0.99750s - loss: 0.0081 - acc: 0.997

可以看到模型經過十次迭代,訓練集的準確度已經達到了%99.7以上,這樣會不會出現過擬合的情況呢?用不用減少一下模型的迭代次數呢?筆者的心裡怕怕的,於是用驗證集來驗證一下模型的準確度:

test_loss, test_acc = model.evaluate(test_images, test_labels)
print(test_acc)

輸出:

0.9868

模型的準確度達到了%98.68,接近百分之九十九的樣子,比筆者僅用全連線神經網路訓練的結果高了零點幾的準確度,從中還是可以看出卷積神經網路的有效性,在沒有進行調參的情況下準確度已經很高