minst手写数字识别(带界面)

目录

  • minst手写数字识别(带界面)
  • 一、项目简介
  • 二、项目结构及环境
  • 三、网络结构介绍
  • 四、程序文件介绍
  • 五、使用介绍
  • 六、源代码获取

一、项目简介

1)概述:手写数字识别项目是深度学习入门的基础项目,本项目中采用自己搭建的四层神经网络实现对0-9十个数字的手写数字识别。准确率达95%以上。同时利用QT5书写了一个交互界面,用户直接利用鼠标在画板上进行数字书写即可完成数字识别,十分直观。

2)部分运行效果图:


二、项目结构及环境

提供项目全部源码,在普通电脑CPU/GPU上可以实时检测和识别
整个项目中,主要的文件内容有:

1)MINST文件夹:minst数据集文件
2)model_parameters文件夹:存放已经训练好的模型参数文件
3)image_processing.py文件:实现对输入图像的预处理
4)model.py文件:搭建好的卷积神经网络
5)number_recognition2.py文件:qt5界面文件
6)number_recognition2.ui文件:qt5界面源文件
7)number_recognition_run2_new.py文件:主运行文件
8)paint_board4.py文件:界面画板交互代码
9)requirement.txt文件:所需环境库文件

主要环境库:

kiwisolver==1.3.1
MarkupSafe==2.0.1
matplotlib==3.4.2
matplotlib-inline==0.1.2
mistune==0.8.4
nbclient==0.5.3
nbconvert==6.1.0
nbformat==5.1.3
nest-asyncio==1.5.1
notebook==6.4.0
numpy==1.21.0
packaging==21.0
pandocfilters==1.4.3
parso==0.8.2
pickleshare==0.7.5
Pillow==8.3.1
prometheus-client==0.11.0
prompt-toolkit==3.0.19
pycparser==2.20
Pygments==2.9.0
pyparsing==2.4.7
pyrsistent==0.18.0
python-dateutil==2.8.1
pywin32==301
pywinpty==1.1.3
pyzmq==22.1.0
qtconsole==5.1.1
QtPy==1.9.0
Send2Trash==1.7.1
six==1.16.0
terminado==0.10.1
testpath==0.5.0
torch==1.9.0+cu102
torchaudio==0.9.0
torchvision==0.10.0+cu102
tornado==6.1
traitlets==5.0.5
typing-extensions==3.10.0.0
wcwidth==0.2.5
webencodings==0.5.1
widgetsnbextension==3.5.1
zipp==3.5.0
PyQt5==5.12.3
PyQt5-sip==12.9.0
PyQt5-stubs==5.15.2.0

使用anaconda+pycharm的环境工具搭配更加方便,点击获取工具包:

https://mp.weixin.qq.com/s?__biz=MzAwOTc3NTg2MA==&mid=2247483657&idx=1&sn=e85ed4388d239fd312b417919132a249

三、网络结构介绍

model.py

