深度学习的上机作业:
基于CNN卷积神经网络的MINIST手写体识别
版本:python-3.9,tensorflow-2.9
目录
MINIST数据集
训练CNN卷积神经网络
使用训练好的模型进行预测
写这篇文章为了讲一个故事:
老师布置了一个上机作业,建议参照着书上的代码进行完成,但书上的代码是四年前的,tensorflow已经大变样了,然后我浪费了两天的时间来改Bug与兼容,最终选择照着官方文档写2.0-tensorflow的故事。
由很多人手写的数字构成,分为训练集与测试集
训练集: 有6万张图片,每张图片大小28x28,同时有对应数量的标签(就是每张图片对应的数字)
测试集: 与训练集相比,其他一样,就是图片只有1万张
我们可以看看测试集的大小与部分图片
代码:
import tensorflow as tf
import matplotlib.pyplot as plt
# 导入数据集
mnist = tf.keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
print("训练集样本及标签", train_images.shape, train_labels.shape)
print("测试集样本及标签", test_images.shape, test_labels.shape)
train_images, test_images = train_images / 255.0, test_images / 255.0 # 归一化,不然梯度爆炸
# 进行绘画
for i in range(15):
plt.subplot(3, 5, i + 1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(test_images[i])
plt.xlabel(test_labels[i])
plt.show()
数据集大小:
图像:
运行结果:图像如果看这篇文章是为了完成实验报告,就用这里的代码就行
这个代码是不是看着比书(深度学习之美)上的示例代码简洁?这就是tensorflow在四年的发展,它从原来的偏向底层的代码变成现在这种高度集成的框架,但没有书上那样可以清楚的知道底层是如何实现的。
我将讲解这个代码所定义的神经网络模型,
(与书上唯一不同的就是全连接层的神经元为64个)。
代码:(最后一行是自己的文件路径)
import tensorflow as tf
# 导入数据集
mnist = tf.keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images, test_images = train_images / 255.0, test_images / 255.0 # 归一化,不然梯度爆炸
# 训练模型
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(32, (5, 5), activation='relu', padding='same', input_shape=(28, 28, 1)))
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
model.add(tf.keras.layers.Conv2D(64, (5, 5), activation='relu', padding='same'))
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(10)) # 最后输出10个数
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.fit(train_images, train_labels, validation_data=(test_images, test_labels))
# 评估模型精度
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\n最终测试集上的精度为:', test_acc)
# 保存模型
model.save( "../兼收并蓄/CNN模型") # 这是自定义的路径,删除"/兼收并蓄"即可直接运行
运行结果:
在训练集上训练了1875次,每次32张图片,最终在测试集上的精度为: 0.9874
好不容易将模型训练完了,怎么能够不去使用?
从文件夹读取出模型,开始预测,看看自己亲手训练出的成果如何。
(这里应该将图片给显示出来才直观,但是那样意义不大,只看标签也够了)
代码:
import tensorflow as tf
# 导入数据集
mnist = tf.keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# 引入模型
model = tf.keras.models.load_model("../兼收并蓄/CNN模型")
# 加入待预测的图像及其标签
show_images, show_labels = test_images[0:20], test_labels[0:20]
print("所选取的测试集图片的标签is:", show_labels)
# 开始预测
predictions = model.predict(show_images)
# 预测完成
predictions_num = tf.argmax(predictions, 1)
# 输出预测标签
print("所预测的标签为:", predictions_num)
运行结果:
(可以看到训练20个图像,全部都预测对了)