BP神经网络的手写数字识别

ANN 人工神经网络算法在实践中往往给人难以琢磨的印象,有句老话叫“出来混总是要还的”,大概是由于具有很强的非线性模拟和处理能力,因此作为代价上帝让它“黑盒”化了。作为一种general purpose的学**算法,如果你实在不想去理会其他类型算法的理论基础,那就请使用ANN吧。本文为笔者使用BP神经网络进行手写数字识别的整体思路和算法实现,由于近年来神经网络在深度学**,尤其是无监督特征学**上的成功,理解神经网络的实现机制也许可以让“黑盒”变得不再神秘。

首先,作为一篇面向机器学**爱好者的文章,基本的理论介绍还是必要的。BP (Back Propagation)神经网络,即误差反传误差反向传播算法的学**过程,由信息的正向传播和误差的反向传播两个过程组成。输入层各神经元负责接收来自外界的输入信息,并传递给中间层各神经元;中间层是内部信息处理层,负责信息变换,根据信息变化能力的需求,中间层可以设计为单隐层或者多隐层结构;最后一个隐层传递到输出层各神经元的信息,经进一步处理后,完成一次学**的正向传播处理过程,由输出层向外界输出信息处理结果。当实际输出与期望输出不符时,进入误差的反向传播阶段。误差通过输出层,按误差梯度下降的方式修正各层权值,向隐层、输入层逐层反传。周而复始的信息正向传播和误差反向传播过程,是各层权值不断调整的过程,也是神经网络学**训练的过程,此过程一直进行到网络输出的误差减少到可以接受的程度,或者预先设定的学**次数为止。

网络结构

输入层有n个神经元,隐含层有p个神经元,输出层有q个神经元。

变量定义

参数训练

算法流程

图像预处理与归一化

好了,理论介绍完了,接下来看看如何识别手写数字。

输入样本示例

输入样本为书写数字的图像,数据下载百度网盘链接:http://yun.baidu.com/s/1nt3UewD

本文采用逐像素特征提取的方法提取数字样本的特征向量。将像素点RGB值之和大于255的像素点,特征值设为1,反之设为0。归一化的图像生成一个28x28的布尔矩阵,依次取每列元素,转化为784x1的列矩阵,作为输入图像的特征向量。

模型训练与模型识别

BP神经网络模型参数设置

样本描述:

受训练样本限制,本文仅对0,1,2,3,4这5个数字进行识别。每个数字对应训练样本与测试样本数量如下表

模型评估

程序设计参考(Java)

public class AnnModel:前反馈神经网络模型

主要成员变量

public HiddenNeuron[] hiddenLayer;

//隐含层神经元数组

public OutputNeuron[] outputLayer;

//输出层神经元数组

publicintinputLayerSize,hiddenLayerSize,outputLayerSize;

//输入层神经元个数、隐含层神经元个数、输出层神经元个数

主要方法

public BPAnnModel(intinputLayerSize,inthiddenLayerSize,int outputLayerSize)

//根据输入层、隐含层与输出层神经元个数,初始化隐含层与输出层各神经元,构造网络模型

publicdouble[] calculateHiddenLayerOutput(double[] inputLayer)

//根据输入层计算隐含层输出

publicdouble[] calculateModelOutput(double[] inputLayer)

//根据输入层计算输出层输出

public String getOutputClass(double[] inputLayers)

//根据输入层预测分类结果

publicvoidsave(String modelSavePath)

//将模型的训练结果保存到文本文件中

publicstatic BPAnnModel load(String modelSavePath)

//从保存训练结果的文本文件中读取模型参数,创建神经网络模型实例

public class Neuron:神经元超类

主要成员变量

publicdoubletheta=0.2;

//theta 为神经元兴奋度阈值

publicdouble[] weight;

//权值向量

publicdoublemu=0.1;

//mu为梯度下降的学**速率

publicintidx;

//idx为神经元在其所在层的索引位置

主要方法

public Neuron(intweightArrLength,intidx)

//根据权值向量长度初始化权值向量,构造神经元实例,this.idx=idx

publicdouble calculateActivation(double[] layerInput)

//根据神经元输入计算净活跃度

publicdouble calculateOutput(double[]layerInput)

//根据神经元输入计算神经元输出

publicdouble logisticSigmod(doublefixedActivation)