import numpy as np
import torch
from PIL import Image
from torch import nn, optim
from torch.autograd import Variable
from torchvision import datasets, transforms# 定义网络结构
class Net(nn.Module):def __init__(self):super(Net, self).__init__()# Sequential表示在搭建网络模型中要执行的一系列的步骤# Dropout中,p=0.5表示50%的神经元不工作# layer3:输出层 一般输出层中不需要加Dropout# Conv2d Conv:卷积 2d:表示2维的卷积# nn.Conv2d的几个参数# 1:输入通道数:1表示黑白的图片 彩色的话就是3# 32:输出通道数:表示要生成多少个特征图# 5:是卷积核的大小,(5,5)表示是5*5的窗口。可以只写一个5# 1表示步长。步长默认值就是1# 2表示在padding外面填2圈0 这个相当于samepadding# nn.MaxPool2d的几个参数# 第一个2是池化的窗口的大小是2*2 第二个2表示步长为2self.conv1 = nn.Sequential(nn.Conv2d(1, 32, 5, 1, 2), nn.ReLU(), nn.MaxPool2d(2, 2))self.conv2 = nn.Sequential(nn.Conv2d(32, 64, 5, 1, 2), nn.ReLU(), nn.MaxPool2d(2, 2))self.fc1 = nn.Sequential(nn.Linear(64 * 7 * 7, 1000), nn.Dropout(p=0.5), nn.ReLU())self.fc2 = nn.Sequential(nn.Linear(1000, 10), nn.Softmax(dim=1))# dim=1代表对第一个维度,计算概率值# 因为batch = 64# 所以fc1输出的是(64,10)# 所以dim=1,表示对第二个维度进行softmax求值def forward(self, x):# ([64,1,28,28])变成2维的数据->(64,784) 全连接层做计算,必须是2维的数据# x = x.view(x.size()[0],-1)# 但是卷积只能对四维的数据进行计算 ([64,1,28,28])# 64表示批次的数量,1表示通道数 28表示长宽x = self.conv1(x)x = self.conv2(x)# 将原来x四维的数据,改变为2维的数据# (64,64,7,7)x = x.view(x.size()[0], -1)x = self.fc1(x)x = self.fc2(x)return xdef onehot_to_num(onehot:torch.Tensor):list1 = onehot.detach().numpy()list1 = list1[0]for index,value in enumerate(list1):if value > 0.5:return indexif __name__ == '__main__':the_model = Net()  # 定义模型the_model.load_state_dict(torch.load("model_parameters/parame"))  # 读取参数# image =im1 = Image.open('111.png').convert("L")im2 = im1.copy()im2.thumbnail((28,28))# im2.save('222.png')# print("im1的大小:",im1.size)# print("im2的大小:",im2.size)im2 = 255 - np.array(im2)# for i in im2:#     print(i)im2 = torch.Tensor(im2)im2 = im2.view(1,1,28,28)# im2 = Variable(im2)result = the_model(im2)print(result)print(onehot_to_num(result))

四、程序文件介绍

number_recognition2.py

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'number_recognition2.ui'
#
# Created by: PyQt5 UI code generator 5.12.3
#
# WARNING! All changes made in this file will be lost!from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from paint_board4 import Exampleclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(414, 330)self.lcdNumber = QtWidgets.QLCDNumber(Form)self.lcdNumber.setGeometry(QtCore.QRect(310, 70, 81, 41))self.lcdNumber.setObjectName("lcdNumber")self.label = QtWidgets.QLabel(Form)self.label.setGeometry(QtCore.QRect(310, 30, 81, 31))font = QtGui.QFont()font.setPointSize(15)self.label.setFont(font)self.label.setObjectName("label")self.pushButton = QtWidgets.QPushButton(Form)self.pushButton.setGeometry(QtCore.QRect(310, 150, 75, 41))self.pushButton.setObjectName("pushButton")self.widget = Example(Form)self.widget.setAttribute(Qt.WA_StyledBackground)self.widget.setGeometry(QtCore.QRect(20, 10, 280, 280))self.widget.setObjectName("widget")self.widget.setStyleSheet("border: 1px solid black;background-color: rgb(255,255, 255);")self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Form"))self.label.setText(_translate("Form", "识别结果"))self.pushButton.setText(_translate("Form", "清空画板"))

paint_board4.py

