首页 > 其他分享 >花 5 分钟自己构建手写数字识别项目,这是一个完全体,可以识别你自己的图片

花 5 分钟自己构建手写数字识别项目,这是一个完全体,可以识别你自己的图片

时间:2024-11-13 21:15:28浏览次数:3  
标签:训练 img 标签 image 28 构建 手写 识别 model

大家好啊,我是董董灿。

手写数字识别项目之前写过相关的文章,但是只介绍了这个项目的背景,并且给出了源码。

后来有很多朋友反馈,按照源码自己设计的模型,虽然可以很好的识别出给定数据集中的图片,但是自己手写的数字却很难识别出来。

这个问题被我解决后,给一部分朋友发过最新的源码,但仍有一些朋友还是会有类似的问题,所以,今天索性写一个该项目的完全体

看完本文,关于手写数字识别这个项目或许:你只需要这一篇文章就够了

1、项目介绍

手写数字识别是计算机视觉(CV)中图像识别门类中的一个项目,也属于一个初学 AI 视觉的入门项目。

该项目以数据集小、神经网络简单、任务简单为优势,并且集合了卷积神经网络中该有的东西,可谓麻雀虽小,五脏俱全。

非常适合新手上手学习。

本文以详细的介绍和给出源码进行走读的形式,带你一览该项目的每一处细节。

文章末尾附代码下载链接,只用自己的笔记本电脑,你也可以从头训练一个可以识别图像的神经网络模型出来。

2、什么是手写数字识别

简答来说,就是搭建了一个卷积神经网络模型,对这个模型进行训练后,它可以完成手写数字的识别。

比如,你用笔在纸上写了个 6,神经网络模型就能认识这是6,你写个8,它就识别出来这是个8,就这么简单。

之所以说该任务简单,是因为它的标签只有 0-9 这 10 种数字分类,相比于 resnet 等网络在 ImageNet 上 1000 个实物分类,确实小很多。

虽然简单,但背后的原理却一点都不少,典型的卷积神经网络训练和算法全部都有。

与该项目一起出名的,便是大名鼎鼎的 MNIST(Mathematical Numbers In Text) 数据集。

该数据集中包含了 60,000 个训练图像和 10,000 个测试图像,图像都是各种手写的数字,基本都是长这样的。

图片

3、代码走读

在了解了项目背景后,我以代码走读的形式,一点点介绍该神经网络模型。

当然你可以按照下面给出的源码,在自己的笔记本上(配置再低也够用)搭建一个python环境,来训练这个模型。

第一步:导入必要的库

# 导入NumPy数学工具箱import numpy as np# 导入Pandas数据处理工具箱import pandas as pd# 从 Keras中导入 mnist数据集from keras.datasets import mnist# 导入绘图工具包import matplotlib.pyplot as plt

keras 是一个开源的人工神经网络库,里面有很多经典的神经网络和数据集,要用的 mnist 数据集就在其中。

第二步:加载数据集

# 从mnist数据集中加载训练数据集以及对应的标签,测试数据集以及对应的标签(x_train_image, y_train_lable), (x_test_image, y_test_lable) = mnist.load_data()

这条命令利用 keras 中自带的 mnist 模块,加载数据集(load_data)进来,分别赋值给四个变量。

其中:x_train_image 保存用来训练的图像,y_train_lable是与之对应的标签。假设图像中的数字是1,那么标签就是1。

x_test_image和 y_test_lable分别为用来验证的图像和标签,也就是验证集。训练完神经网络后,可以使用验证集中的数据进行验证。

第三步:数据预处理

其中一个预处理内容是改变数据集的 shape,使其满足模型的要求。​​​​​​​

# 导入keras.utils工具箱的类别转换工具
from tensorflow.keras.utils import to_categorical

# 给标签增加维度,使其满足模型的需要# 原始标签,比如训练集标签的维度信息是[60000, 28, 28, 1]x_train = x_train_image.reshape(60000, 28, 28, 1)x_test = x_test_image.reshape(10000, 28, 28, 1)# 特征转换为one-hot编码y_train = to_categorical(y_train_lable, 10)y_test = to_categorical(y_test_lable, 10)

这个数据集中的共 60000 张训练图像,10000 张验证图像,每张图像的长宽均为 28 个像素,通道数为 1。

那么对于训练集 x_train_image而言,将其形状变为 NHWC = [60000, 28, 28, 1], 验证集类似。

to_categorical 的作用是将样本标签转为 one-hot 编码,而 one-hot  编码的作用是可以对于类别更好的计算概率或得分。

One-Hot算法

这里我简单介绍下 one-hot,你也可以点这里仔细学习一下。

之所以用 one-hot 编码,是因为对于输出 0-9 这10个标签而言,每个标签的地位应该是相等的,并不存在标签数字 2 大于数字 1 的情况。

但如果我们直接利用标签的原始值(0-9)进行最终结果的计算,就会出现标签2 大于标签 1的情况。

因此,在大部分情况下,都需要将标签转换为 one-hot 编码,也就独热编码,这样标签之间便没有任何大小而言。

这个例子中,数字 0-9 转换为的独热编码为:​​​​​​​

