BP神经网络学习和c++例子程序代码

2024-05-25 00:48

本文主要是介绍BP神经网络学习和c++例子程序代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



转自:http://blog.csdn.net/luxiaoxun/article/details/7649945

BP(Back Propagation)网络是1986年由Rumelhart和McCelland为首的科学家小组提出,是一种按误差逆传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一。BP网络能学习和存贮大量的输入输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。它的学习规则是使用最速下降法(梯度法),通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小。BP神经网络模型拓扑结构包括输入层(input layer)、隐层(hide layer)和输出层(output layer)。

以下是我收集的一些关于神经网络的文章:

神经网络介绍——利用反向传播算法的模式学习
http://www.ibm.com/developerworks/cn/linux/other/l-neural/index.html

人工智能 Java 坦克机器人系列: 神经网络,上部
http://www.ibm.com/developerworks/cn/java/j-lo-robocode3/index.html
人工智能 Java 坦克机器人系列: 神经网络,下部
http://www.ibm.com/developerworks/cn/java/j-lo-robocode4/

使用 Python 构造神经网络--Hopfield 网络可以重构失真的图案并消除噪声
http://www.ibm.com/developerworks/cn/linux/l-neurnet/

提供一个Matlab的BP神经网络的基础资料
http://www.cnblogs.com/galaxyprince/archive/2010/12/20/1911157.html

http://www.codeproject.com/KB/recipes/aforge_neuro.aspx
作者已经给出好几种形式的应用例子

以下C++代码实现了BP网络,通过8个3位二进制样本对应一个期望输出,训练BP网络,最后训练好的网络可以将输入的三位二进制数对应输出一位十进制数。

