基于Keras的卷积神经网络手写数字识别

# -*- coding: utf-8 -*-
"""
Created on Sun Aug  1 16:22:47 2021

@author: Yang Hongyun
"""

#构建卷积神经网络模型代码

import tensorflow as tf
import keras               #keras框架导入
from keras.datasets import mnist  #数据集
from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPool2D,Input  #神经网络层导入
from keras.models import Sequential #模型类型:Sequential序列模型和Model函数模型

#加载mnist数据集,(x_train,y_train)为训练样本, (x_test,y_test)测试样本
(x_train,y_train),(x_test,y_test)=mnist.load_data()
#数据归一化处理,将0~255归一化至 0~1之间,使得数据乘法运算也在0~1之间
#若已知样本数量,可以将-1改为具体样本数量=60000
x_train=x_train.reshape(-1,28,28,1)/255.0  #注意是255.0,发生浮点数运算,不是255
#若已知测试样本数量,可以将-1改为样本数量=10000
x_test=x_test.reshape(-1,28,28,1)/255.0

#标签转one hot操作,将所有数据从1,2,3,4,...标注改编为
# 如 1 表达为【0,1,0,0,0,0,0,0,0,0】
# 如 5 表达为【0,0,0,0,0,1,0,0,0,0】
y_train=keras.utils.to_categorical(y_train,num_classes=10)  #10个类别
y_test =keras.utils.to_categorical(y_test,num_classes=10)

#搭建网络模型---全连接层
model=Sequential()  #模型实例化
#向模型添加CNN层,其中默认卷积核的内容是随机的,当然也可以手工设计卷积核内容
model.add(Conv2D(filters=32,#卷积核的数量,会影响计算量
                 kernel_size=(3,3), #卷积核大小,卷积运算后图像大小=28-3+1=26 
                 input_shape=(28,28,1), #样本尺寸,若为RGB图像=(28,28,3)
                 strides=(1,1),
                 activation='relu',
                 padding='valid' #有效尺寸,另一个参数'same'
                 ))
model.add(MaxPool2D(pool_size=(2,2)))
#数据打平,变成一列
model.add(Flatten())
#向模型中添加Dense层---分类层
model.add(Dense(units=32,activation='relu'))
#输出层,手写数字共0~9十个类别
model.add(Dense(units=10,activation='softmax'))
print(model.summary())#模型编译---训练设置
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
#启动训练
model.fit(
        x=x_train,
        y=y_train,
        batch_size=64,#每轮都是60000个样本,但不能将6万样本一次训练,那样所需内存过大,所以设置batch_size为每次训练样本数
        epochs=10,#训练多少轮次
        )
#模型测试
loss,acc=model.evaluate(x_test,y_test)
print(loss,acc)
#模型保存 --*.h5格式
model.save('mnistTrainOnCNN.h5')

#--------------------------------------------------------------------------------------------------------------------------#

#模型测试部分代码

import tkinter as tk
import tkinter.messagebox as tkmessagebox
import numpy as np
import tensorflow
from keras.models import load_model
from PIL import Image
class window(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        
        self.resizable(0, 0)
        self.title('手写数字识别系统')
        self.geometry('280x280+600+300')  #窗体大小和位置      
        self.canvas=tk.Canvas(self, width=280,height=280,background='black')      
        self.canvas.pack(fill = 'both',expand ='yes')
        self.canvas.bind('<B1-Motion>',self.on_move_press) 
        self.canvas.bind('<ButtonRelease-1>',self.on_button_release)
        self.r=5  #书写笔画的宽度
        self.data=np.zeros([280,280])   #画布图像数据的尺寸
    def on_move_press(self,event):                
        self.canvas.create_rectangle(event.x-self.r,event.y-self.r,event.x+self.r,event.y+self.r,fill='white',outline='',tag='c')
        #有笔画部分数据设为白色,像素值=255
        self.data[event.y-self.r:event.y+self.r,event.x-self.r:event.x+self.r]=255
    def on_button_release(self,event):
        self.data=np.matrix(self.data)  #数组转为矩阵形式
        img= Image.fromarray(np.uint8(self.data))  #格式化为PIL.Image形式
        img_array =img.resize((28,28))  #缩放到mnist数据集样本大小
        img_array= np.reshape(img_array,(28,28,1))#将二维矩阵转为一层的三维矩阵,如彩色图像,应为3层
#        #将数字图像矩阵数定义为1个样本并归一化
        img_array=img_array.reshape(1,28,28,1)/255.0
        #加载模型
        model=load_model('mnistTrainOnCNN.h5')
        #进行预测
        prediction=model.predict(img_array)
        result =tkmessagebox.askokcancel(title='识别结果',message='识别的数字是:'+str(np.argmax(prediction)))
        if(result==1):
            self.canvas.delete('c')
            self.data[:,:]=0
        return

if __name__=='__main__':
    w=window()
    w.mainloop()

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值