//激活函数

publicdouble logisticSigmod_1(doubleoutput)

//激活函数一阶导数

public class HiddenNeuron:隐含层神经元,Neuron子类

publicvoidupdateWeight(double[] inputLayer, double[]yArr,

double[] tmpHiddenLayerOutput,

double[] tmpModelOutput)

//根据网络模型输入层、期望输出、隐含层输出与输出层修正权值向量

public class OutputNeuron:输出层神经元,Neuron子类

publicvoidupdateWeight(double[] inputLayer, double[]yArr)

//根据网络模型输入层和期望输出修正权值向量

public class BPBP神经网络训练主程序

主要成员变量

publicdoubleepsilon=0.005;

//训练停止的最小误差

publicintcurTrainingTimes=0,maxTrainingTimes=50000;

//当前训练次数与最大训练次数

public BPAnnModel model;

//神经网络模型

publicdouble[][] trainData;

//训练数据集

主要方法

publicvoidsetModel(BPAnnModel model)

//加载权值已训练好的神经网络模型

publicvoidsetTrain(String trainPath,String varType,Stringdelimiter)

//输入训练数据文件与文件格式生成训练数据集

publicvoidtrain()

//执行训练过程

publicdouble calculateSingleError(double[] inputLayer,double[] yArr,boolean standardizeTrans)

//计算单训练点误差

publicdouble calculateGlobalError()

//计算全局误差

注意事项

1.输入样本归一化处理 由于模型输入数据的单位不一样,有些数据的范围可能特别大,导致的结果是神经网络收敛慢、训练时间长、模型不稳定。因此在进行训练之前通常需要对数据进行归一化处理。为了统一各层神经元的输入标准,采用S形激活函数时,激活函数的值域为 (0,1),通常采用max&min的方法将变量映射成 (0,1) 之间的数;采用双极S形激活函数时,激活函数的值域为 (-1,1),通常采用2(max&min)-1的方法将变量映射成 (-1,1) 之间的数。

2.减少计算全局误差的频次 每次迭代过程中,权值修正的效率只和网络的规模有关系,而计算全局误差消耗的时间则和样本量的大小直接成正比。在样本量较大的情况下,频繁的计算全局误差会带来及大的开销。为了提高训练效率,可以采取批量式的训练方法,即在第六步完成后,直接跳回第二步,进行指定次迭代后,再进入到第七步进行全局误差检验。

3.输出层定义 当目标变量有m个分类时,输出层的神经元个数通常有有两种定义方法,m或以2为底的log m。建议采用m作为输出层神经元个数,一方面可以很方便地从输出层输出信号映射到分类值;另一方面可以给出分类结论的“置信度”。采用以2为底的log m作为输出层神经元个数时,通常采用输出信号的二进制表示去映射指定分类。

4.学**效率(梯度下降的步长)参数设定

学**效率直接影响着网络收敛的速度,以及网络能否收敛。学**效率设置偏小可以保证网络收敛,但是收敛较慢;反之则有可能使网络训练不收敛,影响识别效果。因此可以在误差快速下降后放缓学**效率,增强模型稳定性。

5.过拟合问题 神经网络计算不能一味地追求训练误差最小,这样很容易出现“过拟合”现象,只要能够实时检测误差率的变化就可以确定最佳的训练次数,比如在本文中25000次左右的学**次数即可在测试数据上达到最优效果,25000次之后的学**,不仅徒增计算量,而且还有过拟合的风险。

 
 

