您好,欢迎访问三七文档
机器学习作业(BP神经网络)胡雷201313704043#includestdio.h#includestdlib.h#includemath.h#includetime.h#defineIN2//输入向量维数#defineOUT2//输出向量维数#defineNUM20//样本数量#defineLoop_MAX262140//最大循环次数#definedot_MAX20//最大结点个数typedefstruct//bp人工神经网络结构{intdot;//隐层节点数doublev[IN][dot_MAX];//输入层权矩阵doubleu[dot_MAX][dot_MAX];//隐藏层权矩阵doublew[dot_MAX][OUT];//输出层权矩阵doublerate;//学习率doubleerror;//允许误差限}bp_net;doublev[IN][3]={0.5,0.4,0.1,0.2,0.6,0.2};//题目要求的权矩阵doubleu[3][3]={0.10,0.55,0.35,0.20,0.45,0.35,0.25,0.15,0.60};//同上doublew[3][OUT]={0.30,0.35,0.35,0.25,0.45,0.30};//同上doublefnet(doublenet)//Sigmoid函数{return1/(1+exp(-net));}voidInitialize_Bp(bp_net*bp)//初始化bp网络{printf(请输入隐层结点数:\n);scanf(%d,&(*bp).dot);printf(请输入学习率:\n);scanf(%lf,&(*bp).rate);printf(请输入允许误差限:\n);scanf(%lf,&(*bp).error);inti,j,flag;start:printf(请选择权矩阵输入形式:\n1、随机产生权矩阵\n2、手动输入权矩阵\n3、载入题目要求权矩阵\n);scanf(%d,&flag);if(flag==1){srand((unsigned)time(NULL));//随机函数产生随机权矩阵for(i=0;iIN;i++)for(j=0;j(*bp).dot;j++)(*bp).v[i][j]=rand()/(double)(RAND_MAX);for(i=0;i(*bp).dot;i++)for(j=0;j(*bp).dot;j++)(*bp).u[i][j]=rand()/(double)(RAND_MAX);for(i=0;i(*bp).dot;i++)for(j=0;jOUT;j++)(*bp).w[i][j]=rand()/(double)(RAND_MAX);}elseif(flag==2){printf(输入权矩阵:\n);for(i=0;iIN;i++)for(j=0;j(*bp).dot;j++)scanf(%lf,&(*bp).v[i][j]);printf(隐藏权矩阵:\n);for(i=0;i(*bp).dot;i++)for(j=0;j(*bp).dot;j++)scanf(%lf,&(*bp).u[i][j]);printf(输出权矩阵:\n);for(i=0;i(*bp).dot;i++)for(j=0;jOUT;j++)scanf(%lf,&(*bp).w[i][j]);}elseif(flag==3){for(i=0;iIN;i++)for(j=0;j3;j++)(*bp).v[i][j]=v[i][j];for(i=0;i3;i++)for(j=0;j3;j++)(*bp).u[i][j]=u[i][j];for(i=0;i3;i++)for(j=0;jOUT;j++)(*bp).w[i][j]=w[i][j];printf(载入完成!\n);}else{printf(输入错误!请重新输入!\n);gotostart;}printf(初始化输入权矩阵:\n);for(i=0;iIN;i++){for(j=0;j(*bp).dot;j++)printf(%lf,(*bp).v[i][j]);printf(\n);}printf(初始化隐藏层权矩阵:\n);for(i=0;i(*bp).dot;i++){for(j=0;j(*bp).dot;j++)printf(%lf,(*bp).u[i][j]);printf(\n);}printf(初始化输出权矩阵:\n);for(i=0;i(*bp).dot;i++){for(j=0;jOUT;j++)printf(%lf,(*bp).w[i][j]);printf(\n);}printf(\n);}voidTrain_Bp(bp_net*bp,doublex[NUM][IN],inty[NUM][OUT])//训练bp网络{doublee=(*bp).error;//允许误差限doublerate=(*bp).rate;//学习率intdot=(*bp).dot;//隐藏层结点doublev[IN][dot_MAX],w[dot_MAX][OUT],u[dot_MAX][dot_MAX];//权矩阵doubleError_Input[dot_MAX],Error_hider[dot_MAX],Error_Output[OUT];//各个结点的反向误差doubleInput[dot_MAX],hider[dot_MAX],Output[OUT];//各个层的结点输出inti,j,k,n,flag;//flag为是否继续修改权矩阵标志量doubletemp;for(i=0;iIN;i++)//复制结构体中的权矩阵for(j=0;jdot;j++)v[i][j]=(*bp).v[i][j];for(i=0;idot;i++)for(j=0;jdot;j++)u[i][j]=(*bp).u[i][j];for(i=0;idot;i++)for(j=0;jOUT;j++)w[i][j]=(*bp).w[i][j];for(n=0;nLoop_MAX;n++)//反向误差计算{flag=1;for(i=0;iNUM;i++){for(k=0;kdot;k++)//计算输入层输出向量{temp=0;for(j=0;jIN;j++)temp+=x[i][j]*v[j][k];Input[k]=fnet(temp);}for(k=0;kdot;k++)//计算隐藏层输出向量{temp=0;for(j=0;jdot;j++)temp+=Input[j]*u[j][k];hider[k]=fnet(temp);}for(k=0;kOUT;k++)//计算输出层输出向量{temp=0;for(j=0;jdot;j++)temp+=hider[j]*w[j][k];Output[k]=fnet(temp);}for(j=0;jOUT;j++)//测试结果与是否在误差范围内{if(fabs(y[i][j]-Output[j])e)continue;//如果满足精度要求,则继续测试下一个结点的情况else{flag=0;//修改了权矩阵for(j=0;jOUT;j++)Error_Output[j]=y[i][j]-Output[j];for(j=0;jdot;j++)//计算隐层权修改量{temp=0;for(k=0;kOUT;k++)temp+=w[j][k]*Error_Output[k];Error_hider[j]=temp*hider[j]*(1-hider[j]);}for(j=0;jdot;j++)//修改输出层权矩阵for(k=0;kOUT;k++)w[j][k]+=rate*hider[j]*Error_Output[k];for(j=0;jdot;j++)//计算输入层修改量{temp=0;for(k=0;kdot;k++)temp+=u[j][k]*Error_hider[k];Error_Input[j]=temp*Input[j]*(1-Input[j]);}for(j=0;jdot;j++)//修改隐藏层权矩阵for(k=0;kdot;k++)u[j][k]+=rate*Input[j]*Error_hider[k];for(j=0;jIN;j++)//修改输入层权矩阵for(k=0;kdot;k++)v[j][k]+=rate*x[i][j]*Error_Input[k];}}}if(!flag)continue;//若flag=0,标明修改了权矩阵,需重新训练实例直到满足精度条件else//相反,当所有实例均循环一次后,仍未修改权矩阵,标明满足要求,结束循环break;}printf(总共循环次数:%d\n,n);printf(\n);printf(修改后的输入权矩阵:\n);//输出修改后的输入层权矩阵for(i=0;iIN;i++){for(j=0;jdot;j++)printf(%f,v[i][j]);printf(\n);}printf(修改后的隐藏层权矩阵:\n);//输出修改后的隐藏层权矩阵for(i=0;idot;i++){for(j=0;jdot;j++)printf(%f,u[i][j]);printf(\n);}printf(修改后的输出层权矩阵:\n);//输出修改后的输出权矩阵for(i=0;idot;i++){for(j=0;jOUT;j++)printf(%f,w[i][j]);printf(\n);}for(i=0;iIN;i++)//将修改后的输入层权矩阵返回给bp结构体for(j=0;jdot;j++)(*bp).v[i][j]=v[i][j];for(i=0;idot;i++)//将修改后的隐藏层权矩阵返回给bp结构体for(j=0;jdot;j++)(*bp).u[i][j]=u[i][j];for(i=0;idot;i++)//将修改后的输出层权矩阵返回给bp结构体for(j=0;jOUT;j++)(*bp).w[i][j]=w[i][j];printf(bp网络训练结束!\n);}voidTest_Bp(bp_net*bp)//使用bp网络测试结果{floatInput[IN];//输入实例doubleOutput_In[dot_MAX];//输入层输出doubleOutput_Hi[dot_MAX];//隐藏层输出doubleOutput_Ou[OUT];//输出层输出doubletemp;while(1){printf(请输入一个实例:\n);inti,j;for(i=0;iIN;i++)scanf(%f,&Input[i]);for(i=0;i(*bp).dot;i++)//计算输入层输出{temp=0;for(j=0;jIN;j++)temp+=Input[j]*(*bp).v[j][i];Output_In[i]=fnet(temp);}for(i=0;i(*bp).dot;i++)//计算隐藏层输出{temp=0;for(j=0;j(*bp).dot;j++)temp+=Output_In[j]*(*bp).u[j][i];Output_Hi[i]=fnet(temp);}for(i=0;iOUT;i++)//计算输出层输出{temp=0;for(j=0;j(*bp).dot;j++)temp+=Output_Hi[j]*(*bp).w[j][i];Output_Ou[i]=fnet(temp);}printf(bp网络计算结果:\n);printf(\n);for(i=0;iOUT;i++){printf(%.6f,Output_Ou[i]);if(Output_Ou[i]=1)printf(肯定是!\n);elseswitch((i
本文标题:Bp网络算法源代码
链接地址:https://www.777doc.com/doc-2901024 .html