实验描述
使用BP神经网络,编程实现手写体的识别,输出识别率。
浅谈BP
BP神经网络也称后向传播学习的前馈型神经网络( Back Propagation Feed-forward Neural
Network,BPFNN/BPNN),是一种应用最为广泛的神经网络。
BP神经网络是有监督学习网络,是一种按误差逆传播算法训练的多层前馈网络,BP网络能学习和存贮大量的输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。BP神经网络模型结构包括输入层、隐含层和输出层。
BP神经网络主要分为信号的正向传播和误差反向传播两个过程,正向传播是指在样本数据输入后,计算输入层到隐含层,再到输出层的数据;误差反向传播就是将输出误差以某种形式通过隐含层向输入层逐层反传,将误差分摊给各层的单元,再使用梯度下降法修正各单元的权值,使得最终输出结果和预期结果的误差最小。一般当网络输出的误差减少到可接受的程度或者进行到预先设定的学习次数时,训练结束。
BP神经网络算法流程
- 初始化网络权值。网络权值和神经元偏执随机赋值在(-1,1)之间。
- 向前传播输入。
- 反向传播误差。
- 网络权值与神经元偏置调整。
激活函数
sigmoid函数的作用是将输入映射到一个(0,1)的输出范围。
运行环境
系统:Windows系统
语言:C++
软件:Dev-C++ 5.11
MNIST数据集
MNIST是一个非常有名的手写体数字识别数据集,在很多资料中,这个数据集都会被用作深度学习的入门样例。
数据集下载网址:http://yann.lecun.com/exdb/mnist/
数据集简介
MINIST实验包含了四个文件,其中:
train-images-idx3-ubyte是60000个图片样本;跳过开头16个字节,每784个字节代表一张图片,其中每一个字节代表28 * 28 中的一个像素点,取值范围为0~256。(本次实验中,像素点值大于128, 输入层的0-1矩阵对应维取1;小于128,0-1矩阵对应维取0)。
数据集和整个实验项目在https://gitee.com/haaaaaaaaaaaa/SourceCode.git下的IntelligenceSystem/BPNNHandwritingRecognition中。
实验中数据处理
对每一张手写图片,先把它处理成一个28 * 28 的0-1矩阵,其中1代表数字的笔画着色部分,0则代表空白。然后我们把该矩阵,扁平成一个784维的输入向量,输入到输入层。经过隐含层(此次实验隐藏层结点数取100),到达输出层时,是一个10维的输出向量,每一位分别对应数字的0~9 。
实验步骤
- 提取数据(使用MNIST数据集)
- 特征提取
- 训练BP神经网络
1)权值和神经元偏置随机赋值
2)前向求出隐含层和输出层的输出
3)求出输出层与预期输出的误差
4)反向传播误差,求出隐含层误差
5)调整权值和神经元偏置
6)结束(文件读取完毕) - 数据测试,输出识别率
实验代码
/*
Description:智能系统理论与应用实验
题目:基于BP神经网络的手写体识别
1、提取数据(使用MNIST数据集)
2、特征提取
3、训练BP神经网络
1)权值和神经元偏置随机赋值
2)前向求出隐含层和输出层的输出
3)求出输出层与预期输出的误差
4)反向传播误差,求出隐含层误差
5)调整权值和神经元偏置
6)结束(文件读取完毕)
4、数据测试,输出识别率
Date: 2020/05/25
Version: Dev-C++ 5.11
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <cmath>
#include <time.h>
using namespace std;
/*全局变量*/
const int first = 784; //输入层到隐藏层,输入层是784维输入向量(数据集中照片是28*28)
const int second = 100; //隐含层节点数取100
const int third = 10; //输出层是一个10维的向量,每一位分别对应数字0~9
const double alpha = 0.35; //神经网络的学习率
int input[first]; //784维输入向量
int target[third]; //10维输出向量
double weight1[first][second]; //输入层到隐含层权重
double weight2[second][third]; //隐含层到输出层权重
double output1[second]; //隐含层输出
double output2[third]; //输出层输出,即目标输出
double delta1[second]; //隐含层误差
double delta2[third]; //输出层与预期输出的误差
double b1[second]; //隐含层神经元偏置,偏置的存在是为了更好的拟合数据
double b2[third]; //输出层神经元偏置,偏置的存在是为了更好的拟合数据
double test_num = 0.0; //测试次数
double test_success_count = 0.0;//测试成功次数
/*激活函数*/
//sigmoid函数的作用是将输入映射到一个(0,1)的输出范围
double Sigmoid(double x){
return 1.0 / (1.0 + exp(-x));
}
/*初始化权重矩阵和神经元偏置*/
void Initialize(){
srand((int)time(0) + rand());//算法的随机种子数,有这个数以后才可以产生随机数 ,只调用rand,每次出来的东西是一样的
for (int i = 0; i < first; i++)

本文介绍使用BP神经网络进行手写体数字识别的实验,涵盖BP神经网络原理、实验步骤及代码实现,最终输出识别率。

5596

被折叠的 条评论
为什么被折叠?



