⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bp.cpp

📁 简单实用的BP神经网络训练测试程序
💻 CPP
字号:
#include <iostream.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NULL 0              //网络层数
#define IN 2               //输入层神经元个数 2
#define HN 2               //隐含层神经元个数    2
#define ON 1                //输出层神经元个数    1
#define MODEL 4      //输入模式 4
static int p[IN][MODEL]={{0,0,1,1},{0,1,0,1}};      //输入模式p
static int d[MODEL]={0,1,1,0};         //没组对应的期望输出d
double w[IN][HN] ,dw[IN][HN],b[HN],db[HN];    //隐层权值w及其调整量bw,阈值b及其调整量db
double v[HN][ON] ,dv[HN][ON],r[ON],dr[ON];    //隐层权值v及其调整量bv,阈值b及其调整量dv
double a1[IN][MODEL],a2[MODEL];          //隐层个神经元输出a1(2行4列),输出各层各神经元输出a2(1行4列)
double e2[MODEL],e1[IN][MODEL];        //输出层至隐层反向误差e2,隐层至输出层反向误差e1
double e[MODEL],E;    //输出误差e,总平方误差E
double EE=0.0001;     //误差指标
double lr=0.75; //学习速率lr
int i,j,k,t,x,n;
double h;     //中间过程量h
//程序批处理
void Init()    //初始化权值阈值为随机输 -1<(w,b,v,r)<1
{
  for(i=0;i<IN;i++)
     for(j=0;j<HN;j++)
     {
      w[i][j]=2.00*rand()/RAND_MAX-1.00;
     }
     for(j=0;j<HN;j++)
     for(t=0;t<ON;t++)
     {
      v[j][t]=2.00*rand()/RAND_MAX-1.00;
     }
  for(j=0;j<HN;j++)
  {
     b[j]=2.00*rand()/RAND_MAX-1.00;
  }
  for(t=0;t<ON;t++)
  {
     r[t]=2.00*rand()/RAND_MAX-1.00;
  }
}
void Hout()   //隐层的输出a1
{
   for(j=0;j<HN;j++)
       for(k=0;k<MODEL;k++)
       {
          h=0.00;
          for(i=0;i<IN;i++)
          {
             h=h+w[i][j]*p[i][k];    
          }
       a1[j][k]=1.00/(1.00+exp(-(h+b[j])));
       }
}
void Oout()   //输出层的输出a2
{
   for(t=0;t<ON;t++)
       for(k=0;k<MODEL;k++)
       {
          h=0.00;
          for(j=0;j<HN;j++)
          {
             h=h+v[j][t]*a1[j][k];    
          }
       a2[k]=1.00/(1.00+exp(-(h+r[t])));
       }
}
void Tolerate()  //输出误差e
{
   E=0;
   for(k=0;k<MODEL;k++)
   {
      e[k]=d[k]-a2[k];
      E=E+e[k]*e[k]/2.0;
   }
   cout<<"E="<<E<<'/n';
}
void Btolerate()  //反向误差e1,e2
{
   for(k=0;k<MODEL;k++)
   {
      e2[k]=a2[k]*(1-a2[k])*e[k];
     
   }
  for(t=0;t<ON;t++)
    for(j=0;j<HN;j++)
       for(k=0;k<MODEL;k++)
       {
         e1[j][k]=a1[j][k]*(1.00-a1[j][k])*e2[k]*v[j][t];
       }
}
void Change()   //权值阈值的调整
{
   //所有隐层至输入层反向误差e1乘于学习速率lr
   for(j=0;j<HN;j++)
      for(k=0;k<MODEL;k++)
      {
         e1[j][k]=lr*e1[j][k];
      }
   //输入层至隐层权值w调整
    for(i=0;i<IN;i++)
       for(j=0;j<HN;j++)
       {
          dw[i][j]=0.00;
		  for(k=0;k<MODEL;k++)         
		  {
             dw[i][j]+=e1[j][k]*p[i][k];
          }
          w[i][j]+=dw[i][j];
        }
   //隐层阈值b调整
   for(j=0;j<HN;j++)
   {
      db[j]=0.00;
      for(k=0;k<MODEL;k++)
      {
      db[j]=db[j]+e1[j][k];   //求所有反向误差e1之和
      }
      b[j]=b[j]+db[j];
   }
   //所有输出层至隐层反向误差e2乘以学习速率lr
   for(k=0;k<MODEL;k++)
   {
      e2[k]=lr*e2[k];
   }
   //隐层至输出层权值v调整
   for(t=0;t<ON;t++)
       for(j=0;j<HN;j++)
       {
         dv[j][t]=0.0;
         for(k=0;k<MODEL;k++)
         {
             dv[j][t]=dv[j][t]+e2[k]*a1[j][k];
         }
         v[j][t]=v[j][t]+dv[j][t];
       }
   //输出层阈值r的调整
   for(t=0;t<ON;t++)
   {
       dr[t]=0.00;
       for(k=0;k<MODEL;k++)
       {
           dr[t]=dr[t]+e2[k];  //求所有反向误差e2之和
       }
       r[t]=r[t]+dr[t];
   }
}
void Out()   //计算训练后的输出结果
{
   for(j=0;j<HN;j++)
       for(k=0;k<MODEL;k++)
       {
           h=0.00;
           for(i=0;i<IN;i++)
           {
               h=h+w[i][j]*p[i][k];           
           }
       a1[j][k]=1.00/(1.00+exp(-(h+b[j])));
       }
   for(t=0;t<ON;t++)
       for(k=0;k<MODEL;k++)
       {
           h=0.00;
           for(j=0;j<HN;j++)
           {
                h=h+v[j][t]*a1[j][k];                
           }
       a2[k]=1.00/(1.00+exp(-(h+r[t])));
                
       }
}
void Oinit()     //输出训练结束的权值和阈值
{
     cout<<"输入层至隐层权值w:"<<'\n';
     for(i=0;i<IN;i++)
     {
         for(j=0;j<HN;j++)
         {
             cout<<"w["<<i<<"]["<<j<<"]="<<w[i][j]<<'\t';
         }
         cout<<'\n';
     }
    cout<<"隐层阈值b:"<<'\n';
    for(j=0;j<HN;j++)
    {
        cout<<"b["<<j<<"]="<<b[j]<<'\t';
    }
    cout<<'\n';
    cout<<"隐层至输出层权值v:"<<'\n';
    for(j=0;j<HN;j++)
        for(t=0;t<ON;t++)
        {  
            cout<<"v["<<j<<"]["<<t<<"]="<<v[j][t]<<'\t';
        }
    cout<<'\n';
    cout<<"输出层阈值r:"<<'\n';
    for(t=0;t<ON;t++)
    {
        cout<<"r["<<t<<"]="<<r[t]<<'\t';
    }
    cout<<'\n';
}
void Nout_tolerate()   //训练结果后期望值和网络实际输出误差e
{
     for(k=0;k<MODEL;k++)
     {
         e[k]=d[k]-a2[k];
     }
}
void main()  //主程序
{
     FILE *fp1,*fp2,*fp3,*fp4,*fp5;
     Init();
     n=0;
     fp1=fopen("w00.txt","w");
     fp2=fopen("b0.txt","w");
     fp3=fopen("v00.txt","w");
     fp4=fopen("r0.txt","w");
     fp5=fopen("xor.txt","w");
     do
     {
     Hout();
     Oout();
     Tolerate();
     Btolerate();
     Change();
     fprintf(fp1,"%d%f\n",n,w[0][0]);
     fprintf(fp2,"%d%f\n",n,b[0]);
     fprintf(fp3,"%d%f\n",n,v[0][0]);
     fprintf(fp4,"%d%f\n",n,r[0]);
     fprintf(fp5,"%d%f%f%f%f\n",n,w[0][0],b[0],v[0][0],r[0]);
     n++;
}while(E>EE); //一直训练到吗组误差指标EE为止
cout<<"训练次数n="<<n<<'\t'<<'\n';
      Out();
      Oinit();
      Nout_tolerate();
      cout<<"网络输出"<<"   "<<"期望输出"<<"   "<<"网络输出"<<"   "<<"期望输出与实际值误差"<<'\n';
      double O[4][5]={{0,0,0,a2[0],e[0]},{0,1,1,a2[1],e[1]},{1,0,1,a2[2],e[2]},{1,1,0,a2[3],e[3]}};
      for(i=0;i<4;i++)
      {  
          for(j=0;j<5;j++)
          {
              cout<<O[i][j]<<'t';
          }
          cout<<'\n';
       }
       cout<<'\n';
       fclose(fp1); fclose(fp2); fclose(fp3); fclose(fp4); fclose(fp5);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -