【机器学习实战入门】使用Python进行MNIST手写数字识别

在这里插入图片描述

什么是手写数字识别?

手写数字识别是计算机识别手写数字的能力。这对手工制造的设备来说是一个难题,因为手写数字并不完美,且人们书写数字的方式多种多样。手写数字识别旨在解决这一问题,通过使用数字的图像来识别该图像中的数字。
在这里插入图片描述

Python 深度学习项目的介绍

python 混合学习项目 - 手写数字识别

在本文中,我们将使用 MNIST 数据集实现一个手写数字识别应用程序。我们将使用一种特殊的深度神经网络,即卷积神经网络(Convolutional Neural Networks)。最终,我们将构建一个图形用户界面(GUI),您可以在其中手绘数字,并立即进行识别。

前提条件

这个有趣的 Python 项目要求您具备基本的 Python 编程知识、使用 Keras 库进行深度学习的知识以及使用 Tkinter 库构建 GUI 的能力。

使用以下命令安装此项目所需的所有库:

pip install numpy, tensorflow, keras, pillow

MNIST 数据集

这可能是机器学习和深度学习爱好者中最为流行的数据集之一。MNIST 数据集包含 60,000 张用于训练的手写数字图像(从零到九)和 10,000 张用于测试的图像。因此,MNIST 数据集有 10 个不同的类别。手写数字图像以 28×28 的矩阵形式表示,其中每个单元格包含一个灰度像素值。

下载项目完整源代码

链接: 使用Python进行MNIST手写数字识别 源代码与数据集 Python-Project-Handwritten-digit-recognizer

构建 Python 深度学习项目进行手写数字识别

以下是实现手写数字识别项目的步骤:

  1. 导入库并加载数据集
    首先,我们将导入训练模型所需的所有模块。Keras 库已经包含了一些数据集,MNIST 就是其中之一。因此,我们可以轻松地导入数据集并开始使用它。mnist.load_data() 方法会返回给我们训练数据、其标签以及测试数据和其标签。
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K
# 数据集,分为训练集和测试集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print(x_train.shape, y_train.shape)
  1. 预处理数据
    图像数据不能直接输入到模型中,因此我们需要执行一些操作以处理数据,使其准备好用于我们的神经网络。训练数据的维度为 (60000,28,28)。卷积神经网络(CNN)模型需要一个额外的维度,因此我们将矩阵重新调整为 (60000,28,28,1) 形状。
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
input_shape = (28, 28, 1)
# 将类别向量转换为二进制类别矩阵
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'training samples')
print(x_test.shape[0], 'test samples')
  1. 创建模型
    现在我们将在 Python 数据科学项目中创建我们的卷积神经网络(CNN)模型。CNN 模型通常包括卷积层和池化层,它更适合处理以网格结构表示的数据,这也是为什么 CNN 在图像分类任务中表现出色的原因。Dropout 层用于停用一些神经元,在训练过程中可以减少模型的过拟合。然后我们使用 Adadelta 优化器编译模型。
batch_size = 128
num_classes = 10
epochs = 10
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,optimizer=keras.optimizers.Adadelta(),metrics=['accuracy'])
  1. 训练模型
    Keras 的 model.fit() 函数将开始训练模型。它需要训练数据、验证数据、训练轮数和批次大小作为参数。

模型训练需要一些时间。训练完成后,我们将权重和模型定义保存在 ‘mnist.h5’ 文件中。

hist = model.fit(x_train, y_train,batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(x_test, y_test))
print("The model has successfully trained")
model.save('mnist.h5')
print("Saving the model as mnist.h5")
  1. 评估模型
    我们的数据集中有 10,000 张图像,这些图像将用于评估我们的模型表现如何。测试数据未参与数据的训练过程,因此对模型来说是新的数据。由于 MNIST 数据集非常平衡,我们模型的准确率可以达到约 99%。
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
  1. 创建 GUI 以预测数字
    为了构建 GUI,我们创建了一个新的文件,其中构建了一个交互窗口,用于在画布上绘制数字,并通过一个按钮识别数字。Tkinter 库包含在 Python 标准库中。我们创建了一个 predict_digit() 函数,该函数以图像作为输入,使用训练好的模型来预测数字。

