【开发者空间实践指导】基于TensorFlow的手写体识别

举报
开发者空间小蜜蜂 发表于 2024/11/26 15:15:38 2024/11/26
【摘要】 本实验采用的MNIST数据库(Modified National Institute of Standards and Technology database)是一个大型数据库的手写数字是通常用于训练各种图像处理系统。该数据库还广泛用于机器学习领域的培训和测试。

一、实验介绍

随着人工智能技术的飞速发展,图像识别技术在众多领域得到了广泛应用。手写体识别作为图像识别的一个重要分支,其在教育、金融、医疗等领域具有广泛的应用前景。本实验旨在利用深度学习框架TensorFlow,结合MNIST手写体数据集,构建一个高效、准确的手写体识别系统,本实验是在云主机中安装PyCharm,并且基于TensorFlow框架的手写体识别的案例。

本实验采用的MNIST数据库(Modified National Institute of Standards and Technology  database)是一个大型数据库 的手写数字是通常用于训练 各种图像处理 系统。该数据库还广泛用于机器学习 领域的培训和测试。MNIST数据集共有训练数据60000项、测试数据10000项。每张图像的大小为28*28(像素),每张图像都为灰度图像,位深度为8(灰度图像是0-255)。

二、 免费领取云主机

如您还没有云主机,可点击链接,根据领取指南进行操作。

如您已领取云主机,可直接开始实验。

三、实验流程

image003.png

说明:

① 下载并安装PyCharm;

② 创建Python文件,部署TensorFlow;

③ 编写代码,实现手写体识别;

④ 运行代码,生成结果。

四、实验资源

云资源

消耗/

时长

开发者空间-云主机

免费

40分钟

合计:0

五、实验步骤

1、安装PyCharm

1.1 下载PyCharm

进入云主机,打开左侧Firefox浏览器,搜索https://www.jetbrains.com.cn/en-us/pycharm/download/download-thanks.html?platform=linux 点击下载PyCharm。

image005.png

下载好后是一个压缩文件,选择将文件压缩到此处。

解压后目录内容显示如下。

image009.png

1.2 安装PyCharm

双击进入bin目录,双击PyCharm图标打开PyCharm。

image011.png

在PyCharm的左下角单击图标打开终端。

进入到终端后输入命令进入到bin目录下。

cd 下载
cd pycharm-2024.2.1
cd bin

输入命令执行脚本。

sh ./pycharm.sh

执行完命令后会自动弹出窗口,选择“开始30天免费试用”。

image017.png

2、下载TensorFlow框架

2.1 新建目录

打开PyCharm,单击左上角图标在弹出的菜单中选择“新建>目录”。

image019.png

目录名称输入:demo。

image021.png

2.2 新建文件

在PyCharm左侧新建的demo目录单击鼠标右键,在打开的菜单中选择“新建>Python文件”。

image023.png

输入Python文件的名字,自定义即可。

image025.png

2.3 部署TensorFlow框架

新建好后,在左侧找到新建好的Python文件双击打开。

image027.png

单击左下角图标打开终端。

image029.png

在终端输入命令,部署TensorFlow框架。

pip3 install tensorflow

image031.png

3、编写代码

3.1 创建和编写文件

在demo目录下新建一个py文件进行代码编辑。

image033.png

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 指令下载。

image035.png

3.2 代码部分讲解

1)导入数据包;

首先对于导包部分导入TensorFlow、matplotlib、numpy等库,用于进行深度学习模型的构建数据可视化。

image037.png

2)下载MNIST数据集;

这段代码加载了MNIST数据集,这是一个包含手写体数字0到9的图片数据集,常用于图像识别的入门任务。数据集分为训练集和测试集。

image039.png

3)数据预处理;

这里对图像数据进行了归一化处理,将像素值从0-255的范围缩放到0-1。这样做可以加快模型的训练速度并提高其性能。之后,通过增加一个维度,将数据形状调整为模型所需的格式(样本数量,高度,宽度,通道数),并将数据类型转换为float32.

image041.png

4)创建数据集对象;

将训练和测试数据转换为TensorFlow的数据集对象,并设置批次大小为32。并对训练数据进行混洗。

image043.png

5)构建模型;

构建一个顺序模型,包括数据增强层、三个卷积层(每个卷积层后跟一个池化层)、一个展平层、一个丢弃层以及两个全连接层。

image045.png

6)编译模型;

配置模型的学习过程,选择Adam优化器、稀疏分类交叉熵损失函数,并设置评估指标为准确率。

image047.png

7)回调模型;

定义三个回调函数,用于在学习工程中调整学习率、早停以及在验证损失改善时保存模型权重。

image049.png

8)训练模型;

使用训练数据集训练模型,指定训练轮数为10,使用测试数据集进行验证,并应用之前定义的回调函数。

image051.png

9)加载模型最佳权重;

在训练完成后,加载具有最佳验证的损失的模型权重。

image053.png

10)评估模型;

在测试数据集上评估模型的性能,并打印准确率。

image055.png

11)可视化训练过程;

使用matplotlib绘制训练和验证损失及准确率的变化曲线。

image057.png

12)预测并展示结果。

定义plot_image函数:用于绘制单个预测结果,显示图像、真是标签、预测概率和预测标签;

预测测试样本:使用model.predict对测试数据集进行预测;

绘制预测结果:选择前几个测试样本,调用plot_image函数绘制预测结果。

image059.png

4、运行结果生成

代码编写完毕后右击鼠标,点击运行。

image061.png

运行后会出现手写体识别的结果,上方图片是手写的字体,图片下方是模型预测的结果。

image063.png

运行结果中有loss损失函数,以及acc准确率,可以看到loss损失函数在慢慢的降低,而acc准确率在慢慢的升高。acc准确率提高的原因是因为训练轮数的不断增加,交叉熵损失衡量了模型预测与真实标签之间的差异。在训练过程中,优化器的目标是使损失函数最小化。随着训练轮数的增加,损失函数的值逐渐降低,这意味着模型的预测越来越接近真实标签,从而提高准确率。可以看到每一个epoch中每一秒的准确率以及损失率的变换。

image065.png

Loss损失率和acc准确率折线图,能供清楚的看到,loss损失率随着eopch的不断增加而减少,acc准确率则随着epoch的不断增加而不断提高。

image067.png

至此,实验完毕。

想了解更多手写体识别的内容可以访问:

  https://yann.lecun.com/exdb/mnist/

想了解更多关于TensorFlow框架的可以访问:

关于TensorFlow | TensorFlow中 文官网

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。