import sysimport torch
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtCore import Qt, QRect
from image_processing import convert_image_to_array
from model import Netclass Example(QWidget):def __init__(self,parent):super(Example, self).__init__(parent)# resize设置宽高,move设置位置self.parent = parentself.resize(400, 300)self.move(100, 100)self.setWindowTitle("简单的画板4.0")# setMouseTracking设置为False,否则不按下鼠标时也会跟踪鼠标事件self.setMouseTracking(False)'''要想将按住鼠标后移动的轨迹保留在窗体上需要一个列表来保存所有移动过的点'''self.pos_xy = []self.the_model = Net()  # 定义模型self.the_model.load_state_dict(torch.load("model_parameters/parame",map_location='cpu'))  # 读取参数print("模型加载完毕")def paintEvent(self, event):painter = QPainter()painter.begin(self)pen = QPen(Qt.black, 30, Qt.SolidLine)painter.setPen(pen)'''首先判断pos_xy列表中是不是至少有两个点了然后将pos_xy中第一个点赋值给point_start利用中间变量pos_tmp遍历整个pos_xy列表point_end = pos_tmp判断point_end是否是断点,如果是point_start赋值为断点continue判断point_start是否是断点,如果是point_start赋值为point_endcontinue画point_start到point_end之间的线point_start = point_end这样,不断地将相邻两个点之间画线,就能留下鼠标移动轨迹了'''if len(self.pos_xy) > 1:point_start = self.pos_xy[0]for pos_tmp in self.pos_xy:point_end = pos_tmpif point_end == (-1, -1):point_start = (-1, -1)continueif point_start == (-1, -1):point_start = point_endcontinuepainter.drawLine(point_start[0], point_start[1], point_end[0], point_end[1])point_start = point_endpainter.end()def mouseMoveEvent(self, event):"""按住鼠标移动事件:将当前点添加到pos_xy列表中调用update()函数在这里相当于调用paintEvent()函数每次update()时,之前调用的paintEvent()留下的痕迹都会清空"""# 中间变量pos_tmp提取当前点pos_tmp = (event.pos().x(), event.pos().y())# pos_tmp添加到self.pos_xy中self.pos_xy.append(pos_tmp)self.update()def mouseReleaseEvent(self, event):"""重写鼠标按住后松开的事件在每次松开后向pos_xy列表中添加一个断点(-1, -1)然后在绘画时判断一下是不是断点就行了是断点的话就跳过去,不与之前的连续"""pos_test = (-1, -1)self.pos_xy.append(pos_test)self.update()qRect = QRect(1,1,278,278)picture = self.grab(qRect)picture.save("./111.png","png")# print("保存成功!")picture_array = convert_image_to_array("./111.png")# print("转换成功")# print(picture_array)picture_array = torch.Tensor(picture_array)picture_array = picture_array.view(1, 1, 28, 28)result = self.the_model.forward(picture_array)result = self.onehot_to_num(result)print(result)self.parent.ui.lcdNumber.display(result)def onehot_to_num(self,onehot:torch.Tensor):list1 = onehot.detach().numpy()list1 = list1[0]for index, value in enumerate(list1):if value > 0.5:return indexif __name__ == "__main__":app = QApplication(sys.argv)pyqt_paint = Example(None)pyqt_paint.show()app.exec_()

五、使用介绍

直接运行number_recognition_run2_new.py

import sysfrom PyQt5.QtCore import Qt, QLineF, QObject
from PyQt5.QtGui import QPainter, QPen, QColorimport number_recognition2
from PyQt5.QtWidgets import QWidget, QApplicationclass MyWidget(QWidget):def __init__(self):super().__init__()self.ui = number_recognition2.Ui_Form()self.ui.setupUi(self)self.ui.pushButton.clicked.connect(self.clear)self.ui.lcdNumber.display(99999)def clear(self):self.ui.widget.pos_xy = []self.ui.lcdNumber.display(99999)self.ui.widget.update()# def pushButton_clickedif __name__ == '__main__':app = QApplication(sys.argv)myWindow = MyWidget()myWindow.show()app.exec_()

在空白画板上用鼠标进行书写即可

六、源代码获取

点击获取源代码
其他问题可留言,相互交流进步!

