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神经网络。……x1x2xn……11121n21111w211w212w21nw1nnw121wy2层神经网络本文隐含层和输出层的激活函数选用Sigmoid函数,1()1sse,()(1())dssds其函数曲线如下所示:由奇偶检验问题的定义:可定义如下分类函数:1y=1/2Y()0y1/2y其中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次运算的平均值,其正确率如下图所示:定义正确率:nAN其中,A为正确率,n=测试值和真实值相等的数量,N为参与测试的样本数量。由上图可以看出,10次测试的正确率都是A=1,有理由相信,BP神经网络所训练出来的参数是正确的。(2.3)XOR运算使用2层BP神经网络,NN的取隐含层节点数为3,示意图如下所示:x1x2y两层神经网络实现逻辑异或运算(XOR)的真值表如下所示:x1x2y000011101110计算公式如下:11111111122111112211222211113311322221212121111221331sigmoidsigmoidsigmoidsigmoidywxwxywxwxywxwxywywywy经过28582次迭代后,可求得其权值取值如下:1112130001111121121221131324.2173326.5755455.6754655.6381996.6629604.24822122211121311.86787616.30160911.86368721[][0](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次运算的平均值,其正确率如下图所示:定义正确率:nAN其中,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_COUTSampleTest=2^IN_COUTNN_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,隐层节点最大数量为50doublew[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,理想输出为yintUseBp(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语言实现*/#includestdlib.h#includemath.h#includestdio.h#includetime.h#includeNeuralNetBP.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;iIN_COUT;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;jOUT_COUT;j++)(*bp).w[i][j]=rand()/(double)(RAND_MAX);return1;}intTrainBp(bp_nn*bp,intx[SampleTrain][IN_COUT],inty[SampleTrain][OUT_COUT]){//训练bp网络,样本为x,理想输出为ydoublef=(*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;iIN_COUT;i++)//复制结构体中的权矩阵for(j=0;jh;j++)v[i][j]=(*bp).v[i][j];for(i=0;ih;i++)for(j=0;jOUT_