BP神经网络的手写数字识别的更多相关文章

  1. 利用c++编写bp神经网络实现手写数字识别详解

    利用c++编写bp神经网络实现手写数字识别 写在前面 从大一入学开始,本菜菜就一直想学习一下神经网络算法,但由于时间和资源所限,一直未展开比较透彻的学习.大二下人工智能课的修习,给了我一个学习的契机. ...

  2. BP神经网络(手写数字识别)

    1实验环境 实验环境:CPU i7-3770@3.40GHz,内存8G,windows10 64位操作系统 实现语言:python 实验数据:Mnist数据集 程序使用的数据库是mnist手写数字数据 ...

  3. 【机器学习】BP神经网络实现手写数字识别

    最近用python写了一个实现手写数字识别的BP神经网络,BP的推导到处都是,但是一动手才知道,会理论推导跟实现它是两回事.关于BP神经网络的实现网上有一些代码,可惜或多或少都有各种问题,在下手写了一 ...

  4. TensorFlow卷积神经网络实现手写数字识别以及可视化

    边学习边笔记 https://www.cnblogs.com/felixwang2/p/9190602.html # https://www.cnblogs.com/felixwang2/p/9190 ...

  5. 第二节,TensorFlow 使用前馈神经网络实现手写数字识别

    一 感知器 感知器学习笔记:https://blog.csdn.net/liyuanbhu/article/details/51622695 感知器(Perceptron)是二分类的线性分类模型,其输 ...

  6. 卷积神经网络CNN 手写数字识别

    1. 知识点准备 在了解 CNN 网络神经之前有两个概念要理解,第一是二维图像上卷积的概念,第二是 pooling 的概念. a. 卷积 关于卷积的概念和细节可以参考这里,卷积运算有两个非常重要特性, ...

  7. TensorFlow.NET机器学习入门【5】采用神经网络实现手写数字识别(MNIST)

    从这篇文章开始,终于要干点正儿八经的工作了,前面都是准备工作.这次我们要解决机器学习的经典问题,MNIST手写数字识别. 首先介绍一下数据集.请首先解压:TF_Net\Asset\mnist_png. ...

  8. 莫烦pytorch学习笔记(八)——卷积神经网络(手写数字识别实现)

    莫烦视频网址 这个代码实现了预测和可视化 import os # third-party library import torch import torch.nn as nn import torch ...

  9. NN:利用深度学习之神经网络实现手写数字识别(数据集50000张图片)—Jason niu

    import mnist_loader import network training_data, validation_data, test_data = mnist_loader.load_dat ...

随机推荐

  1. 动软代码生成器,主子表增加的时候子表的parentID无法插入问题解决方案

    StringBuilder strSql=new StringBuilder(); strSql.Append("insert into HT_XunJiaMain("); str ...

  2. JavaScript 闭包的详细分享(三种创建方式)(附小实例)

    JavaScript闭包的详细理解 一.原理:闭包函数--指有权访问私有函数里面的变量和对象还有方法等:通俗的讲就是突破私有函数的作用域,让函数外面能够使用函数里面的变量及方法. 1.第一种创建方式 ...

  3. react+webpack 引入字体图标

    在使用react+webpack 构建项目过程中免不了要用到字体图标,在引入过程中报错,不能识别字体图标文件中的@符,报错 Uncaught Error: Module parse failed: U ...

  4. 笨办法学Python(三十二)

    习题 32: 循环和列表 现在你应该有能力写更有趣的程序出来了.如果你能一直跟得上,你应该已经看出将“if 语句”和“布尔表达式”结合起来可以让程序作出一些智能化的事情. 然而,我们的程序还需要能很快 ...

  5. [转载]在VB.Net中获取COM对象的特定实例(Getting a specific instance of COM object in VB.Net)

    转载:http://www.it1352.com/534235.html 问题: I am writing a Windows Form application in .Net to list all ...

  6. 关于SAP UI5数据绑定我的一些原创内容

    如何查找SAP UI5官方关于数据绑定的文档: https://sapui5.hana.ondemand.com/ 点Documentation: Filter里输入data就能看到Data Bind ...

  7. telegram汉化和代理

    telegram在Ubuntu18.04的应用商店中可以一键下载. 1.注册:用国内手机号即可,就是验证码可能很慢. 2.汉化:关注zh-CN 频道,在点击其中的安装链接即可. 3.代理: 如果你使用 ...

  8. 2018.9.3 CEP课程总结

    什么是CEP课程? 职业生涯规划课程 蓝桥介绍 立人达人 全人教育 人文 重视人 尊重人 关心人 爱护人 人才 人格 简历的制作 找工作的流程? 1.简历的准备------>投发简历(自己投.老 ...

  9. FastRCNN 训练自己数据集 (1编译配置)

    http://www.cnblogs.com/louyihang-loves-baiyan/p/4885659.html 按照博客的教程配置,但自己在服务器上配置时,USE_CUDNN = 1会报错, ...

  10. fast rcnn的实例

    http://www.cnblogs.com/louyihang-loves-baiyan/p/4906690.html https://saicoco.github.io/object-detect ...