用keras訓練mnist資料集手寫識別
阿新 • • 發佈:2018-12-23
%matplotlib inline
import pickle
import os
import keras, theano
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
# keras2 用Conv2D 替換 Convolution2D
from keras.layers import Conv2D,MaxPooling2D
from keras.utils import np_utils
from keras.datasets import mnist
from keras import backend as bk
# 可以通過 backend判斷是theano還是tensorflow,兩者 對影象的channel通道位置不統一
# 本文采用theano,所以配置是"image_data_format": "channels_first", 即input shape是(通道數,寬,高)
# mnist 格式:train集: x=[60000張[28*28的畫素值]],y=[60000個(0~9)]. test集x=[10000張[28*28的畫素值]],y=[10000個(0~9)].
# train[0]:x_train,train[1]:ytrain
train,test
if os .path.exists('mnist.pkl'):
f=open('mnist.pkl','rb')
if f:
train,test=pickle.load(f)
print("loading mnist from local")
else:
train,test = mnist.load_data()
#寫到本地
pickle.dump((train,test),open('mnist.pkl','wb'))
print(train[0].shape)
#print(train[0][0]) #[[ 0 0 0 0 0 0 0 0 0 0 0 0 3 18 18 18 126 136 175 26 166 255 247 127 0 0 0 0]...]
# print(train[1][:10]) # [5 0 4 1 9 2 1 3 1 4]
from matplotlib import pyplot as plt
plt.imshow(train[0][0])
# 在後端使用 Theano 時, 必須顯式地宣告一個維度, 用於表示輸入圖片的深度. 舉個例子, 一幅帶有 RGB 3 個通道的全綵圖片, 深度為 3.
# MNIST 圖片的深度為 1, 因此必須顯式地進行宣告.
# 要將資料集從 (n, width, height) 轉換成 (n, depth, width, height).
trainx=train[0].reshape(train[0].shape[0],1,28,28)
testx=test[0].reshape(test[0].shape[0],1,28,28)
print(trainx.shape)
print(testx.shape)
# 由於顏色值都是0-255的值,將其歸一化,浮點化
#print(trainx[0])
trainx=trainx.astype('float32')
testx=testx.astype('float32')
trainx /=255
testx /=255
# 處理標籤, 將值轉為分類標籤二維表,共60000行,10列. 第一個數5 置矩陣第一行的第6列為1. 0 放在第二行第0列為1
trainy = np_utils.to_categorical(train[1],10)
testy = np_utils.to_categorical(test[1],10)
#print(train[1][:10]) #[5 0 4 1 9 2 1 3 1 4]
#print(trainy[:10]) #[[ 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.] [ 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]...]
print(trainy.shape,testy.shape) #(60000, 10) (10000, 10)
# 模型處理
# 建立序列模型
model = Sequential()
# 建立卷積輸入層.
model.add(Conv2D(32,kernel_size=(3, 3),activation='relu', input_shape=(1,28,28)))
print(model.output_shape) #(None, 32, 26, 26)
# 添加捲積層
model.add(Conv2D(64,kernel_size=(3, 3),activation='relu'))
# 新增pooling層
model.add(MaxPooling2D(pool_size=(2,2)))
# 新增Drop out層,防止過擬合。0.25表示隨機丟掉1/4的點
model.add(Dropout(0.25))
# 新增全輸出層
# 必須平面化
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
# 輸出必須是類別數
model.add(Dense(10,activation='softmax'))
# 編譯模型, 新增損失函式和優化函式。損失函式採用交叉資訊熵。
model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(),metrics=['accuracy'])
# 訓練擬合
model.fit(trainx,trainy, batch_size=128,epochs=2,verbose=1,validation_data=(testx,testy))
# 評估模型
score = model.evaluate(testx,testy)
print("loss:{}".format(score[0]))
print("accuracy:{}".format(score[1]))