minst手写数字识别(带界面)相关推荐

  1. MATLAB实现基于BP神经网络的手写数字识别+GUI界面+mnist数据集测试

    文章目录 MATLAB实现基于BP神经网络的手写数字识别+GUI界面+mnist数据集测试 一.题目要求 二.完整的目录结构说明 三.Mnist数据集及数据格式转换 四.BP神经网络相关知识 4.1 ...

  2. 深度学习入门项目:PyTorch实现MINST手写数字识别

    完整代码下载[github地址]:https://github.com/lmn-ning/MNIST_PyTorch.git 目录 一.MNIST数据集介绍及下载地址 二.代码结构 三.代码 data ...

  3. Python手写数字识别+GUI界面+手写板设计

    摘要 手写数字识别是模式识别中一个非常重要和活跃的研究领域,数字识别也不是一项孤立的技术,他涉及的问题是模式识别的其他领域都无法回避的:应用上,作为一种信息处理手段,字符识别有广阔的应用背景和巨大的市 ...

  4. 全连接神经网络——MINST手写数字识别

    简介 本文构建了一个全连接神经网络(FCN),实现对MINST数据集手写数字的识别,没有借助任何深度学习算法库,从原理上理解手写数字识别的全过程,包括反向传播,梯度下降等.最终的代码总行数不超过200 ...

  5. Pytorch 学习 (一)Minst手写数字识别(含特定函数解析)

    目录 本人目前在跟随csdn博主 "K同学啊"进行365天深度学习训练营进行学习,这是打卡内容 也作为本人学习的记录. 一.准备部分 三.训练模型 四.正式训练 五.输出 MNIS ...

  6. matlab实现BP神经网络minst手写数字识别

    按照模式分类课本写的代码,如有错误欢迎指正! main.m %程序运行可能会需要3-5分钟的时间,请耐心等待. clear; %已对lms.mat进行随机打乱,并将Y由标量化为[1,10]矩阵形成da ...

  7. 手写数字识别问题(2)——利用matlab搭建GUI界面

    经过GUI的学习(详见博客:https://blog.csdn.net/didi_ya/article/details/105357279 ),小白逐渐了解了MATLAB的GUI界面及其搭建.下面是我 ...

  8. 机器学习笔记——从手写数字识别开始

    文章目录 前言 关于这篇博客(预计八月下旬全部完成) 关于项目实现 监督学习 ANN全连接神经网络的实现 1.总述 2.初始化 3.传播及损失 4.反向传播 决策树以及随机森林的实现 1.总述 2.单 ...

  9. 03_深度学习实现手写数字识别(python)

    本次项目采用了多种模型进行测试,并尝试策略来提升模型的泛化能力,最终取得了99.67%的准确率,并采用pyqt5来制作可视化GUI界面进行呈现.具体代码已经开源. 代码详情见附录 1简介 早在1998 ...

最新文章

  1. iOS开发8:使用Tool Bar切换视图
  2. LeetCode—笔记—51、N皇后——递归回溯,个人思路,简单易懂
  3. 科普丨深度学习硬件(GPU、FPGA、ASIC、DSP)
  4. 【 C 】高级指针话题之高级声明的演进
  5. 计算机多媒体技术广泛应用于各个领域,多媒体技术发展前景计算机现状及
  6. 耳朵经济在生活中的应用
  7. Android开发之跨进程通信-广播跨进程实现方法(附源码)
  8. java并发框架支持锁包括,jdk1.8锁
  9. raid卡组不同raid_RAID磁盘阵列是如何运作的?
  10. 如何通俗理解计算机视觉、计算机图形、图像处理之间的区别与联系
  11. linux禁用IPv6地址
  12. 每秒处理1000万用户请求…云上架构如何实现高性能和高可用
  13. 使用什么优化器_新的深度学习优化器Ranger:RAdam + LookAhead强强结合
  14. 【netty】Netty并发工具-Promise
  15. 王道机试指南读后总结-3
  16. Oracle Concepts Guide 中 Oracle 实例 和 数据库 【关系图】
  17. torch的maximum与max以及导出onnx
  18. Optimistic Concurrency VS. Pessimistic Concurrency Control
  19. 网页 从其他服务器 加载图片,实现网页图片的异步加载
  20. 推广域名被微信拦截怎么办 被拦截的域名怎么做跳转

热门文章

  1. Python课实例5:身体质量指数BMI
  2. 从功能测试到自动化测试,我在阿里的这7年
  3. ie浏览器下载rar文件,变成do文件
  4. 用python做数据处理怎么挣钱_个人利用python爬虫技术怎么挣钱
  5. 4-20mA无源两线制温度热电阻环路供电信号变送器
  6. The road you are trudging is bound for loneliness.(前行的道路注定孤独)
  7. 关于多部门协作完成项目使用过程中出现问题互相推卸责任的问题
  8. 程序员 520 表白方式
  9. 站群网站批量文章翻译发布插件
  10. 北京2022年最后一次快开始了,准备好了吗?