[cpp] view plain copy print ?
  1. //将三位二进制数转为一位十进制数  
  2.   
  3. #include<iostream>  
  4. #include<cmath>  
  5. using namespace std;  
  6.   
  7. #define  innode 3  //输入结点数  
  8. #define  hidenode 10//隐含结点数  
  9. #define  outnode 1 //输出结点数  
  10. #define  trainsample 8//BP训练样本数  
  11. class BpNet  
  12. {  
  13. public:  
  14.     void train(double p[trainsample][innode ],double t[trainsample][outnode]);//Bp训练  
  15.     double p[trainsample][innode];     //输入的样本  
  16.     double t[trainsample][outnode];    //样本要输出的  
  17.   
  18.     double *recognize(double *p);//Bp识别  
  19.   
  20.     void writetrain(); //写训练完的权值  
  21.     void readtrain(); //读训练好的权值,这使的不用每次去训练了,只要把训练最好的权值存下来就OK  
  22.   
  23.     BpNet();  
  24.     virtual ~BpNet();  
  25.   
  26. public:  
  27.     void init();  
  28.     double w[innode][hidenode];//隐含结点权值  
  29.     double w1[hidenode][outnode];//输出结点权值  
  30.     double b1[hidenode];//隐含结点阀值  
  31.     double b2[outnode];//输出结点阀值  
  32.   
  33.     double rate_w; //权值学习率(输入层-隐含层)  
  34.     double rate_w1;//权值学习率 (隐含层-输出层)  
  35.     double rate_b1;//隐含层阀值学习率  
  36.     double rate_b2;//输出层阀值学习率  
  37.   
  38.     double e;//误差计算  
  39.     double error;//允许的最大误差  
  40.     double result[outnode];// Bp输出  
  41. };  
  42.   
  43. BpNet::BpNet()  
  44. {  
  45.     error=1.0;  
  46.     e=0.0;  
  47.   
  48.     rate_w=0.9;  //权值学习率(输入层--隐含层)  
  49.     rate_w1=0.9; //权值学习率 (隐含层--输出层)  
  50.     rate_b1=0.9; //隐含层阀值学习率  
  51.     rate_b2=0.9; //输出层阀值学习率  
  52. }  
  53.   
  54. BpNet::~BpNet()  
  55. {  
  56.   
  57. }  
  58.   
  59. void winit(double w[],int n) //权值初始化  
  60. {  
  61.   for(int i=0;i<n;i++)  
  62.     w[i]=(2.0*(double)rand()/RAND_MAX)-1;  
  63. }  
  64.   
  65. void BpNet::init()  
  66. {  
  67.     winit((double*)w,innode*hidenode);  
  68.     winit((double*)w1,hidenode*outnode);  
  69.     winit(b1,hidenode);  
  70.     winit(b2,outnode);  
  71. }  
  72.   
  73. void BpNet::train(double p[trainsample][innode],double t[trainsample][outnode])  
  74. {  
  75.     double pp[hidenode];//隐含结点的校正误差  
  76.     double qq[outnode];//希望输出值与实际输出值的偏差  
  77.     double yd[outnode];//希望输出值  
  78.   
  79.     double x[innode]; //输入向量  
  80.     double x1[hidenode];//隐含结点状态值  
  81.     double x2[outnode];//输出结点状态值  
  82.     double o1[hidenode];//隐含层激活值  
  83.     double o2[hidenode];//输出层激活值  
  84.   
  85.     for(int isamp=0;isamp<trainsample;isamp++)//循环训练一次样品  
  86.     {  
  87.         for(int i=0;i<innode;i++)  
  88.             x[i]=p[isamp][i]; //输入的样本  
  89.         for(int i=0;i<outnode;i++)  
  90.             yd[i]=t[isamp][i]; //期望输出的样本  
  91.   
  92.         //构造每个样品的输入和输出标准  
  93.         for(int j=0;j<hidenode;j++)  
  94.         {  
  95.             o1[j]=0.0;  
  96.             for(int i=0;i<innode;i++)  
  97.                 o1[j]=o1[j]+w[i][j]*x[i];//隐含层各单元输入激活值  
  98.             x1[j]=1.0/(1+exp(-o1[j]-b1[j]));//隐含层各单元的输出  
  99.             //    if(o1[j]+b1[j]>0) x1[j]=1;  
  100.             //else x1[j]=0;  
  101.         }  
  102.   
  103.         for(int k=0;k<outnode;k++)  
  104.         {  
  105.             o2[k]=0.0;  
  106.             for(int j=0;j<hidenode;j++)  
  107.                 o2[k]=o2[k]+w1[j][k]*x1[j]; //输出层各单元输入激活值  
  108.             x2[k]=1.0/(1.0+exp(-o2[k]-b2[k])); //输出层各单元输出  
  109.             //    if(o2[k]+b2[k]>0) x2[k]=1;  
  110.             //    else x2[k]=0;  
  111.         }  
  112.   
  113.         for(int k=0;k<outnode;k++)  
  114.         {  
  115.             qq[k]=(yd[k]-x2[k])*x2[k]*(1-x2[k]); //希望输出与实际输出的偏差  
  116.             for(int j=0;j<hidenode;j++)  
  117.                 w1[j][k]+=rate_w1*qq[k]*x1[j];  //下一次的隐含层和输出层之间的新连接权  
  118.         }  
  119.   
  120.         for(int j=0;j<hidenode;j++)  
  121.         {  
  122.             pp[j]=0.0;  
  123.             for(int k=0;k<outnode;k++)  
  124.                 pp[j]=pp[j]+qq[k]*w1[j][k];  
  125.             pp[j]=pp[j]*x1[j]*(1-x1[j]); //隐含层的校正误差  
  126.   
  127.             for(int i=0;i<innode;i++)  
  128.                 w[i][j]+=rate_w*pp[j]*x[i]; //下一次的输入层和隐含层之间的新连接权  
  129.         }  
  130.   
  131.         for(int k=0;k<outnode;k++)  
  132.         {  
  133.             e+=fabs(yd[k]-x2[k])*fabs(yd[k]-x2[k]); //计算均方差  
  134.         }  
  135.         error=e/2.0;  
  136.   
  137.         for(int k=0;k<outnode;k++)  
  138.             b2[k]=b2[k]+rate_b2*qq[k]; //下一次的隐含层和输出层之间的新阈值  
  139.         for(int j=0;j<hidenode;j++)  
  140.             b1[j]=b1[j]+rate_b1*pp[j]; //下一次的输入层和隐含层之间的新阈值  
  141.     }  
  142. }  
  143.   
  144. double *BpNet::recognize(double *p)  
  145. {  
  146.     double x[innode]; //输入向量  
  147.     double x1[hidenode]; //隐含结点状态值  
  148.     double x2[outnode]; //输出结点状态值  
  149.     double o1[hidenode]; //隐含层激活值  
  150.     double o2[hidenode]; //输出层激活值  
  151.   
  152.     for(int i=0;i<innode;i++)  
  153.         x[i]=p[i];  
  154.   
  155.     for(int j=0;j<hidenode;j++)  
  156.     {  
  157.         o1[j]=0.0;  
  158.         for(int i=0;i<innode;i++)  
  159.             o1[j]=o1[j]+w[i][j]*x[i]; //隐含层各单元激活值  
  160.         x1[j]=1.0/(1.0+exp(-o1[j]-b1[j])); //隐含层各单元输出  
  161.         //if(o1[j]+b1[j]>0) x1[j]=1;  
  162.         //    else x1[j]=0;  
  163.     }  
  164.   
  165.     for(int k=0;k<outnode;k++)  
  166.     {  
  167.         o2[k]=0.0;  
  168.         for(int j=0;j<hidenode;j++)  
  169.             o2[k]=o2[k]+w1[j][k]*x1[j];//输出层各单元激活值  
  170.         x2[k]=1.0/(1.0+exp(-o2[k]-b2[k]));//输出层各单元输出  
  171.         //if(o2[k]+b2[k]>0) x2[k]=1;  
  172.         //else x2[k]=0;  
  173.     }  
  174.   
  175.     for(int k=0;k<outnode;k++)  
  176.     {  
  177.         result[k]=x2[k];  
  178.     }  
  179.     return result;  
  180. }  
  181.   
  182. void BpNet::writetrain()  
  183. {  
  184.     FILE *stream0;  
  185.     FILE *stream1;  
  186.     FILE *stream2;  
  187.     FILE *stream3;  
  188.     int i,j;  
  189.     //隐含结点权值写入  
  190.     if(( stream0 = fopen("w.txt""w+" ))==NULL)  
  191.     {  
  192.         cout<<"创建文件失败!";  
  193.         exit(1);  
  194.     }  
  195.     for(i=0;i<innode;i++)  
  196.     {  
  197.         for(j=0;j<hidenode;j++)  
  198.         {  
  199.             fprintf(stream0, "%f\n", w[i][j]);  
  200.         }  
  201.     }  
  202.     fclose(stream0);  
  203.   
  204.     //输出结点权值写入  
  205.     if(( stream1 = fopen("w1.txt""w+" ))==NULL)  
  206.     {  
  207.         cout<<"创建文件失败!";  
  208.         exit(1);  
  209.     }  
  210.     for(i=0;i<hidenode;i++)  
  211.     {  
  212.         for(j=0;j<outnode;j++)  
  213.         {  
  214.             fprintf(stream1, "%f\n",w1[i][j]);  
  215.         }  
  216.     }  
  217.     fclose(stream1);  
  218.   
  219.     //隐含结点阀值写入  
  220.     if(( stream2 = fopen("b1.txt""w+" ))==NULL)  
  221.     {  
  222.         cout<<"创建文件失败!";  
  223.         exit(1);  
  224.     }  
  225.     for(i=0;i<hidenode;i++)  
  226.         fprintf(stream2, "%f\n",b1[i]);  
  227.     fclose(stream2);  
  228.   
  229.     //输出结点阀值写入  
  230.     if(( stream3 = fopen("b2.txt""w+" ))==NULL)  
  231.     {  
  232.         cout<<"创建文件失败!";  
  233.         exit(1);  
  234.     }  
  235.     for(i=0;i<outnode;i++)  
  236.         fprintf(stream3, "%f\n",b2[i]);  
  237.     fclose(stream3);  
  238.   
  239. }  
  240.   
  241. void BpNet::readtrain()  
  242. {  
  243.     FILE *stream0;  
  244.     FILE *stream1;  
  245.     FILE *stream2;  
  246.     FILE *stream3;  
  247.     int i,j;  
  248.   
  249.     //隐含结点权值读出  
  250.     if(( stream0 = fopen("w.txt""r" ))==NULL)  
  251.     {  
  252.         cout<<"打开文件失败!";  
  253.         exit(1);  
  254.     }  
  255.     float  wx[innode][hidenode];  
  256.     for(i=0;i<innode;i++)  
  257.     {  
  258.         for(j=0;j<hidenode;j++)  
  259.         {  
  260.             fscanf(stream0, "%f", &wx[i][j]);  
  261.             w[i][j]=wx[i][j];  
  262.         }  
  263.     }  
  264.     fclose(stream0);  
  265.   
  266.     //输出结点权值读出  
  267.     if(( stream1 = fopen("w1.txt""r" ))==NULL)  
  268.     {  
  269.         cout<<"打开文件失败!";  
  270.         exit(1);  
  271.     }  
  272.     float  wx1[hidenode][outnode];  
  273.     for(i=0;i<hidenode;i++)  
  274.     {  
  275.         for(j=0;j<outnode;j++)  
  276.         {  
  277.             fscanf(stream1, "%f", &wx1[i][j]);  
  278.             w1[i][j]=wx1[i][j];  
  279.         }  
  280.     }  
  281.     fclose(stream1);  
  282.   
  283.     //隐含结点阀值读出  
  284.     if(( stream2 = fopen("b1.txt""r" ))==NULL)  
  285.     {  
  286.         cout<<"打开文件失败!";  
  287.         exit(1);  
  288.     }  
  289.     float xb1[hidenode];  
  290.     for(i=0;i<hidenode;i++)  
  291.     {  
  292.         fscanf(stream2, "%f",&xb1[i]);  
  293.         b1[i]=xb1[i];  
  294.     }  
  295.     fclose(stream2);  
  296.   
  297.     //输出结点阀值读出  
  298.     if(( stream3 = fopen("b2.txt""r" ))==NULL)  
  299.     {  
  300.         cout<<"打开文件失败!";  
  301.         exit(1);  
  302.     }  
  303.     float xb2[outnode];  
  304.     for(i=0;i<outnode;i++)  
  305.     {  
  306.         fscanf(stream3, "%f",&xb2[i]);  
  307.         b2[i]=xb2[i];  
  308.     }  
  309.     fclose(stream3);  
  310. }  
  311.   
  312.   
  313. //输入样本  
  314. double X[trainsample][innode]= {  
  315.     {0,0,0},{0,0,1},{0,1,0},{0,1,1},{1,0,0},{1,0,1},{1,1,0},{1,1,1}  
  316.     };  
  317. //期望输出样本  
  318. double Y[trainsample][outnode]={  
  319.     {0},{0.1429},{0.2857},{0.4286},{0.5714},{0.7143},{0.8571},{1.0000}  
  320.     };  
  321.   
  322. int main()  
  323. {  
  324.     BpNet bp;  
  325.     bp.init();  
  326.     int times=0;  
  327.     while(bp.error>0.0001)  
  328.     {  
  329.         bp.e=0.0;  
  330.         times++;  
  331.         bp.train(X,Y);  
  332.         cout<<"Times="<<times<<" error="<<bp.error<<endl;  
  333.     }  
  334.     cout<<"trainning complete..."<<endl;  
  335.     double m[innode]={1,1,1};  
  336.     double *r=bp.recognize(m);  
  337.     for(int i=0;i<outnode;++i)  
  338.        cout<<bp.result[i]<<" ";  
  339.     double cha[trainsample][outnode];  
  340.     double mi=100;  
  341.     double index;  
  342.     for(int i=0;i<trainsample;i++)  
  343.     {  
  344.         for(int j=0;j<outnode;j++)  
  345.         {  
  346.             //找差值最小的那个样本  
  347.             cha[i][j]=(double)(fabs(Y[i][j]-bp.result[j]));  
  348.             if(cha[i][j]<mi)  
  349.             {  
  350.                 mi=cha[i][j];  
  351.                 index=i;  
  352.             }  
  353.         }  
  354.     }  
  355.     for(int i=0;i<innode;++i)  
  356.        cout<<m[i];  
  357.     cout<<" is "<<index<<endl;  
  358.     cout<<endl;  
  359.     return 0;  
  360. }  
