精华内容
下载资源
问答
  • 手写数字识别是模式识别中一个非常重要和活跃研究领域,数字识别也不是一项孤立技术,它所涉及问题是模式识别其他领域都无法回避;应用上,作为一种信息处理手段,字符识别有广阔应用背景和巨大市场...
  • 本文论述并设计实现了一个脱机自由手写数字识别系统。文中首先对待识别数字预处理进行了介绍,包括二值化、平滑滤波、规范化、细化等图像处理方法;其次,探讨了如何提取数字字符结构特征和笔划特征,并详细地...
  • 单文档程序,使用位图和模拟按钮。识别率达80%,并且经过并接,可以算是合格毕业论文,有需要话可以参考下,鉴于本科毕业论文,我只能把分弄高点啊!
  • 内容摘要:本文论述并设计实现了一个自由手写数字识别系统。文中首先对待识别数字预处理进行了介绍,包括二值化、噪声处理、图像分割、归一化、细化等图像处理方法;其次,探讨了数字字符特征向量提取;最后...

    内容摘要:本文论述并设计实现了一个自由手写体数字识别系统。文中首先对待识别数字的预处理进行了介绍,包括二值化、噪声处理、图像分割、归一化、细化等图像处理方法;其次,探讨了数字字符特征向量的提取;最后采用了bp神经网络算法,并以MATLAB作为编程工具实现了具有友好的图形用户界面的自由手写体数字识别系统。实验结果表明,本方法具有较高的识别率,并具有较好的抗噪性能。

    目 录

     

    内容摘要……...............................................................................................4

    关键字……………………………………………………………………...4

    Abstract……………………………………………………………………..5

    Keywords…………………………………………………………………...5

    第一章 绪论...6

    1.1  字符识别概述………………………………………………………..6

    1.2  数字识别研究的目的及意义………………………………………..6

    1.3  手写数字识别的典型应用…………………………………………..7

    1.4  国内外研究现状……………………………………………………..8

    1.5  手写体数字识别系统概述…………………………………………10

    1.6  文章结构……………………………………………………………11

    第二章  手写体数字识别中预处理技术...13

    2.1  图像灰度化…………………………………………………………13

    2.2  图像二值化…………………………………………………………14

    2.3  图像反色……………………………………………………………16

    2.4  图像去噪声…………………………………………………………16

    2.5  数字分割……………………………………………………………17

    2.6  数字归一化…………………………………………………………18

    2.7  数字细化……………………………………………………………21

    第三章 手写体数字识别中特征值提取技术...25

    3.1  特征提取概述………………………………………………………25

    3.2  手写体字符特征提取方法概述……………………………………27

    3.3  手写体数字识别中的结构特征提取………………………………29

    3.4  手写体数字识别中的统计特征提取……………………………….31

    第四章  人工神经网络分类器...32

    4.1  人工神经网络概述…………………………………………………32

    4.2  BP神经网络概述…………………………………………………..33

    4.3  本文的神经网络结构设计…………………………………………34

     

     

    第五章  系统实现与结果分析...39

    5.1  系统实现……………………………………………………………39

    5.1.1  系统实现环境...39

    5.1.2  系统处理流程图及主要工作...40

    5.1.3  系统界面...41

    5.2  结果分析……………………………………………………………..42

    第六章   结束语...43

    参考文献...44

    致谢...46

    点击下载


    展开全文
  • 在朋友的强烈建议下,写一篇关于利用CNN卷积神经网络实现基于MATLAB的手写数字识别系统的设计的博客。 一、关于卷积神经网络 关于卷积神经网络我写过一篇文章单独介绍,可以参考:手写数字识别问题(3)——详解卷积...

    在朋友的强烈建议下,写一篇关于利用CNN卷积神经网络实现基于MATLAB的手写数字识别系统的设计的博客。

    一、关于卷积神经网络

    关于卷积神经网络我写过一篇文章单独介绍,可以参考:手写数字识别问题(3)——详解卷积神经网络LeNet-5,这里就不进行重点介绍了。

    二、训练过程、准确率与GUI界面

    神经网络为卷积神经网络,分别是输入层、卷积层1、激活函数、池化层1、dropoutout层(主要防止过拟合)、卷积层2、激活函数、池化层2、dropoutout层(主要防止过拟合)、全连接层和输出层。
    其结构参数如下图所示:
    在这里插入图片描述

    一次的训练过程如下:
    在这里插入图片描述

    经过十次训练,测试集准确率为:99.26%,说明该神经网络具有良好的准确率。
    在这里插入图片描述

    最后搭建GUI界面对数字进行识别:
    原始GUI界面:
    在这里插入图片描述
    识别数字后的GUI界面:
    在这里插入图片描述

    三、代码实现

    有需要代码的可以添加微信联系(白嫖党请慎入)(备注:CNN)
    如果需要关于图像处理和神经网络方面的毕业设计指导,也可以添加微信(备注:XX毕业设计)
    在这里插入图片描述

    不过最后提一句,如果你想更轻松掌握深度学习与神经网络,建议还是利用python实现,因为python的编程语法更简洁明了,无论是TensorFlow,pytorch还是Keras。
    利用pytorch实现卷积神经网络Lenet-5可参考博客:卷积神经网络LeNet-5的pytorch代码实现

    展开全文
  • 本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统。这是本人本科毕业论文课题,当然,这个也是机器学习基本问题。本博文不会以论文形式展现,而是以编程实战完成...
  • 本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统。这是本人本科毕业论文课题,当然,这个也是机器学习基本问题。本博文不会以论文形式展现,而是以编程实战完成...

    转载自:https://blog.csdn.net/louishao/article/details/60867339###

    手写数字识别算法的设计与实现

    本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统。这是本人的本科毕业论文课题,当然,这个也是机器学习的基本问题。本博文不会以论文的形式展现,而是以编程实战完成机器学习项目的角度去描述。

    项目要求:本文主要解决的问题是手写数字识别,最终要完成一个识别系统。

    设计识别率高的算法,实现快速识别的系统。
    1 LeNet-5模型的介绍

    本文实现手写数字识别,使用的是卷积神经网络,建模思想来自LeNet-5,如下图所示:
    在这里插入图片描述
    这是原始的应用于手写数字识别的网络,我认为这也是最简单的深度网络。

    LeNet-5不包括输入,一共7层,较低层由卷积层和最大池化层交替构成,更高层则是全连接和高斯连接。

    LeNet-5的输入与BP神经网路的不一样。这里假设图像是黑白的,那么LeNet-5的输入是一个32*32的二维矩阵。同时,输入与下一层并不是全连接的,而是进行稀疏连接。本层每个神经元的输入来自于前一层神经元的局部区域(5×5),卷积核对原始图像卷积的结果加上相应的阈值,得出的结果再经过激活函数处理,输出即形成卷积层(C层)。卷积层中的每个特征映射都各自共享权重和阈值,这样能大大减少训练开销。降采样层(S层)为减少数据量同时保存有用信息,进行亚抽样。

    第一个卷积层(C1层)由6个特征映射构成,每个特征映射是一个28×28的神经元阵列,其中每个神经元负责从5×5的区域通过卷积滤波器提取局部特征。一般情况下,滤波器数量越多,就会得出越多的特征映射,反映越多的原始图像的特征。本层训练参数共6×(5×5+1)=156个,每个像素点都是由上层5×5=25个像素点和1个阈值连接计算所得,共28×28×156=122304个连接。

    S2层是对应上述6个特征映射的降采样层(pooling层)。pooling层的实现方法有两种,分别是max-pooling和mean-pooling,LeNet-5采用的是mean-pooling,即取n×n区域内像素的均值。C1通过2×2的窗口区域像素求均值再加上本层的阈值,然后经过激活函数的处理,得到S2层。pooling的实现,在保存图片信息的基础上,减少了权重参数,降低了计算成本,还能控制过拟合。本层学习参数共有1*6+6=12个,S2中的每个像素都与C1层中的2×2个像素和1个阈值相连,共6×(2×2+1)×14×14=5880个连接。

    S2层和C3层的连接比较复杂。C3卷积层是由16个大小为10×10的特征映射组成的,当中的每个特征映射与S2层的若干个特征映射的局部感受野(大小为5×5)相连。其中,前6个特征映射与S2层连续3个特征映射相连,后面接着的6个映射与S2层的连续的4个特征映射相连,然后的3个特征映射与S2层不连续的4个特征映射相连,最后一个映射与S2层的所有特征映射相连。此处卷积核大小为5×5,所以学习参数共有6×(3×5×5+1)+9×(4×5×5+1)+1×(6×5×5+1)=1516个参数。而图像大小为28×28,因此共有151600个连接。

    S4层是对C3层进行的降采样,与S2同理,学习参数有16×1+16=32个,同时共有16×(2×2+1)×5×5=2000个连接。

    C5层是由120个大小为1×1的特征映射组成的卷积层,而且S4层与C5层是全连接的,因此学习参数总个数为120×(16×25+1)=48120个。

    F6是与C5全连接的84个神经元,所以共有84×(120+1)=10164个学习参数。

    卷积神经网络通过通过稀疏连接和共享权重和阈值,大大减少了计算的开销,同时,pooling的实现,一定程度上减少了过拟合问题的出现,非常适合用于图像的处理和识别。
    2 手写数字识别算法模型的构建
    2.1 各层设计

    有了第一节的基础知识,在这基础上,进行完善和改进。

    输入层设计
    

    输入为28×28的矩阵,而不是向量。

    激活函数的选取
    

    Sigmoid函数具有光滑性、鲁棒性和其导数可用自身表示的优点,但其运算涉及指数运算,反向传播求误差梯度时,求导又涉及乘除运算,计算量相对较大。同时,针对本文构建的含有两层卷积层和降采样层,由于sgmoid函数自身的特性,在反向传播时,很容易出现梯度消失的情况,从而难以完成网络的训练。因此,本文设计的网络使用ReLU函数作为激活函数。

    ReLU的表达式:
    在这里插入图片描述

    卷积层设计
    

    本文设计卷积神经网络采取的是离散卷积,卷积步长为1,即水平和垂直方向每次运算完,移动一个像素。卷积核大小为5×5。

    降采样层
    

    本文降采样层的pooling方式是max-pooling,大小为2×2。

    输出层设计
    

    输出层设置为10个神经网络节点。数字0~9的目标向量如下表所示:
    在这里插入图片描述
    2.2 网络模型的总体结构

    在这里插入图片描述
    其实,本文网络的构建,参考自TensorFlow的手写数字识别的官方教程的,读者有兴趣也可以详细阅读。
    2.3 编程实现算法

    本文使用Python,调用TensorFlow的api完成手写数字识别的算法。
    注:本文程序运行环境是:Win10,python3.5.2。当然,也可以在Linux下运行,由于TensorFlow对py2和py3兼容得比较好,在Linux下可以在python2.7中运行。

    #!/usr/bin/env python2
    # -*- coding: utf-8 -*-
    """
    Created on Fri Feb 17 19:50:49 2017
    
    @author: Yonghao Huang
    """
    
    #import modules
    import numpy as np
    import matplotlib.pyplot as plt
    import tensorflow as tf
    import time
    from datetime import timedelta
    import math
    from tensorflow.examples.tutorials.mnist import input_data
    
    
    def new_weights(shape):
        return tf.Variable(tf.truncated_normal(shape,stddev=0.05))
    def new_biases(length):
        return tf.Variable(tf.constant(0.1,shape=length))
    def conv2d(x,W):
        return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')
    def max_pool_2x2(inputx):
        return tf.nn.max_pool(inputx,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
    
    #import data
    data = input_data.read_data_sets("./data", one_hot=True)  # one_hot means [0 0 1 0 0 0 0 0 0 0] stands for 2
    
    print("Size of:")
    print("--Training-set:\t\t{}".format(len(data.train.labels)))
    print("--Testing-set:\t\t{}".format(len(data.test.labels)))
    print("--Validation-set:\t\t{}".format(len(data.validation.labels)))
    data.test.cls = np.argmax(data.test.labels,axis=1)   # show the real test labels:  [7 2 1 ..., 4 5 6], 10000values
    
    x = tf.placeholder("float",shape=[None,784],name='x')
    x_image = tf.reshape(x,[-1,28,28,1])
    
    y_true = tf.placeholder("float",shape=[None,10],name='y_true')
    y_true_cls = tf.argmax(y_true,dimension=1)
    # Conv 1
    layer_conv1 = {"weights":new_weights([5,5,1,32]),
                   "biases":new_biases([32])}
    h_conv1 = tf.nn.relu(conv2d(x_image,layer_conv1["weights"])+layer_conv1["biases"])
    h_pool1 = max_pool_2x2(h_conv1)
    # Conv 2
    layer_conv2 = {"weights":new_weights([5,5,32,64]),
                   "biases":new_biases([64])}
    h_conv2 = tf.nn.relu(conv2d(h_pool1,layer_conv2["weights"])+layer_conv2["biases"])
    h_pool2 = max_pool_2x2(h_conv2)
    # Full-connected layer 1
    fc1_layer = {"weights":new_weights([7*7*64,1024]),
                "biases":new_biases([1024])}
    h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,fc1_layer["weights"])+fc1_layer["biases"])
    # Droupout Layer
    keep_prob = tf.placeholder("float")
    h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)
    # Full-connected layer 2
    fc2_layer = {"weights":new_weights([1024,10]),
                 "biases":new_weights([10])}
    # Predicted class
    y_pred = tf.nn.softmax(tf.matmul(h_fc1_drop,fc2_layer["weights"])+fc2_layer["biases"])  # The output is like [0 0 1 0 0 0 0 0 0 0]
    y_pred_cls = tf.argmax(y_pred,dimension=1)  # Show the real predict number like '2'
    # cost function to be optimized
    cross_entropy = -tf.reduce_mean(y_true*tf.log(y_pred))
    optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(cross_entropy)
    # Performance Measures
    correct_prediction = tf.equal(y_pred_cls,y_true_cls)
    accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float"))
    with tf.Session() as sess:
        init = tf.global_variables_initializer()
        sess.run(init)
        train_batch_size = 50
        def optimize(num_iterations):
            total_iterations=0
            start_time = time.time()
            for i in range(total_iterations,total_iterations+num_iterations):
                x_batch,y_true_batch = data.train.next_batch(train_batch_size)
                feed_dict_train_op = {x:x_batch,y_true:y_true_batch,keep_prob:0.5}
                feed_dict_train = {x:x_batch,y_true:y_true_batch,keep_prob:1.0}
                sess.run(optimizer,feed_dict=feed_dict_train_op)
                # Print status every 100 iterations.
                if i%100==0:
                    # Calculate the accuracy on the training-set.
                    acc = sess.run(accuracy,feed_dict=feed_dict_train)
                    # Message for printing.
                    msg = "Optimization Iteration:{0:>6}, Training Accuracy: {1:>6.1%}"
                    # Print it.
                    print(msg.format(i+1,acc))
            # Update the total number of iterations performed
            total_iterations += num_iterations
            # Ending time
            end_time = time.time()
            # Difference between start and end_times.
            time_dif = end_time-start_time
            # Print the time-usage
            print("Time usage:"+str(timedelta(seconds=int(round(time_dif)))))
        test_batch_size = 256
        def print_test_accuracy():
            # Number of images in the test-set.
            num_test = len(data.test.images)
            cls_pred = np.zeros(shape=num_test,dtype=np.int)
            i = 0
            while i < num_test:
                # The ending index for the next batch is denoted j.
                j = min(i+test_batch_size,num_test)
                # Get the images from the test-set between index i and j
                images = data.test.images[i:j, :]
                # Get the associated labels
                labels = data.test.labels[i:j, :]
                # Create a feed-dict with these images and labels.
                feed_dict={x:images,y_true:labels,keep_prob:1.0}
                # Calculate the predicted class using Tensorflow.
                cls_pred[i:j] = sess.run(y_pred_cls,feed_dict=feed_dict)
                # Set the start-index for the next batch to the
                # end-index of the current batch
                i = j
            cls_true = data.test.cls
            correct = (cls_true==cls_pred)
            correct_sum = correct.sum()
            acc = float(correct_sum) / num_test
            # Print the accuracy
            msg = "Accuracy on Test-Set: {0:.1%} ({1}/{2})"
            print(msg.format(acc,correct_sum,num_test))
        # Performance after 10000 optimization iterations
    
    

    运行结果显示:测试集中准确率大概为99.2%。
    我还写了一些辅助函数,可以查看部分识别错误的图片,
    在这里插入图片描述
    还可以查看混淆矩阵,
    在这里插入图片描述
    2.3 实现手写识别系统

    最后,将训练好的参数保存,封装进一个GUI界面中,形成一个手写识别系统。
    在这里插入图片描述
    系统中还添加了一点图像预处理的操作,比如灰度化,图像信息的归一化等,更贴近实际应用。
    系统可进行快速识别,如下图:
    在这里插入图片描述
    3 总结

    本文实现的系统其实是基于卷积神经网络的手写数字识别系统。该系统能快速实现手写数字识别,成功识别率高。缺点:只能正确识别单个数字,图像预处理还不够,没有进行图像分割,读者也可以自行添加,进行完善。
    4 收获

    本人之前的本科期间,虽然努力学习高数、线性代数和概率论,但是没有认真学习过机器学习,本人是2017年才开始系统学习机器学习相关知识,而且本科毕业论文也选择了相关的课题,虽然比较基础,但是认真完成后,有一种学以致用的满足感,同时也激励着我进行更深入的理论学习和实践探讨,与所有读者共勉。

    ==================================

    2018年5月13日更新

    以上是基本网络的设计与基本的实现,可满足入门学习。

    相关链接:

    ========================================

    2018年6月6日更新更新!!
    python(TensorFlow)实现手写字符识别

    此处的“手写字符”,其实指的是notMNIST数据库中的手写字符,其实和MNIST数据库是一样的。这里实现手写字符识别,主要是展示TensorFlow框架的可拓展性很强,具体来说,就是可以通过改动少部分的代码,从而实现一个新的识别功能。

    NotMnist数据库

    这个数据库和MNIST数据库基本一样,只是把10个数字换成了10个字母,即:A,B,C,D,E,F,G,H,I,J,K
    当然,这个数据库的识别难度大一些,因为数据噪声更多一些,详情读者可以搜一搜了解一下。
    实战

    将NotMNIST数据库下载以后,放在本博文上述的网络中,基本不需要修改代码,直接训练,即可得到一个能识别字符的网络模型。

    最后在测试集中的准确率,比MNIST的会低一些,大概为96%左右。

    本文也将训练好的网络模型封装在和上述系统相似的GUI系统中,

    [外链图片转存失败(img-k7xPyAio-1564543116627)(https://i.imgur.com/59M3NlD.png)]

    识别效果还可以!

    同样,将卷积卷积层可视化。

    [外链图片转存失败(img-tIWWgZB9-1564543116629)(https://i.imgur.com/4awe7NY.png)]
    结语

    TensorFlow框架可拓展性很强,只要设计好了网络,就能很容易的实现出来;同时,使用基本的CNN识别整体架构也是大同小异的,很多识别任务是通用的。当然,在具体的实践中需要得到接近完美的效果,还是要下很大功夫的!努力学习吧,加油!
    (如果你/您有什么有趣的想法,可以在下面留言,如果我也感兴趣同时又有时间的话,我会尝试做一做,_)
    ————————————————
    声明:本文为转载文章,如侵则删
    原文链接:https://blog.csdn.net/louishao/article/details/60867339

    展开全文
  • 手写数字识别系统 基于python

    千次阅读 2019-12-31 17:53:56
    本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统。文中首先对如何对手写数字图像获取进行了介绍;其次,对待手写数字图片预处理进行了介绍,包括二值化、高斯...

    环境基于Python3.6和Tensorflow框架 实现手写数字识别系统
    本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统。文中首先对如何对手写数字图像的获取进行了介绍;其次,对待手写数字图片的预处理的进行了介绍,包括二值化、高斯滤波、膨胀、腐蚀等图像处理方法,图片的预处理是利用opencv和PIL实现的;之后,探讨了读取MNIST训练数据集数据与标签,设置CNN神经网络参数 ,归一化数据集标签并训练CNN神经网络;最后GUI界面使用PyQt5,该识别器可以实时识别从GUI(图形用户界面)中画出的数字图片,利用截图的方式存储图片,并对图片进行预处理,进行界面分割成多个区域分别进行CNN识别,最终以一图一数字的形式组合返回至前端的手写数字识别系统。实验结果表明,本方法具有较高的识别率,并具有较好的抗噪性能。
    系统组成
    (1)获取手写数字图像:用户使用鼠标在所开发系统的手写面板上书写多个数字。
    (2)手写数字图像预处理:对手写数字图像进行图像灰度化、图像二值化、去噪(干扰)等操作。
    (3)CNN神经网络训练:读取MNIST训练数据集数据与标签,设置CNN神经网络参数(隐藏层层数、迭代次数、激活函数等),归一化数据集标签并训练CNN神经网络。
    (4)手写数字图像识别:利用训练神经网络得到的权重信息测试手写数字识别功能。
    开发环境:Windows 10 +python3.6 +tensorflow框架
    MNSIT数据集
    MNIST 数据集来自美国国家标准与技术研究所National Institute of Standards and Technology (NIST)。训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员。 测试集(test set) 也是同样比例的手写数字数据。它是一个计算机视觉数据集,它包含70000张手写数字的灰度图片,其中每一张图片包含 28 X 28 个像素点。每一张图片都有对应的标签,也就是图片对应的数字。数据集被分成两部分:60000 行的训练数据集(mnist.train)和10000行的测试数据集(mnist.test)。
    其中:60000 行的训练集分拆为 55000 行的训练集和 5000 行的验证集。60000行的训练数据集是一个形状为 [60000, 784]的张量,第一个维度数字用来索引图片,第二个维度数字用来索引每张图片中的像素点。在此张量里的每一个元素,都表示某张图片里的某个像素的强度值,值介于 0 和 1 之间。60000 行的训练数据集标签是介于 0 到 9 的数字,用来描述给定图片里表示的数字。称为 “one-hot vectors”。一个 one-hot向量除了某一位的数字是 1 以外其余各维度数字都是 0。如标签 0 将表示成 ( [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] )。因此,其标签是一个 [60000, 10] 的数字矩阵。
    [link]http://www.tensorfly.cn/tfdoc/tutorials/deep_cnn.html
    CNN神经网络
    卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一 。卷积神经网络具有表征学习(representation learning)能力,能够按其阶层结构对输入信息进行平移不变分类(shift-invariant classification,因此也被称为“平移不变人工神经网络(Shift-Invariant Artificial Neural Networks, SIANN)”。
    对卷积神经网络的研究始于二十世纪80至90年代,时间延迟网络和LeNet-5是最早出现的卷积神经网络 ;在二十一世纪后,随着深度学习理论的提出和数值计算设备的改进,卷积神经网络得到了快速发展,并被应用于计算机视觉、自然语言处理等领域 。
    卷积神经网络仿造生物的视知觉(visual perception)机制构建,可以进行监督学习和非监督学习,其隐含层内的卷积核参数共享和层间连接的稀疏性使得卷积神经网络能够以较小的计算量对格点化(grid-like topo-logy)特征,例如像素和音频进行学习、有稳定的效果且对数据没有额外的特征工程(feature engineering)要求 。
    [link]https://baike.baidu.com/item/卷积神经网络/17541100?fr=aladdin
    CNN神经网络训练模块程序实现

    from tensorflow.examples.tutorials.mnist import input_data
    import tensorflow.contrib.slim as slim
    import matplotlib.pyplot as plt
    import tensorflow as tf
    #调用第三方库
    # ----------------------------------------------------------------------------------------------------------------------
    mnist = input_data.read_data_sets('MNIST_data',one_hot=True)# 第一次运行会自动下载到代码所在的路径下
    # MNIST_data 是保存的文件夹的名称
    sess = tf.InteractiveSession()
    # ----------------------------------------------------------------------------------------------------------------------
    def build_graph():
        keep_prob_1 = tf.placeholder(dtype=tf.float32, shape=[], name='keep_prob_1')
        keep_prob_2 = tf.placeholder(dtype=tf.float32, shape=[], name='keep_prob_2')
        keep_prob_3 = tf.placeholder(dtype=tf.float32, shape=[], name='keep_prob_3')
        # 输入的数据 每张图片的大小是 28 * 28
        # 方便矩阵乘法处理
        x = tf.placeholder(tf.float32, shape=[None, 784])
        y_ = tf.placeholder(tf.float32, shape=[None, 10])
    
        x_image = tf.reshape(x, [-1, 28, 28, 1]) # 将输入tensor x调整成为28*28的矩阵形式
        # 第一个卷积层 32个卷积核
        h_conv1 = slim.conv2d(x_image, 32, [3, 3], 1, padding='SAME', activation_fn=tf.nn.relu) # 进行卷积操作W*X+b,得到线性变    化结果,在利用Tensoflow的relu规则进行非线性映射,得出卷积结果h_convi
        # 第二个卷积层 32个卷积核
        h_conv2 = slim.conv2d(h_conv1, 32, [3, 3], 1, padding='SAME', activation_fn=tf.nn.relu)
        # 第二个池化层
        h_pool1 = slim.max_pool2d(h_conv2, [2, 2], [2, 2], padding='SAME') # 采用了最大池化方法,其中ksize表示取样池的大小,strides表示步长,padding表示边缘补齐方法,SAME方式会在图片边缘补0,补齐边缘像素为1,最终得出池化结果h_pool1
        # 第三个卷积层 64个卷积核
        h_conv3 = slim.conv2d(slim.dropout(h_pool1, keep_prob_1), 64, [3, 3], 1, padding='SAME', activation_fn=tf.nn.relu) # 卷积层2的输入为32张特征映射图,有64个卷积核,最终将输出64个特征映射图 线性变化的结果
        # 第四个卷积层 64个卷积核
        h_conv4 = slim.conv2d(h_conv3, 64, [3, 3], 1, padding='SAME', activation_fn=tf.nn.relu) # 非线性变化的结果
        # 第二个池化层
        h_pool2 = slim.max_pool2d(h_conv4, [2, 2], [2, 2], padding='SAME')
        # 把矩阵flattern成一维的
        flatten = slim.flatten(h_pool2)
        # 第一个全连接层
        h_fc1 = slim.fully_connected(slim.dropout(flatten, keep_prob_2), 256, activation_fn=tf.nn.relu) # 全连接层设有256个神经元,本层的神经元数需要根据经验和实验结果进行反复调参确定。
        # 第二个全连接层,输出为10个类别
        y_conv = slim.fully_connected(slim.dropout(h_fc1, keep_prob_3), 10, activation_fn=None) #输出层为10维的向量
        """
        这里我们定义的神经网络包括三个卷积层和两个全连接层,每个卷积层紧跟一个池化层。输入值的维度是batch_sizex784,代表batch_size个图片,每个图片大小是28x28,转换成一维的数据就是784。输出层维度是batch_sizex10,每一项是一个1x10个数组,代表一张图片属于0 - 9
        每个数字的概率,最大的概率对应的数字就是分类的结果数字。
        三个卷积层共享同样的padding、激活函数、Batch
        Normalization方法,所以我们提出来放到arg_scope里面。
        第一个卷积层有32个卷积核,代表一张原始输入图片经过该卷积层会生成32张新的图片。第二层32个卷积核,代表在这一层每张输入的图片会生成32张新的图片,
        依次类推。接下来是两个全连接层,为了将卷积层的输出接入到全连接层,
        需要通过slim.flatten函数将卷积和池化后的特征摊平后输入全连接层。第一个全连接层共256个节点,将数据映射到256个节点;第二个全连接层将这256个节点映射到最终10个节点上,代表10个类别的结果。
       [link]:https: // www.jianshu.com / p / c4a7eeff7e9f
        """
        predict = tf.argmax(y_conv, 1)
        #交叉熵
        '''训练和评估模型
        为了训练我们的模型,我们首先需要定义损失函数(loss function),然后尽量最小化这个指标。这里使用的损失函数是
        "交叉熵"(cross - entropy)。交叉熵产生于信息论里面的信息压缩编码技术,但是它后来演变成为从博弈论到机器学习等其他领域里的重要技术手段。它的定义如下:
        计算交叉熵后,就可以使用梯度下降来优化参数。由于前面已经部署好网络结构,所以TensorFlow可以使用反向传播算法计算梯度,自动地优化参数,直到交叉熵最小。
        TensorFlow提供了多种优化器,这里选择更加复杂的Adam优化器来做梯度最速下降,学习率0.0001。每次训练随机选择50个样本,加快训练速度,每轮训练结束后,计算预测准确度。
        '''
        cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))#类别预测与损失函数    softmax logdir指定了checkpoint和event文件保存的目录
        train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)#训练模型
        correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))#评估模型
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))# 精确值
        '''
        loss 函数定义了一个我们想要优化的量。对于分类问题,loss 一般是正确的类别分布(true distribution)和预测的类别分布(predicted probability distribution across classes)之间的交叉熵(cross entropy)。对于回归问题,loss 一般是 预测值和真实值之间差值的平方和。
        '''
        return {
            'x': x,
            'y_': y_,
            'keep_prob_1': keep_prob_1,
            'keep_prob_2': keep_prob_2,
            'keep_prob_3': keep_prob_3,
            'loss': cross_entropy,
            'accuracy': accuracy,
            'train_step': train_step,
            'y_conv': y_conv,
            'predict': predict,
        }
    # ----------------------------------------------------------------------------------------------------------------------
    def train():
        with tf.Session() as sess:
            graph = build_graph()
            sess.run(tf.global_variables_initializer())# 对于每一轮训练
            saver = tf.train.Saver()
            STEP = []
            ACCURACY = []
            LOSS = []
            # 在会话中执行网络定义的运算
            for i in range(4001):#4001次训练
                batch = mnist.train.next_batch(30)
                sess.run(graph['train_step'], feed_dict={graph['x']: batch[0], graph['y_']: batch[1], graph['keep_prob_1']: 0.25, graph['keep_prob_2']: 0.5, graph['keep_prob_3']: 0.5})
                if i % 200 == 0:#每200次迭代输出一次
                    train_accuracy = sess.run(graph['accuracy'], feed_dict={graph['x']: batch[0], graph['y_']: batch[1], graph['keep_prob_1']: 1.0, graph['keep_prob_2']: 1.0, graph['keep_prob_3']: 1.0})
                    loss = sess.run(graph['loss'], feed_dict={graph['x']: batch[0], graph['y_']: batch[1], graph['keep_prob_1']: 1.0, graph['keep_prob_2']: 1.0, graph['keep_prob_3']: 1.0})
                    print("step %d, loss %g, training accuracy %g" % (i, loss, train_accuracy))
                    STEP.append(i)
                    ACCURACY.append(train_accuracy)
                    LOSS.append(loss)
                if i % 1000 == 0 and i > 0:
                    saver.save(sess, './model.ckpt')#保存模型 ckpt文件是二进制文件,保存了所有的weights、biases、gradients等变量。在tensorflow 0.11之前,保存在.ckpt文件中
        plt.plot(STEP, ACCURACY)
        plt.plot(STEP, LOSS)
        plt.show()
    # ----------------------------------------------------------------------------------------------------------------------
    train()
    # ----------------------------------------------------------------------------------------------------------------------
    #初学者 请多提意见  QQ:421065484
    

    ###训练输出的结果
    在这里插入图片描述
    在这里插入图片描述
    鼠标轨迹的获取

    def paintEvent(self, event):  # paintEvent()函数是QWidget类中的虚函数,用于ui的绘制#重写重绘事件处理函数实现绘图
        painter = QPainter(self)
        # 绘图事件
        # 绘图时必须使用QPainter的实例,此处为__painter
        # 绘图在begin()函数与end()函数间进行
        # begin(param)的参数要指定绘图设备,即把图画在哪里
        # drawPixmap用于绘制QPixmap类型的对象
        self.painter.begin(self)                    
        self.painter.drawPixmap(0, 0, self.board)  # 0,0为绘图的左上角起点的坐标,__board即要绘制的图
        self.painter.end()                          
        
    def mousePressEvent(self, event):  # 鼠标按下时,获取鼠标的当前位置保存为上一次位置
        self.lastPos = event.pos()  # 上一次鼠标位置
    
    def mouseMoveEvent(self, event):                
        self.currentPos = event.pos()  # 当前的鼠标位置
        self.painter.begin(self.board)              
        self.painter.setPen(QPen(self.penColor, self.thickness))  # 默认画笔粗细为10xp #设置默认画笔颜色为黑色
        self.painter.drawLine(self.lastPos, self.currentPos)  # 绘制范围
        self.painter.end()                                       
        self.lastPos = self.currentPos                           
        self.update() 
    

    *图像预处理
    图像处理中,最基本的就是色彩空间的转换。一般而言,我们的图像都是 RGB 色彩空间的,但在图像识别当中,我们可能需要转换图像到灰度图、二值图等不同的色彩空间。PIL 在这方面也提供了极完备的支持。

    def measure(image):
        blur = cv.GaussianBlur(image, (5, 5), 0)#使用高斯滤波器模糊图像,该函数将源图像与指定的高斯核进行卷积,支持就地过滤。
        gray = cv.cvtColor(blur, cv.COLOR_RGB2GRAY)#转换成灰度图
        _, out = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)#对图像二值化 threshold_type可以使用CV_THRESH_OTSU类型,这样该函数就会使用大律法OTSU得到的全局自适应阈值来进行二值化图片,而参数中的threshold不再起作用。
        ret, thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)#cv.THRESH_BINARY_INV 参数取反 thresh:閾值。 threshold_type –对图像取阈值的方法
        kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))#函数getStructuringElement,可以获取常用的结构元素的形状:矩形(包括线形)、椭圆(包括圆形)及十字形。
        erode = cv.dilate(thresh, kernel)#腐蚀
        #腐蚀后的图像,只检测最外面的轮廓,压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
        #cvFindContours将图片中识别到的轮廓返回给contours变量,contours是一个list类型数据,里面存放了识别到的所有轮廓
        contours, hierarchy = cv.findContours(erode, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)#用cvFindContours获取轮廓
        #将轮廓画入开始的image图像并显示
    

    GUI界面
    在这里插入图片描述

    展开全文
  • 手写数字识别问题(5)——完结

    千次阅读 2020-06-22 15:54:29
    经过接近15周艰苦努力,毕业设计(基于MATLAB的手写数字识别系统)已经完结。 设计过程中遇到部分问题可查阅博客: 手写数字识别问题(1)——关于MNIST数据集 手写数字识别问题(2)——利用MATLAB搭建GUI界面...
  • 本书直击当今研究热点,选择有代表性专题项目,详细介绍了手写数字识别、邮政编码识别、汽车牌照号码识别、印刷体汉字识别、一维条形码识别、人脸识别、虹膜识别、指纹识别八个应用项目的实现方法。同时,针对每一...
  • 3.2 基于Bayes的手写数字识别系统的设计 69 3.3 基于决策树的地理图片纹理分类软件设计 77 3.4 基于KNN的纹理分类系统的软件设计 88 3.5 基于类条件概率密度的视频移动目标跟踪系统设计 91 第4章 几何分类器 94 ...
  • 再加上用于服务器群组应用负载均衡ServerIron系列交换机,以及能保证线速网络流量监控安全sFlow(RFC3176)技术,从而构成了从边缘到核心完整解决方案,完全满足了会展中心对于网络设计在高性能,数据、语音...
  • 第9章 离散Hopfield神经网络联想记忆——数字识别 第10章 离散Hopfield神经网络分类——高校科研能力评价 第11章 连续Hopfield神经网络优化——旅行商问题优化计算 第12章 初始SVM分类回归 第13章 LIBSVM...
  • 第9章 离散Hopfield神经网络联想记忆——数字识别 第10章 离散Hopfield神经网络分类——高校科研能力评价 第11章 连续Hopfield神经网络优化——旅行商问题优化计算 第12章 初始SVM分类回归 第13章 LIBSVM...
  • 第9章 离散Hopfield神经网络联想记忆——数字识别 第10章 离散Hopfield神经网络分类——高校科研能力评价 第11章 连续Hopfield神经网络优化——旅行商问题优化计算 第12章 初始SVM分类回归 第13章 LIBSVM...
  • 第9章 离散Hopfield神经网络联想记忆——数字识别 第10章 离散Hopfield神经网络分类——高校科研能力评价 第11章 连续Hopfield神经网络优化——旅行商问题优化计算 第12章 初始SVM分类回归 第13章 LIBSVM...
  • 第9章 离散Hopfield神经网络联想记忆——数字识别 第10章 离散Hopfield神经网络分类——高校科研能力评价 第11章 连续Hopfield神经网络优化——旅行商问题优化计算 第12章 初始SVM分类回归 第13章 LIBSVM...
  • vc++ 应用源码包_1

    热门讨论 2012-09-15 14:22:12
    老版qq系统的实现。 MyIE3.0浏览器源代码 如题。完整的代码,重载控件实现,非常适合初学者。 MyPhpServer(原创,有实现的主要代码) microcai-ibus-t9-输入法源码 如题,主要源码就几个,详细见代码。 MzfHips...
  • 第9章 离散Hopfield神经网络联想记忆——数字识别 第10章 离散Hopfield神经网络分类——高校科研能力评价 第11章 连续Hopfield神经网络优化——旅行商问题优化计算 第12章 初始SVM分类回归 第13章 LIBSVM...
  • vc++ 应用源码包_2

    热门讨论 2012-09-15 14:27:40
    老版qq系统的实现。 MyIE3.0浏览器源代码 如题。完整的代码,重载控件实现,非常适合初学者。 MyPhpServer(原创,有实现的主要代码) microcai-ibus-t9-输入法源码 如题,主要源码就几个,详细见代码。 MzfHips...
  • 第9章 离散Hopfield神经网络联想记忆——数字识别 第10章 离散Hopfield神经网络分类——高校科研能力评价 第11章 连续Hopfield神经网络优化——旅行商问题优化计算 第12章 初始SVM分类回归 第13章 LIBSVM...
  • vc++ 应用源码包_6

    热门讨论 2012-09-15 14:59:46
    老版qq系统的实现。 MyIE3.0浏览器源代码 如题。完整的代码,重载控件实现,非常适合初学者。 MyPhpServer(原创,有实现的主要代码) microcai-ibus-t9-输入法源码 如题,主要源码就几个,详细见代码。 MzfHips...
  • 第9章离散Hopfield神经网络联想记忆——数字识别 第10章离散Hopfield神经网络分类——高校科研能力评价 第11章连续Hopfield神经网络优化——旅行商问题优化计算 第12章初始SVM分类回归 第13章LIBSVM参数实例...

空空如也

空空如也

1 2 3 4
收藏数 70
精华内容 28
关键字:

手写数字识别系统的设计与实现