array([[1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],       [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],       [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],       [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],       [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],       [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],       [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],       [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],       [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],       [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]]

每一行的向量代表一个标签。

假设 [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.] 代表 0 而 [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.] 代表1,可以看到这两者之间是正交独立的,不存在谁比谁大的问题。

第四步:创建神经网络​​​​​​​

# 从 keras 中导入模型from keras import models
# 从 keras.layers 中导入神经网络需要的计算层from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
# 构建一个最基础的连续的模型,所谓连续,就是一层接着一层model = models.Sequential()# 第一层为一个卷积,卷积核大小为(3,3), 输出通道32,使用 relu 作为激活函数model.add(Conv2D(32, (3, 3), activation="relu", input_shape=(28, 28, 1)))# 第二层为一个最大池化层,池化核为(2,2)# 最大池化的作用,是取出池化核(2,2)范围内最大的像素点代表该区域# 可减少数据量,降低运算量。model.add(MaxPooling2D(pool_size=(2, 2)))# 又经过一个(3,3)的卷积,输出通道变为64,也就是提取了64个特征。# 同样为 relu 激活函数model.add(Conv2D(64, (3, 3), activation="relu"))# 上面通道数增大,运算量增大,此处再加一个最大池化,降低运算model.add(MaxPooling2D(pool_size=(2, 2)))# dropout 随机设置一部分神经元的权值为零,在训练时用于防止过拟合# 这里设置25%的神经元权值为零model.add(Dropout(0.25))# 将结果展平成1维的向量model.add(Flatten())# 增加一个全连接层,用来进一步特征融合model.add(Dense(128, activation="relu"))# 再设置一个dropout层,将50%的神经元权值为零,防止过拟合# 由于一般的神经元处于关闭状态,这样也可以加速训练model.add(Dropout(0.5))# 最后添加一个全连接+softmax激活,输出10个分类,分别对应0-9 这10个数字model.add(Dense(10, activation="softmax"))

上面每一行代码都加了注释,说明每一行的作用,短短几行,便是这个手写数字识别神经网络的全部了。

至于每一种算法的原理,如果想深入了解,这里有传送门:Conv2D(卷积)MaxPooling2D(池化)Dense(全连接层DropoutSoftmax 

第五步:训练​​​​​​​

# 编译上述构建好的神经网络模型# 指定优化器为 rmsprop# 制定损失函数为交叉熵损失model.compile(optimizer="rmsprop", loss="categorical_crossentropy", metrics=["accuracy"])
# 开始训练model.fit(    x_train,    y_train,  # 指定训练特征集和训练标签集    validation_split=0.3,  # 部分训练集数据拆分成验证集    epochs=5,  # 训练轮次为5轮    batch_size=128,)  # 以128为批量进行训练

Epoch 5/5329/329 [==============================] - 15s 46ms/step - loss: 0.1054 - accuracy: 0.9718 - val_loss: 0.0681 - val_accuracy: 0.9826

训练结果如上,可以看到最后的训练精度达到了 98.26%,还是挺高的。

第6步:测试集评估

​​​​​​​

# 在测试集上进行模型评估score = model.evaluate(x_test, y_test)print("测试集预测准确率:", score[1])  # 打印测试集上的预测准确率

313/313 [==============================] - 1s 4ms/step - loss: 0.0662 - accuracy: 0.9815 测试集预测准确率: 0.9815000295639038

可以看到在验证集上也能有98%的准确率。

第7步:验证一张图片​​​​​​​

# 预测验证集第一个数据pred = model.predict(x_test[1].reshape(1, 28, 28, 1))# 把one-hot码转换为数字print(pred[0], "转换一下格式得到:", pred.argmax())# # # 输出这个图片plt.imshow(x_test[1].reshape(28, 28))plt.show()

‍以验证集中的第一张图片为例来进行验证,输出如下:

1/1 [==============================] - 0s 17ms/step
[4.2905590e-15 2.6790809e-11 2.8249305e-09 2.3393848e-11 7.1304548e-14

1.8217797e-18 5.7493907e-19 1.0000000e+00 8.0317367e-15 4.6352322e-10] 

转换一下格式得到:7

得到的数字是7,将该图片显示出来,确实是7。说明训练的模型确实达到了识别数字的水平。

图片

第8步:自己手写一个数字拍成图片来识别一下

你可以用如下的代码,测试你自己手写的数字的图片。

注意:手写的数字要粗一些,对比度高一些,否则会有一定概率识别出错。​​​​​​​

# 你可以用如下的代码,测试你自己的图片from PIL import Image, ImageOpsimport cv2

def preprocess_handwritten_image(image_path):    # 加载图片    img = Image.open(image_path)    # 转换为灰度图像    img = img.convert("L")    # 反转像素值    img = ImageOps.invert(img)    # 将图像调整为28x28像素    img = img.resize((28, 28))    img = np.array(img)    # Otsu's方法进行自动二值化处理    _, img_binary = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)    # 调整形状为 (1, 28, 28, 1),用于模型输入    img_binary = img_binary.reshape(1, 28, 28, 1)    return img_binary

my_pic = "./5.jpg"  # 你的图片路径preprocessed_image = preprocess_handwritten_image(my_pic)
my_pred = model.predict(preprocessed_image)print(my_pred[0], "我的图片是:", my_pred.argmax())plt.imshow(preprocessed_image.reshape(28, 28))plt.show()

下面这张图片是我手写的数字,识别效果很好。

图片

3、总结

手写数字识别项目比较简单,仅仅两个卷积层,整体运算量不大,就目前计算机的配置,即使笔记本基本上都可以完成该神经网络的训练和验证。

如果你感兴趣,欢迎你关注我的公众号:董董灿是个攻城狮,在公众号后台回复【mnist】获取源码,实操起来吧。


CSDN尾巴

标签:训练,img,标签,image,28,构建,手写,识别,model
From: https://blog.csdn.net/dongtuoc/article/details/143752671

相关文章

  • 浏览器指纹及其识别的优点和缺点
    浏览器指纹识别是网站用来收集有关浏览器和网络设备的独特信息的方法。最初,指纹识别用于网站正确显示,但现在它可以跟踪用户的在线活动并创建他们的在线个人资料,从而使他们成为营销活动的完美目标并剥夺他们的在线隐私。一、什么是浏览器指纹?当网站收集有关其访问者的各种信息......
  • PaddleOCR在华为云上实现文本检测识别任务,并部署到华为昇腾NPU的详细步骤
            PaddleOCR是飞桨推出的一套丰富的OCR工具库开源项目,支持文字检测、文字方向检测、多语种文本识别、手写体文本识别等多种OCR相关前沿算法,并提供了丰富的轻量级预训练模型和模型优化技术,可以快速部署和使用OCR功能。https://github.com/PaddlePaddle/PaddleOCR......
  • GEE 训练教程——通过点构建缓冲区然后构建格网
    目录简介正常构建格网的过程代码解释代码结果简介GEE训练教程——通过点构建缓冲区然后构建格网正常构建格网的过程构建格网的主要流程如下:1.确定研究区域:首先需要确定要构建格网的研究区域,可以是基于经纬度或行政边界等范围。2.确定格网类型:根据研究需求,确定......
  • 汽车场景OCR解决方案:电子行驶证与驾驶证识别,引领智慧交通新纪元
    在数字化浪潮的推动下,交通管理行业迎来了革命性的变化。OCR技术的电子行驶证和电子驾驶证的引入,极大地提高了车辆和驾驶执照的管理效率,并为车主的出行带来了极大的便利。随着电子证件的普及,交通管理正逐步从传统的实体证件向数字化转型,这不仅为智能出行提供了便利,也催生了新的......
  • 值班空岗睡岗识别智慧矿山一体机斜井人员进出识别系统管理功能解析
    在矿山行业迈向智能化、自动化的进程中,智慧矿山一体机应运而生,它是一款专为矿山安全监控和管理设计的创新设备。这款设备不仅能够提升矿山的安全监管能力,还能够通过边缘计算技术实现对矿山安全风险的实时监控和预警。本文将详细介绍值班空岗睡岗识别智慧矿山一体机的系统管理功能,......
  • 非煤矿山算法智慧矿山一体机提升机危险区域违规闯入识别边坡监测预警系统详述
    在矿山行业中,安全始终是最为关键的议题。随着智能化技术的发展,智慧矿山一体机应运而生,它专为矿山安全监控和管理设计,集成了多种智能化功能,以提升矿山的安全监管能力和生产效率。这款设备不仅能够满足矿山场景下的视频智能化建设需求,还能够通过边缘计算技术实现对矿山安全风险的实......
  • CMDB平台(进阶篇):CMDB的构建指南(一)
    CMDB(配置管理数据库)的构建是一个复杂而细致的过程,其中组建项目团队和定义项目是至关重要的初始阶段。以下是根据高权威性来源整理的,关于这两个阶段的详细指南: 一、组建项目团队团队角色与技能:选择的团队必须具备相应的技能、经验、知识去解释、设计和实施一个CMDB,以满足所......
  • 深入理解面向对象分析中的类图:构建清晰的系统蓝图
    标题:深入理解面向对象分析中的类图:构建清晰的系统蓝图摘要面向对象分析(Object-OrientedAnalysis,OOA)是软件开发中的关键过程,通过以对象为中心的方法来理解和建模系统。类图(ClassDiagram)是面向对象分析中最基础且重要的图形化工具,主要用于展示系统中的类及其关系,帮助开......
  • Tofu识别跟踪产品视频输入接口汇总
    网络视频输入视频输入默认支持网络RTSP协议视频,分辨率支持480P,720P,1080P,1440P等格式。目前仅Tofu3支持1440P格式的400万像素视频,可通过升级包支持,400万像素分辨率目前仅支持2560×1440。并行数字视频输入数字视频支持BT.656与BT.1120,对于BT.656协议已在《第三方热红外......
  • 实木家具鉴定标准表格;消费者在购买实木家具时,应提高警惕,注意识别是否存在“贴皮”或“
    实木家具鉴定标准表格项目具体内容鉴定标准注意事项1.木材种类检查家具所用木材的种类,是否符合实木家具要求。1.应为天然实木,不含人工合成材料。1.可通过木材切面、颜色、纹理等特点辨识木材种类。2.木材厚度与结构检查木材厚度是否符合设计要求,结构是否稳......