//将三位二进制数转为一位十进制数#include<iostream>
#include<cmath>
using namespace std;#define  innode 3  //输入结点数
#define  hidenode 10//隐含结点数
#define  outnode 1 //输出结点数
#define  trainsample 8//BP训练样本数
class BpNet
{
public:void train(double p[trainsample][innode ],double t[trainsample][outnode]);//Bp训练double p[trainsample][innode];     //输入的样本double t[trainsample][outnode];    //样本要输出的double *recognize(double *p);//Bp识别void writetrain(); //写训练完的权值void readtrain(); //读训练好的权值,这使的不用每次去训练了,只要把训练最好的权值存下来就OKBpNet();virtual ~BpNet();public:void init();double w[innode][hidenode];//隐含结点权值double w1[hidenode][outnode];//输出结点权值double b1[hidenode];//隐含结点阀值double b2[outnode];//输出结点阀值double rate_w; //权值学习率(输入层-隐含层)double rate_w1;//权值学习率 (隐含层-输出层)double rate_b1;//隐含层阀值学习率double rate_b2;//输出层阀值学习率double e;//误差计算double error;//允许的最大误差double result[outnode];// Bp输出
};BpNet::BpNet()
{error=1.0;e=0.0;rate_w=0.9;  //权值学习率(输入层--隐含层)rate_w1=0.9; //权值学习率 (隐含层--输出层)rate_b1=0.9; //隐含层阀值学习率rate_b2=0.9; //输出层阀值学习率
}BpNet::~BpNet()
{}void winit(double w[],int n) //权值初始化
{for(int i=0;i<n;i++)w[i]=(2.0*(double)rand()/RAND_MAX)-1;
}void BpNet::init()
{winit((double*)w,innode*hidenode);winit((double*)w1,hidenode*outnode);winit(b1,hidenode);winit(b2,outnode);
}void BpNet::train(double p[trainsample][innode],double t[trainsample][outnode])
{double pp[hidenode];//隐含结点的校正误差double qq[outnode];//希望输出值与实际输出值的偏差double yd[outnode];//希望输出值double x[innode]; //输入向量double x1[hidenode];//隐含结点状态值double x2[outnode];//输出结点状态值double o1[hidenode];//隐含层激活值double o2[hidenode];//输出层激活值for(int isamp=0;isamp<trainsample;isamp++)//循环训练一次样品{for(int i=0;i<innode;i++)x[i]=p[isamp][i]; //输入的样本for(int i=0;i<outnode;i++)yd[i]=t[isamp][i]; //期望输出的样本//构造每个样品的输入和输出标准for(int j=0;j<hidenode;j++){o1[j]=0.0;for(int i=0;i<innode;i++)o1[j]=o1[j]+w[i][j]*x[i];//隐含层各单元输入激活值x1[j]=1.0/(1+exp(-o1[j]-b1[j]));//隐含层各单元的输出//    if(o1[j]+b1[j]>0) x1[j]=1;//else x1[j]=0;}for(int k=0;k<outnode;k++){o2[k]=0.0;for(int j=0;j<hidenode;j++)o2[k]=o2[k]+w1[j][k]*x1[j]; //输出层各单元输入激活值x2[k]=1.0/(1.0+exp(-o2[k]-b2[k])); //输出层各单元输出//    if(o2[k]+b2[k]>0) x2[k]=1;//    else x2[k]=0;}for(int k=0;k<outnode;k++){qq[k]=(yd[k]-x2[k])*x2[k]*(1-x2[k]); //希望输出与实际输出的偏差for(int j=0;j<hidenode;j++)w1[j][k]+=rate_w1*qq[k]*x1[j];  //下一次的隐含层和输出层之间的新连接权}for(int j=0;j<hidenode;j++){pp[j]=0.0;for(int k=0;k<outnode;k++)pp[j]=pp[j]+qq[k]*w1[j][k];pp[j]=pp[j]*x1[j]*(1-x1[j]); //隐含层的校正误差for(int i=0;i<innode;i++)w[i][j]+=rate_w*pp[j]*x[i]; //下一次的输入层和隐含层之间的新连接权}for(int k=0;k<outnode;k++){e+=fabs(yd[k]-x2[k])*fabs(yd[k]-x2[k]); //计算均方差}error=e/2.0;for(int k=0;k<outnode;k++)b2[k]=b2[k]+rate_b2*qq[k]; //下一次的隐含层和输出层之间的新阈值for(int j=0;j<hidenode;j++)b1[j]=b1[j]+rate_b1*pp[j]; //下一次的输入层和隐含层之间的新阈值}
}double *BpNet::recognize(double *p)
{double x[innode]; //输入向量double x1[hidenode]; //隐含结点状态值double x2[outnode]; //输出结点状态值double o1[hidenode]; //隐含层激活值double o2[hidenode]; //输出层激活值for(int i=0;i<innode;i++)x[i]=p[i];for(int j=0;j<hidenode;j++){o1[j]=0.0;for(int i=0;i<innode;i++)o1[j]=o1[j]+w[i][j]*x[i]; //隐含层各单元激活值x1[j]=1.0/(1.0+exp(-o1[j]-b1[j])); //隐含层各单元输出//if(o1[j]+b1[j]>0) x1[j]=1;//    else x1[j]=0;}for(int k=0;k<outnode;k++){o2[k]=0.0;for(int j=0;j<hidenode;j++)o2[k]=o2[k]+w1[j][k]*x1[j];//输出层各单元激活值x2[k]=1.0/(1.0+exp(-o2[k]-b2[k]));//输出层各单元输出//if(o2[k]+b2[k]>0) x2[k]=1;//else x2[k]=0;}for(int k=0;k<outnode;k++){result[k]=x2[k];}return result;
}void BpNet::writetrain()
{FILE *stream0;FILE *stream1;FILE *stream2;FILE *stream3;int i,j;//隐含结点权值写入if(( stream0 = fopen("w.txt", "w+" ))==NULL){cout<<"创建文件失败!";exit(1);}for(i=0;i<innode;i++){for(j=0;j<hidenode;j++){fprintf(stream0, "%f\n", w[i][j]);}}fclose(stream0);//输出结点权值写入if(( stream1 = fopen("w1.txt", "w+" ))==NULL){cout<<"创建文件失败!";exit(1);}for(i=0;i<hidenode;i++){for(j=0;j<outnode;j++){fprintf(stream1, "%f\n",w1[i][j]);}}fclose(stream1);//隐含结点阀值写入if(( stream2 = fopen("b1.txt", "w+" ))==NULL){cout<<"创建文件失败!";exit(1);}for(i=0;i<hidenode;i++)fprintf(stream2, "%f\n",b1[i]);fclose(stream2);//输出结点阀值写入if(( stream3 = fopen("b2.txt", "w+" ))==NULL){cout<<"创建文件失败!";exit(1);}for(i=0;i<outnode;i++)fprintf(stream3, "%f\n",b2[i]);fclose(stream3);}void BpNet::readtrain()
{FILE *stream0;FILE *stream1;FILE *stream2;FILE *stream3;int i,j;//隐含结点权值读出if(( stream0 = fopen("w.txt", "r" ))==NULL){cout<<"打开文件失败!";exit(1);}float  wx[innode][hidenode];for(i=0;i<innode;i++){for(j=0;j<hidenode;j++){fscanf(stream0, "%f", &wx[i][j]);w[i][j]=wx[i][j];}}fclose(stream0);//输出结点权值读出if(( stream1 = fopen("w1.txt", "r" ))==NULL){cout<<"打开文件失败!";exit(1);}float  wx1[hidenode][outnode];for(i=0;i<hidenode;i++){for(j=0;j<outnode;j++){fscanf(stream1, "%f", &wx1[i][j]);w1[i][j]=wx1[i][j];}}fclose(stream1);//隐含结点阀值读出if(( stream2 = fopen("b1.txt", "r" ))==NULL){cout<<"打开文件失败!";exit(1);}float xb1[hidenode];for(i=0;i<hidenode;i++){fscanf(stream2, "%f",&xb1[i]);b1[i]=xb1[i];}fclose(stream2);//输出结点阀值读出if(( stream3 = fopen("b2.txt", "r" ))==NULL){cout<<"打开文件失败!";exit(1);}float xb2[outnode];for(i=0;i<outnode;i++){fscanf(stream3, "%f",&xb2[i]);b2[i]=xb2[i];}fclose(stream3);
}//输入样本
double X[trainsample][innode]= {{0,0,0},{0,0,1},{0,1,0},{0,1,1},{1,0,0},{1,0,1},{1,1,0},{1,1,1}};
//期望输出样本
double Y[trainsample][outnode]={{0},{0.1429},{0.2857},{0.4286},{0.5714},{0.7143},{0.8571},{1.0000}};int main()
{BpNet bp;bp.init();int times=0;while(bp.error>0.0001){bp.e=0.0;times++;bp.train(X,Y);cout<<"Times="<<times<<" error="<<bp.error<<endl;}cout<<"trainning complete..."<<endl;double m[innode]={1,1,1};double *r=bp.recognize(m);for(int i=0;i<outnode;++i)cout<<bp.result[i]<<" ";double cha[trainsample][outnode];double mi=100;double index;for(int i=0;i<trainsample;i++){for(int j=0;j<outnode;j++){//找差值最小的那个样本cha[i][j]=(double)(fabs(Y[i][j]-bp.result[j]));if(cha[i][j]<mi){mi=cha[i][j];index=i;}}}for(int i=0;i<innode;++i)cout<<m[i];cout<<" is "<<index<<endl;cout<<endl;return 0;
}

这篇关于BP神经网络学习和c++例子程序代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1000011

相关文章

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的