什么是手写数字识别?
手写数字识别是计算机识别手写数字的能力。这对手工制造的设备来说是一个难题,因为手写数字并不完美,且人们书写数字的方式多种多样。手写数字识别旨在解决这一问题,通过使用数字的图像来识别该图像中的数字。
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 深度学习项目进行手写数字识别
以下是实现手写数字识别项目的步骤:
- 导入库并加载数据集
首先,我们将导入训练模型所需的所有模块。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)
- 预处理数据
图像数据不能直接输入到模型中,因此我们需要执行一些操作以处理数据,使其准备好用于我们的神经网络。训练数据的维度为 (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')
- 创建模型
现在我们将在 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'])
- 训练模型
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")
- 评估模型
我们的数据集中有 10,000 张图像,这些图像将用于评估我们的模型表现如何。测试数据未参与数据的训练过程,因此对模型来说是新的数据。由于 MNIST 数据集非常平衡,我们模型的准确率可以达到约 99%。
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[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.xself.y = event.yr=8self.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 |