【开发者空间实践指导】基于TensorFlow的手写体识别
一、实验介绍
随着人工智能技术的飞速发展,图像识别技术在众多领域得到了广泛应用。手写体识别作为图像识别的一个重要分支,其在教育、金融、医疗等领域具有广泛的应用前景。本实验旨在利用深度学习框架TensorFlow,结合MNIST手写体数据集,构建一个高效、准确的手写体识别系统,本实验是在云主机中安装PyCharm,并且基于TensorFlow框架的手写体识别的案例。
本实验采用的MNIST数据库(Modified National Institute of Standards and Technology database)是一个大型数据库 的手写数字是通常用于训练 各种图像处理 系统。该数据库还广泛用于机器学习 领域的培训和测试。MNIST数据集共有训练数据60000项、测试数据10000项。每张图像的大小为28*28(像素),每张图像都为灰度图像,位深度为8(灰度图像是0-255)。
二、 免费领取云主机
如您还没有云主机,可点击链接,根据领取指南进行操作。
如您已领取云主机,可直接开始实验。
三、实验流程
说明:
① 下载并安装PyCharm;
② 创建Python文件,部署TensorFlow;
③ 编写代码,实现手写体识别;
④ 运行代码,生成结果。
四、实验资源及所需环境
云资源 |
消耗/时 |
时长 |
开发者空间-云主机 |
免费 |
40分钟 |
环境:
TensorFlow |
pip3 install tensorflow -i http://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple |
Matplotlib |
pip3 install matplotlib |
五、实验步骤
1、安装PyCharm
1.1 下载PyCharm
进入云主机,打开左侧Firefox浏览器,搜索https://www.jetbrains.com.cn/en-us/pycharm/download/download-thanks.html?platform=linux 点击下载PyCharm。
下载好后是一个压缩文件,选择将文件压缩到此处。
解压后目录内容显示如下。
1.2 安装PyCharm
双击进入bin目录,双击PyCharm图标打开PyCharm。
在PyCharm的左下角单击图标打开终端。
进入到终端后输入命令进入到bin目录下。
cd 下载
cd pycharm-2024.2.1
cd bin
输入命令执行脚本。
sh ./pycharm.sh
执行完命令后会自动弹出窗口,选择“开始30天免费试用”。
2、下载TensorFlow框架
2.1 新建目录
打开PyCharm,单击左上角图标在弹出的菜单中选择“新建>目录”。
目录名称输入:demo。
2.2 新建文件
在PyCharm左侧新建的demo目录单击鼠标右键,在打开的菜单中选择“新建>Python文件”。
输入Python文件的名字,自定义即可。
2.3 部署TensorFlow框架
新建好后,在左侧找到新建好的Python文件双击打开。
单击左下角图标打开终端。
在终端输入命令,部署TensorFlow框架。
pip3 install tensorflow -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
3、编写代码
3.1 创建和编写文件
在demo目录下新建一个py文件进行代码编辑。
import tensorflow as tf
from tensorflow.keras import layers, models, callbacks
import matplotlib.pyplot as plt
import numpy as np
# 下载MNIST数据集
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 归一化数据
x_train, x_test = x_train / 255.0, x_test / 255.0
# 拓展维度
x_train = x_train[..., tf.newaxis].astype("float32")
x_test = x_test[..., tf.newaxis].astype("float32")
# 数据增强
data_augmentation = tf.keras.Sequential([
layers.RandomRotation(0.1),
layers.RandomZoom(0.1),
layers.RandomTranslation(0.1, 0.1)
])
# 创建数据集对象,并设置每个批次的大小
train_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train)).shuffle(10000).batch(32)
test_ds = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)
# 构建模型
model = models.Sequential([
data_augmentation,
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(128, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dropout(0.5),
layers.Dense(128, activation='relu'),
layers.Dense(10)
])
# 编译模型
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# 回调模型
reduce_lr = callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5, min_lr=0.0001)
early_stopping = callbacks.EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
model_checkpoint = callbacks.ModelCheckpoint('best_model.keras', monitor='val_loss', save_best_only=True)
# 训练模型
history = model.fit(train_ds, epochs=10, validation_data=test_ds, callbacks=[reduce_lr, early_stopping, model_checkpoint])
# 加载模型最佳权重
model.load_weights('best_model.keras')
# 评估模型
test_loss, test_acc = model.evaluate(test_ds, verbose=2)
print('\nTest accuracy:', test_acc)
# 绘制实验的损失及准确率
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend(loc='upper right')
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.show()
# 预测并绘制一些预测样本
def plot_image(i, predictions_array, true_label, img):
true_label, img = true_label[i], img[i].reshape((28, 28))
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.imshow(img, cmap=plt.cm.binary)
predicted_label = np.argmax(predictions_array)
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.xlabel("{} {:2.0f}% ({})".format(true_label, 100*np.max(predictions_array), predicted_label),
color=color)
# 预测测试样本集
predictions = model.predict(test_ds)
# 绘制前五个测试样本
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
plt.subplot(num_rows, 2*num_cols, 2*i+1)
plot_image(i, predictions[i], y_test, x_test)
plt.tight_layout()
plt.show()
当代码编写完毕后,需要下载相应的Python包,在终端输入命令:pip3 install matplotlib 指令下载。
3.2 代码部分讲解
1)导入数据包;
首先对于导包部分导入TensorFlow、matplotlib、numpy等库,用于进行深度学习模型的构建数据可视化。
2)下载MNIST数据集;
这段代码加载了MNIST数据集,这是一个包含手写体数字0到9的图片数据集,常用于图像识别的入门任务。数据集分为训练集和测试集。
3)数据预处理;
这里对图像数据进行了归一化处理,将像素值从0-255的范围缩放到0-1。这样做可以加快模型的训练速度并提高其性能。之后,通过增加一个维度,将数据形状调整为模型所需的格式(样本数量,高度,宽度,通道数),并将数据类型转换为float32.
4)创建数据集对象;
将训练和测试数据转换为TensorFlow的数据集对象,并设置批次大小为32。并对训练数据进行混洗。
5)构建模型;
构建一个顺序模型,包括数据增强层、三个卷积层(每个卷积层后跟一个池化层)、一个展平层、一个丢弃层以及两个全连接层。
6)编译模型;
配置模型的学习过程,选择Adam优化器、稀疏分类交叉熵损失函数,并设置评估指标为准确率。
7)回调模型;
定义三个回调函数,用于在学习工程中调整学习率、早停以及在验证损失改善时保存模型权重。
8)训练模型;
使用训练数据集训练模型,指定训练轮数为10,使用测试数据集进行验证,并应用之前定义的回调函数。
9)加载模型最佳权重;
在训练完成后,加载具有最佳验证的损失的模型权重。
10)评估模型;
在测试数据集上评估模型的性能,并打印准确率。
11)可视化训练过程;
使用matplotlib绘制训练和验证损失及准确率的变化曲线。
12)预测并展示结果。
定义plot_image函数:用于绘制单个预测结果,显示图像、真是标签、预测概率和预测标签;
预测测试样本:使用model.predict对测试数据集进行预测;
绘制预测结果:选择前几个测试样本,调用plot_image函数绘制预测结果。
4、运行结果生成
代码编写完毕后右击鼠标,点击运行。
运行后会出现手写体识别的结果,上方图片是手写的字体,图片下方是模型预测的结果。
运行结果中有loss损失函数,以及acc准确率,可以看到loss损失函数在慢慢的降低,而acc准确率在慢慢的升高。acc准确率提高的原因是因为训练轮数的不断增加,交叉熵损失衡量了模型预测与真实标签之间的差异。在训练过程中,优化器的目标是使损失函数最小化。随着训练轮数的增加,损失函数的值逐渐降低,这意味着模型的预测越来越接近真实标签,从而提高准确率。可以看到每一个epoch中每一秒的准确率以及损失率的变换。
Loss损失率和acc准确率折线图,能供清楚的看到,loss损失率随着eopch的不断增加而减少,acc准确率则随着epoch的不断增加而不断提高。
至此,实验完毕。
想了解更多手写体识别的内容可以访问:
https://yann.lecun.com/exdb/mnist/
想了解更多关于TensorFlow框架的可以访问:
- 点赞
- 收藏
- 关注作者
评论(0)