如何用C语言编程实现多层前向BP神经网络用来解决逻辑 XOR 运算和奇偶检验问题.docx
- 文档编号:27432719
- 上传时间:2023-06-30
- 格式:DOCX
- 页数:23
- 大小:310.43KB
如何用C语言编程实现多层前向BP神经网络用来解决逻辑 XOR 运算和奇偶检验问题.docx
《如何用C语言编程实现多层前向BP神经网络用来解决逻辑 XOR 运算和奇偶检验问题.docx》由会员分享,可在线阅读,更多相关《如何用C语言编程实现多层前向BP神经网络用来解决逻辑 XOR 运算和奇偶检验问题.docx(23页珍藏版)》请在冰豆网上搜索。
如何用C语言编程实现多层前向BP神经网络用来解决逻辑XOR运算和奇偶检验问题
6.
(1)试用C语言编程实现多层前向NN的BP算法。
要求:
输入、输出结点数目,隐层数目,及各隐层中结点的数目应为任意整数。
(2)试用所编出的BP算法程序训练出一个实现XOR运算的2层前向网络。
(3)用所编出的BP算法程序训练出输入矢量的维数分别为n=7和n=8的两个实现奇偶检验运算(即如题2.
(2)所述)的2层前向NN。
注:
对第6题的要求:
(i)列表给出训练收敛后的NN权值和所用的迭代次数;
(ii)给出训练收敛后的训练误差和检验误差,及用训练集和检验集做输入时所得到的正确输出率;
(iii)给出NN的学习曲线(即E(W(k))随迭代次数k的变化曲线,该结果应是用计算程序计算和打印出来的曲线,而不要是用手画出的曲线)。
(1)用C语言编程实现前向NN的BP算法
解:
解题思路:
先用C语言编程实现前向NN的BP算法,再将误差保存至文本文件,最后用MATLAB绘制出误差曲线。
(1.1)开发思路
奇偶检验问题可视为XOR问题的推广(由2输入到n输入的推广):
若n个输入中有奇数个1,则输出为1;若n个输入中有偶数个1,则输出为0。
一个2层的NN可实现奇偶检验运算。
本文选用2层神经网络,包括隐含层1层,输出层1层,来设计BP神经网络。
2层神经网络
本文隐含层和输出层的激活函数选用Sigmoid函数,
,
其函数曲线如下所示:
由奇偶检验问题的定义:
可定义如下分类函数:
其中y为BP神经网络的输出值,Y为分类结果。
(1.2)运行流程
本文的多层前向NN的BP算法用C语言编程实现,最后将运行结果保存成数据文件,通过MATLAB绘图显示,其运行流程图如上图所示,其源代码见附录部分。
(1.3)参数设定
输入、输出结点数目,隐层数目,及各隐层中结点的数目应为任意整数,通过宏定义改变相应的值,具体修改方式见《NeuralNetBP.h》文件,在程序运行之前,需要跳转到该文件修改具体的取值。
(2)试用所编出的BP算法程序训练出一个实现XOR运算的2层前向网络。
解:
利用
(1)中BP算法程序训练出XOR运算的2层前向网络。
(2.1)参数设定
首先进入《NeuralNetBP.h》文件通过宏定义改变相应的值,包括输入、输出结点数目,隐层数目,及各隐层中结点的数目。
//XOR2
#defineIN_COUT2//输入向量维数
#defineOUT_COUT1//输出向量维数
#defineIMPLY_NUM1//隐含层层数
#defineSampleTrain4//训练样本数量
#defineSampleTest4//测试样本数量
#defineNN_ImplyCout3//隐含层节点数
#defineNN_Rate0.5//学习速率
#defineNN_Error0.001//精度控制参数
#defineNN_LOOP100000//最大循环次数
(2.1)程序训练结果
对所有样本进行训练,取隐含层节点数为3,运行结果如下:
BP神经网络的学习曲线如下:
可以看出BP神经网络的误差很快收敛至0。
为了测试BP神经网络的有效性,取10次运算的平均值,其正确率如下图所示:
定义正确率:
其中,A为正确率,n=测试值和真实值相等的数量,N为参与测试的样本数量。
由上图可以看出,10次测试的正确率都是A=1,有理由相信,BP神经网络所训练出来的参数是正确的。
(2.3)XOR运算
使用2层BP神经网络,NN的取隐含层节点数为3,示意图如下所示:
两层神经网络实现逻辑异或运算(XOR)的真值表如下所示:
x1
x2
y
0
0
0
0
1
1
1
0
1
1
1
0
计算公式如下:
经过28582次迭代后,可求得其权值取值如下:
(3)用所编出的BP算法程序训练出输入矢量的维数分别为n=7和n=8的两个实现奇偶检验运算(即如题2.
(2)所述)的2层前向NN。
解:
n=7和n=8的两个实现奇偶检验运算的2层前向NN,完全相同,本文以n=7为例进行说明。
(3.1)参数设定
首先进入《NeuralNetBP.h》文件通过宏定义改变相应的值,包括输入、输出结点数目,隐层数目,及各隐层中结点的数目。
//XOR7
#defineIN_COUT7//输入向量维数
#defineOUT_COUT1//输出向量维数
#defineIMPLY_NUM1//隐含层层数
#defineSampleTrain128//训练样本数量用0-127共128组数据全部参加训练
#defineSampleTest128//测试样本数量用0-127共128组数据全部参加测试
#defineNN_ImplyCout25//隐含层节点数
#defineNN_Rate0.4//学习速率
#defineNN_Error0.001//精度控制参数
#defineNN_LOOP100000//最大循环次数
(3.2)程序训练结果
7位2进制数数,共有128个样本,对所有样本进行训练,取隐含层节点数为25,运行结果如下:
经过85857次迭代学习后,收敛至指定误差范围内。
全部样本参加测试,所有的样本的输出值都能完全和真值吻合,正确率为1。
BP神经网络的学习曲线如下:
可以看出BP神经网络的误差很快收敛至0。
为了测试BP神经网络的有效性,取10次运算的平均值,其正确率如下图所示:
定义正确率:
其中,A为正确率,n=测试值和真实值相等的数量,N为参与测试的样本数量。
由上图可以看出,10次测试的正确率均值为0.967,有理由相信,BP神经网络所训练出来的参数是正确的。
附录
一、《"NeuralNetBP.h"》
/*
参数定义
*/
#pragmaonce
#ifndef_NEURALNETBP_H
#define_NEURALNETBP_H
////XOR2
//#defineIN_COUT2//输入向量维数
//#defineOUT_COUT1//输出向量维数
//#defineIMPLY_NUM1//隐含层层数
//
//#defineSampleTrain4//训练样本数量用0-127共128组数据全部参加训练
//#defineSampleTest4//测试样本数量用0-127共128组数据全部参加测试
//
//#defineNN_ImplyCout4//隐含层节点数
//#defineNN_Rate0.5//学习速率
//#defineNN_Error0.001//精度控制参数
//#defineNN_LOOP100000//最大循环次数
/*参数该变量
输入维数改变时,改变IN_COUT的值即可
同时需要修改SampleTrain、SampleTest、NN_ImplyCout的值;
本程序取:
SampleTrain=2^IN_COUT
SampleTest=2^IN_COUT
NN_ImplyCout=(2-4)*IN_COUT
*/
//XOR7
#defineIN_COUT7//输入向量维数
#defineOUT_COUT1//输出向量维数
#defineIMPLY_NUM1//隐含层层数
#defineSampleTrain128//训练样本数量用0-127共128组数据全部参加训练
#defineSampleTest128//测试样本数量用0-127共128组数据全部参加测试
#defineNN_ImplyCout25//隐含层节点数
#defineNN_Rate0.4//学习速率
#defineNN_Error0.001//精度控制参数
#defineNN_LOOP100000//最大循环次数
typedefstruct{//bp人工神经网络结构
inth;//实际使用隐层节点数
doublev[IN_COUT][50];//隐藏层权矩阵i,隐层节点最大数量为50
doublew[50][OUT_COUT];//输出层权矩阵
doublea;//学习率
doubleb;//精度控制参数
intLoopCout;//最大循环次数
intLoopItera;//实际循环次数
doubleError[NN_LOOP];//误差
}bp_nn;
intInitBp(bp_nn*bp);//初始化bp网络
intTrainBp(bp_nn*bp,intx[SampleTrain][IN_COUT],inty[SampleTrain][OUT_COUT]);//训练bp网络,样本为x,理想输出为y
intUseBp(bp_nn*bp,intInput[IN_COUT],doubleOutput[OUT_COUT]);//使用bp网络
doubleTestBp(bp_nn*bp,intx[SampleTest][IN_COUT],inty[SampleTest][OUT_COUT]);//测试bp网络
#endif
二、《"NeuralNetBP.cpp"》
/*
BP人工神经网络基本算法C语言实现
*/
#include
#include
#include
#include
#include"NeuralNetBP.h"
//神经网络激活函数
doublefnet(doublenet){
doubletemp=0;
//Sigmoid函数
temp=1.0/(1+exp(-net));
returntemp;
}
intInitBp(bp_nn*bp){//初始化bp网络
//请输入隐层节点数,最大数为50
(*bp).h=NN_ImplyCout;
//请输入学习率
(*bp).a=NN_Rate;//(*bp).a为double型数据,所以必须是lf
//请输入精度控制参数
(*bp).b=NN_Error;
//请输入最大循环次数
(*bp).LoopCout=NN_LOOP;
//产生随机数初始化权值矩阵
inti,j;
srand((unsigned)time(NULL));
for(i=0;i for(j=0;j<(*bp).h;j++) (*bp).v[i][j]=rand()/(double)(RAND_MAX); for(i=0;i<(*bp).h;i++) for(j=0;j (*bp).w[i][j]=rand()/(double)(RAND_MAX); return1; } intTrainBp(bp_nn*bp,intx[SampleTrain][IN_COUT],inty[SampleTrain][OUT_COUT]) { //训练bp网络,样本为x,理想输出为y doublef=(*bp).b;//精度控制参数 doublea=(*bp).a;//学习率 inth=(*bp).h;//隐层节点数 doublev[IN_COUT][50],w[50][OUT_COUT];//权矩阵 doubleChgH[50],ChgO[OUT_COUT];//修改量矩阵 doubleO1[50],O2[OUT_COUT];//隐层和输出层输出量 intLoopCout=(*bp).LoopCout;//最大循环次数 inti,j,k,n; doubletemp; for(i=0;i for(j=0;j v[i][j]=(*bp).v[i][j]; for(i=0;i for(j=0;j w[i][j]=(*bp).w[i][j]; doublee=f+1; for(n=0;e>f&&n {//对每个样本训练网络 e=0; for(i=0;i { for(k=0;k temp=0; for(j=0;j temp=temp+x[i][j]*v[j][k]; O1[k]=fnet(temp); } for(k=0;k temp=0; for(j=0;j temp=temp+O1[j]*w[j][k]; O2[k]=fnet(temp); } for(j=0;j ChgO[j]=O2[j]*(1-O2[j])*(y[i][j]-O2[j]); for(j=0;j e=e+(y[i][j]-O2[j])*(y[i][j]-O2[j]); for(j=0;j temp=0; for(k=0;k temp=temp+w[j][k]*ChgO[k]; ChgH[j]=temp*O1[j]*(1-O1[j]); } for(j=0;j for(k=0;k w[j][k]=w[j][k]+a*O1[j]*ChgO[k]; for(j=0;j for(k=0;k v[j][k]=v[j][k]+a*x[i][j]*ChgH[k]; } (*bp).Error[n]=e;//记录误差 if(n%10==0) { printf("循环次数: %d,误差: %f\n",n,e); } } (*bp).LoopItera=n;//实际循环次数 printf("总共循环次数: %d\n",n); printf("调整后的隐层权矩阵: \n"); for(i=0;i for(j=0;j printf("%f",v[i][j]); printf("\n"); } printf("调整后的输出层权矩阵: \n"); for(i=0;i for(j=0;j printf("%f",w[i][j]); printf("\n"); } for(i=0;i for(j=0;j (*bp).v[i][j]=v[i][j]; for(i=0;i for(j=0;j (*bp).w[i][j]=w[i][j]; printf("bp网络训练结束! \n\n"); return1; } intUseBp(bp_nn*bp,intInput[IN_COUT],doubleOutput[OUT_COUT]){//使用bp网络 doubleO1[50]; doubleO2[OUT_COUT];//O1为隐层输出,O2为输出层输出 inti,j; doubletemp; for(i=0;i<(*bp).h;i++){ temp=0; for(j=0;j temp+=Input[j]*(*bp).v[j][i]; O1[i]=fnet(temp); } for(i=0;i temp=0; for(j=0;j<(*bp).h;j++) temp+=O1[j]*(*bp).w[j][i]; O2[i]=fnet(temp); } //输出值 for(i=0;i { Output[i]=O2[i]; } return1; } doubleTestBp(bp_nn*bp,intx[SampleTest][IN_COUT],inty[SampleTest][OUT_COUT]) {//使用bp网络 inti,j; intInput[IN_COUT]; doubleOutput[OUT_COUT];//此处的输出是实际计算输出所以为double型 intyMeasure[SampleTest]; intCorrectN=0; doubleAccuracy=0;//正确率 for(i=0;i { for(j=0;j { Input[j]=x[i][j]; } UseBp(bp,Input,Output);//测试bp神经网络子函数 //结果分类 if(Output[OUT_COUT-1]>=0.5) { yMeasure[i]=1; } else { yMeasure[i]=0; } if(y[i][OUT_COUT-1]==yMeasure[i])//真值=测量值 { CorrectN++; } } Accuracy=CorrectN*1.0/SampleTest;//计算正确率 //显示测试结果 printf("n=7时,BPNN测试结果为: \n"); printf("测试样本数: %d\n",SampleTest); printf("正确样本数: %d\n",CorrectN); printf("正确率为: %f\n",Accuracy); printf("\n\n"); returnAccuracy; } 三、《"main.cpp"》 #include #include #include #include #include #include"NeuralNetBP.h" #include"HandleFile.h" #include"Sample.h" /*奇偶性判断 若n个输入中有奇数个1,则输出为1;若n个输入中有偶数个1,则输出为0。 */ intmain() { intTrainX[SampleTrain][IN_COUT]; intTrainY[SampleTrain][OUT_COUT]; intTestX[SampleTest][IN_COUT]; intTestY[SampleTest][OUT_COUT]; bp_nnbp; constintTrainTimes=1;//训练次数 doubleAccuracy[TrainTimes];//正确率 SampleTrain_Init(TrainX,TrainY); SampleTest_Init(TestX,TestY); //InitBp(&bp);//初始化bp网络结构 //TrainBp(&bp,TrainX,TrainY);//训练bp神经网络 //TestBp(&bp,TestX,TestY);//测试bp神经网络 //多次训练取平均值 for(inti=0;i { InitBp(&bp);//初始化bp网络结构 TrainBp(&bp,TrainX,TrainY);//训练bp神经网络 Accuracy[i]=TestBp(&bp,TestX,TestY);//测试bp神经网络 } //保存数据 WriteToFile_Error(&bp,"Data\\XOR7_Error.txt");//保存最后一次的误差 WriteToFile_Accuracy("Data\\XOR7_Result.txt",Accuracy,TrainTimes);//保存所有的运行结果 system("pause"); return1; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 如何用C语言编程实现多层前向BP神经网络用来解决逻辑 XOR 运算和奇偶检验问题 何用 语言 编程 实现 多层 BP 神经网络 用来 解决 逻辑 运算 奇偶 检验 问题
![提示](https://static.bdocx.com/images/bang_tan.gif)