然后我们创建了 App 类,该类负责构建我们应用程序的 GUI。我们创建了一个画布,可以在其中通过捕捉鼠标事件来绘制,通过一个按钮触发 predict_digit() 函数并显示结果。

以下是 gui_digit_recognizer.py 文件的完整代码:

from keras.models import load_model
from tkinter import *
import tkinter as tk
import win32gui
from PIL import ImageGrab, Image
import numpy as np
model = load_model('mnist.h5')
def predict_digit(img):
    # 将图像调整为 28x28 像素
    img = img.resize((28,28))
    # 将 RGB 转换为灰度
    img = img.convert('L')
    img = np.array(img)
    # 重新调整形状以支持模型输入并归一化
    img = img.reshape(1,28,28,1)
    img = img/255.0
    # 预测类别
    res = model.predict([img])[0]
    return np.argmax(res), max(res)
class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.x = self.y = 0
        # 创建元素
        self.canvas = tk.Canvas(self, width=300, height=300, bg = "white", cursor="cross")
        self.label = tk.Label(self, text="Thinking..", font=("Helvetica", 48))
        self.classify_btn = tk.Button(self, text = "Recognise", command =         self.classify_handwriting) 
        self.button_clear = tk.Button(self, text = "Clear", command = self.clear_all)
        # 网格结构
        self.canvas.grid(row=0, column=0, pady=2, sticky=W, )
        self.label.grid(row=0, column=1,pady=2, padx=2)
        self.classify_btn.grid(row=1, column=1, pady=2, padx=2)
        self.button_clear.grid(row=1, column=0, pady=2)
        # self.canvas.bind("<Motion>", self.start_pos)
        self.canvas.bind("<B1-Motion>", self.draw_lines)
    def clear_all(self):
        self.canvas.delete("all")
    def classify_handwriting(self):
        HWND = self.canvas.winfo_id() # 获取画布的句柄
        rect = win32gui.GetWindowRect(HWND) # 获取画布的坐标
        im = ImageGrab.grab(rect)
        digit, acc = predict_digit(im)
        self.label.configure(text= str(digit)+', '+ str(int(acc*100))+'%')
    def draw_lines(self, event):
        self.x = event.x
        self.y = event.y
        r=8
        self.canvas.create_oval(self.x-r, self.y-r, self.x + r, self.y + r, fill='black')
app = App()
mainloop()

界面截图:

在这里插入图片描述

  • python 机器学习项目输出数字 2
    在这里插入图片描述

  • python 机器学习项目输出数字 5

在这里插入图片描述

  • python 项目输出数字 6

总结

在本文中,我们成功构建了一个 Python 深度学习项目,实现了手写数字识别应用。我们构建并训练了一个卷积神经网络模型,该模型在图像分类任务中非常有效。随后,我们构建了一个图形用户界面(GUI),可以在其中绘制数字,然后分类数字并显示结果。

参考资料

资料名称链接
Keras 官方文档https://keras.io/
TensorFlow 深度学习教程https://tensorflow.google.cn/
MNIST 数据集官网http://yann.lecun.com/exdb/mnist/
Python Tkinter 教程https://docs.python.org/3/library/tkinter.html
手写数字识别综述https://zhuanlan.zhihu.com/p/35863468
深度学习入门https://www.deeplearning-book.org/
Convolutional Neural Networks (CNN) 简介https://www.cnblogs.com/zyg123/p/8561567.html
Python 图像处理库 Pillow 介绍https://pillow.readthedocs.io/en/stable/
手写数字识别系统实现http://www.cs.ubc.ca/~_written/yangzhang981/courses/532/2016/Handwriting-Recognition.pdf
深度学习框架 Keras 指南https://www.programcreek.com/python/example/54362/keras.models.Sequential
手写数字识别数据预处理https://www.datacamp.com/community/tutorials/mnist-python
Windows GUI 编程教程https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms632586.aspx
手写数字识别实际应用https://ieeexplore.ieee.org/document/8235104
卷积神经网络改进技巧https://towardsdatascience.com/a-keras-pipeline-for-image-classification-4a28f728750a
手写数字识别性能分析https://arxiv.org/abs/1707.09725
MNIST 数据集使用指南https://www.kaggle.com/c/digit-recognizer/data
posted @   爱上编程技术  阅读(24)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示