keras卷积网络对手写数字的识别
keras卷积网络对手写数字的识别与多层感知器对手写数字识别的步骤内容差不多,这一章主要写之间不同的地方,步骤一样,接下来直接上代码
1、数据预处理
from keras.datasets import mnist
from keras.utils import np_utils
import numpy as np
(x_train,y_train),(x_test,y_test)=mnist.load_data()#下载数据集
x_train4D=x_train.reshape(x_train.shape[0],28,28,1).astype('float32')#数据转换
x_test4D=x_test.reshape(x_test.shape[0],28,28,1).astype('float32')
x_train4D_normallize=x_train4D/255#标准化
x_test4D_normalize=x_test4D/255
y_trainOnHot=np_utils.to_categorical(y_train)#独热编码处理标签
y_testOnHot=np_utils.to_categorical(y_test)
下载数据,标签处理与多层感知器一样,唯一不一样的地方为把图像数据转换 为6000*28*28*1的四维矩阵,而多层感知器把数据处理为6000*784的二维矩阵,因为这里多了卷积层,所以需要输入的数据类型也就不一样了。
2、建立模型
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPooling2D
model=Sequential()
model.add(Conv2D(filters=16,
kernel_size=(5,5),
padding='same',
input_shape=(28,28,1),
activation='relu')) #卷积层1
model.add(MaxPooling2D(pool_size=(2,2))) #池化层1
model.add(Conv2D(filters=36,kernel_size=(5,5),
padding='same',activation='relu'))#卷积层2
model.add(MaxPooling2D(pool_size=(2,2)))#池化层2
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.summary()
与多层最大的不同就是多了个卷积模块,卷积层1的运算就是将28*28的数字图像,使用随机产生的5*5的矩阵(又叫滤镜)进行卷积运算,卷积运算的结果不会改变图像的大小,但是矩阵运算类似于滤镜效果,每一个新的图像都提取了原始图形的不同特征。
卷积参数说明:
filters | 建立16个滤镜 |
kernel_size | 每一个滤镜5*5的大小,5行5列的矩阵 |
padding | 卷积运算完产生的卷积图像大小不变 |
input_shape=(28,28,1) | 输入图像的大小为28*28大小,1代表为单色灰白 |
activation | 激活函数,一般为relu |
池化层原理:原本图像是28*28,经过池化层就变为14*14(利用保留矩阵里四个相邻的最大的数值来达到减半的作用),但是不会改变图像的数量。利用提取 不同特征如何缩减像素,这种方法叫做缩减采样。
平坦层,将缩减完的36*7*7的数据转换为1764个数据,这样才能进入隐藏层,并且在keras模型中,每个模型的输出都为下一个模型的输入。
在训练模型中可以通过改变卷积层的个数,隐藏层个数或者隐藏层神经元个数来获得较好的训练模型。
接下来的模型训练,预测,可视化都与多层感知器一样,这里只上代码
#训练模型
model.compile(loss='categorical_crossentropy',
optimizer='adam',metrics=['accuracy'])
train_history=model.fit(x=x_train4D_normallize,
y=y_trainOnHot,validation_split=0.2,
epochs=10,batch_size=300,verbose=2)
#建立显示训练过程的函数
import matplotlib.pyplot as plt
def show_train_history(train_history,train,validation):
plt.plot(train_history.history[train])
plt.plot(train_history.history[validation])
plt.title('Train History')
plt.ylabel(train)
plt.xlabel('Epoch')
plt.legend(['train','validation'],loc='upper left')
plt.show()
show_train_history(train_history,'acc','val_acc')
show_train_history(train_history,'loss','val_loss')
prediction=model.evaluate(x_test4D_normalize,y_testOnHot)
print('准确率为:',prediction[1])
#创建方便查看数字图像、真实的数字与预测结果
def plot_images_labels_prediction(images,labels,prediction,idx,num=10):
fig=plt.gcf()#设置显示图形大小
fig.set_size_inches(12,14)
if num>25:num=25
for i in range(0,num):
ax=plt.subplot(5,5,1+i)#建立子图5行5列
ax.imshow(images[idx],cmap='binary')
title='lablel='+str(labels[idx])
if len(prediction)>0:
title+=',predict='+str(prediction[idx])
ax.set_title(title,fontsize=10)
ax.set_xticks([]);ax.set_yticks([])
idx+=1
plt.show()
prediction=model.predict_classes(x_test4D)#预测测试集
plot_images_labels_prediction(x_test,y_test,prediction,idx=0)
import pandas as pd
pd.crosstab(y_test,prediction,
rownames=['labels'],colnames=['predict'])