#卷积神经网络(CNN)训练手写体数据集
import numpy as np
import matplotlib.pyplot as plt
import tensorflow.keras as ka
import datetime
#python3.X版本显示图片还需导入此库
import pylab
np.random.seed(0)
#定义加载数据集函数
def load_data_npz(path):
#np.load文件可以加载npz,npy格式的文件
f = np.load(path)
X_train,y_train,X_test,y_test = f['x_train'], f['y_train'], f['x_test'],f['y_test']
f.close()
#返回加载后的地址
return X_train, y_train, X_test, y_test
#加载自定义mnist数据集文件地址
path = 'C:/Users/yeahamen/AppData/Local/Programs/Python/Python310/Lib/site-packages/keras/datasets/mnist.npz'
X_train,y_train,X_test,y_test = load_data_npz(path)
# 查看手写体数字数据集图像
plt.imshow(X_train[1])
#python3.X版本显示图片还需加此行
pylab.show()
# 查看mnist数据集的形状
print('X_train:{}'.format(X_train.shape))
print('y_train:{}'.format(y_train.shape))
print('X_test:{}'.format(X_test.shape))
print('y_test:{}'.format(y_test.shape))
#以行为单位将二维数组拉成一维的向量
X_train = X_train.reshape(X_train.shape[0],28,28,1).astype('float32')
X_test = X_test.reshape(X_test.shape[0],28,28,1).astype('float32')
#归一化灰度值
X_train = X_train/255
X_test = X_test/255
#将(训练集与测试集)标签转化为独热编码,即将向量转化为0-1二进制矩阵类型表示;详细解释可见:http://t.csdn.cn/W4wDZ
y_train = ka.utils.to_categorical(y_train)
y_test = ka.utils.to_categorical(y_test)
#获取测试集标签列数10(测试集标签只有0-9这十种类型),所以独热后测试集变为10000(行)*10(列)的数据
num_classes = y_test.shape[1]
#CNN模型
#输入28*28*32
model = ka.Sequential([ka.layers.Conv2D(filters = 32,kernel_size=(5,5),input_shape=(28,28,1),activation='relu'),
#卷积24*24*32、卷积层;参量依次为:卷积核个数、卷积核尺寸、单个像素点尺寸、使用ReLu激活函数、解释可见:http://t.csdn.cn/6s3dz
ka.layers.MaxPooling2D(pool_size=(2,2),strides = None,padding='VALID'),
#池化12(24/2)*12*32、最大池化层,池化核尺寸2*2、步长默认为2、无填充、解释可见:http://t.csdn.cn/sES2u
ka.layers.Dropout(0.2),
#模型正则化防止过拟合, 只会在训练时才会起作用,随机设定输入的值x的某一维=0,这个概率为输入的百分之20,即丢掉1/5神经元不激活
#在模型预测时,不生效,所有神经元均保留也就是不进行dropout。解释可见:http://t.csdn.cn/RXbmS、http://t.csdn.cn/zAIuJ
ka.layers.Flatten(),
#拉平12*12*32=4608;拉平池化层为一个向量
ka.layers.BatchNormalization(),
#批标准化层,提高模型准确率
ka.layers.Dense(128,activation='relu'),
#全连接层1,128个神经元,激活函数为ReLu
ka.layers.Dense(num_classes,activation='softmax')])
#全连接层2,10个神经元(对应数字0-9),激活函数为softmax,作用是把神经网络的输出转化为概率,参考可见:http://t.csdn.cn/bcWgu;http://t.csdn.cn/A1Jyn
model.summary()
#对于输出参数解释可见:http://t.csdn.cn/k9bgm
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
#损失函数为分类交叉熵;优化器为adam,参考解释可见:http://t.csdn.cn/YcBq0;评价函数为accuracy,用来评价模型训练的性能,参考同前。
#获取训练之前时间
startdate = datetime.datetime.now()
#训练轮数epochs=n,即训练n轮
model.fit(X_train,y_train,validation_data=(X_test,y_test),epochs=2,batch_size=200,verbose=2)
#训练样本、训练标签、指定验证数据为测试集、训练轮数、显示每一轮训练进程,参考可见:http://t.csdn.cn/oE46K
#获取训练结束时间
enndate=datetime.datetime.now()
print("训练用时:"+str(enndate-startdate))
只需经过两轮训练便能达到0.9914的精度!