`

BP算法

    博客分类:
  • c++
阅读更多
//---------------------------------------------------------------------------------------//
//           BP算法例子:用一个五层的神经网络去逼近函数            //
//           f(x1,x2)=pow(x1-1,4)+2*pow(x2,2)                                       //
//                                 作者:MaxMatrix                                             //
//                                 2004.5.9调通 运行于VC++6.0                     //
//--------------------------------------------------------------------------------------//

#include<iostream.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<fstream.h>
//---------------------------------------------------------------------
#define RANDOM rand()/32767.0  //0~1随机数生成函数
   
const int Layer_Max=5;//神经网络的层数

const double PI=3.1415927;//圆周率

const int Layer_number[Layer_Max]={2,4,4,2,1};//神经网络各层的神经元个数

const int Neural_Max=4;//神经网络各层最大神经元个数

const int InMax=21;//样本输入的个数

ofstream Out_W_File("All_W.txt",ios::out) ;
ofstream Out_Error("Error.txt",ios::out) ;

//定义类 BP
class BP
{
public:
 BP(); //BP类的构造函数

 void BP_Print();//打印权系数

 double F(double x);//神经元的激发函数

 double Y(double x1,double x2);//要逼近的函数
                               // 
 double NetWorkOut(int x1 , int x2);//网络输出,他的输入为
                              //第input个样本
 void AllLayer_D(int x1 , int x2);//求所有神经元的输出误差微分
 
 void Change_W();   //改变权系数
    
 void Train();     //训练函数

 void After_Train_Out(); //经过训练后,21样本的神经网络输出

 double Cost(double out,double Exp);//代价函数

private:
 double W[Layer_Max][Neural_Max][Neural_Max];//保存权系数
        //规定W[i][j][k]表示网络第i层的第j个神经元连接到
        //第i-1层第k个神经元的权系数
 double Input_Net[2][InMax];//21个样本输入,约定Input_Net[0][i]
                            //表示第i个样本的输入x1
                            //而 Input_Net[1][i]表示第i个样本的输入x2
 double Out_Exp[InMax][InMax];//期望输出
 
 double Layer_Node[Layer_Max][Neural_Max];//保存各神经元的输出
     //规定Layer_Node[i][j]表示第i层的第j个神经元的输出

 double D[Layer_Max][Neural_Max];//保存各神经元的误差微分
     //规定D[i][j]表示第i层第j个神经元的误差微分

 double Study_Speed;//学习速度
 
 double e;//误差
};

//构造函数,用来初始化权系数,输入,期望输出和学习速度
BP::BP()
{
 srand(time(NULL));//播种,以便产生随即数
 for(int i=1 ; i<Layer_Max ; i++)
 {
  for(int j=0 ; j<Layer_number[i] ; j++)
  {
      for(int k=0 ; k<Layer_number[i-1]+1 ; k++)
   {
    W[i][j][k] = RANDOM;//随机初始化权系数
    
   }
  //     Q[i][j] = RANDOM ;//初始化各神经元的阀值
  }
 }
//输入归和输出归一化
 for(int l=0 ; l<InMax ; l++)
 {
  Input_Net[0][l] = l * 0.05 ;//把0~1分成20等分,表示x1
  Input_Net[1][l] = 1 - l * 0.05 ;//表示x2
 }
 for(i=0 ; i<InMax ; i++)
 {
  for(int j=0 ; j<InMax ; j++)
  {
   Out_Exp[i][j] = Y(Input_Net[0][i],Input_Net[1][j]) ;//期望输出
      Out_Exp[i][j] = Out_Exp[i][j]/3.000000;//期望输出归一化
  }
 }
 
 Study_Speed=0.5;//初始化学习速度
 
 e=0.0001;//误差精度
 
  
}//end
//激发函数F()
double BP::F(double x)
{
 return(1.0/(1+exp(-x)));
}//end

//要逼近的函数Y()
//输入:两个浮点数
//输出:一个浮点数
double BP::Y(double x1,double x2)
{
 double temp;
 temp = pow(x1-1,4) + 2 * pow(x2,2);
 return temp;
}//end
//--------------------------------------------------------
//代价函数
double BP::Cost(double Out,double Exp)
{
 return(pow(Out-Exp,2));
}//end

//网络输出函数
//输入为:第input个样本
double BP::NetWorkOut(int x1 , int x2)
{
 int i,j,k;
 double N_node[Layer_Max][Neural_Max];
    //约定N_node[i][j]表示网络第i层的第j个神经元的总输入
 //第0层的神经元为输入,不用权系数和阀值,即输进什么即输出什么
 N_node[0][0] = Input_Net[0][x1] ;
 Layer_Node[0][0] = Input_Net[0][x1] ;
 N_node[0][1] = Input_Net[1][x2] ;
 Layer_Node[0][1] = Input_Net[1][x2] ;

 for(i=1 ; i<Layer_Max ; i++)//神经网络的第i层
 {
  for(j=0 ; j<Layer_number[i] ; j++)//Layer_number[i]为第i层的
  {                             //神经元个数
            N_node[i][j] = 0.0;
   for(k=0 ; k<Layer_number[i-1] ; k++)//Layer_number[i-1]
   {            //表示与第i层第j个神经元连接的上一层的
             //神经元个数
    
    //求上一层神经元对第i层第j个神经元的输入之和
    N_node[i][j]+=Layer_Node[i-1][k] * W[i][j][k];
    
   }
   N_node[i][j] = N_node[i][j]-W[i][j][k];//减去阀值

   //求Layer_Node[i][j],即第i层第j个神经元的输出
   Layer_Node[i][j] = F(N_node[i][j]);
  }
 }
 return Layer_Node[Layer_Max-1][0];//最后一层的输出
}//end

//求所有神经元的输出误差微分函数
//输入为:第input个样本
//计算误差微分并保存在D[][]数组中
void BP::AllLayer_D(int x1 , int x2)
{
 int i,j,k;
 double temp;
 D[Layer_Max-1][0] = Layer_Node[Layer_Max-1][0] *
                  (1-Layer_Node[Layer_Max-1][0])*
                  (Layer_Node[Layer_Max-1][0]-Out_Exp[x1][x2]);
 for(i=Layer_Max-1 ; i>0 ; i--)
 {
  for(j=0 ; j<Layer_number[i-1] ; j++)
  {
   temp = 0 ;
   for(k=0 ; k<Layer_number[i] ; k++)
   {
    temp = temp+W[i][k][j]*D[i][k] ;
   }
   D[i-1][j] = Layer_Node[i-1][j] * (1-Layer_Node[i-1][j])
            *temp ;
  }
 }
}//end
//修改权系数和阀值
void BP::Change_W()
{
 int i,j,k;
 for(i=1 ; i<Layer_Max ; i++)
 {
  for(j=0;j<Layer_number[i];j++)
  {
   for(k=0;k<Layer_number[i-1];k++)
   {
    //修改权系数
    W[i][j][k]=W[i][j][k]-Study_Speed*
            D[i][j]*Layer_Node[i-1][k];
                 
   }
   W[i][j][k]=W[i][j][k]+Study_Speed*D[i][j];//修改阀值
  }
 }
}//end
//训练函数
void BP::Train()
{
 int i,j;
 int ok=0;
 double Out;
 long int count=0;
 double err;
    ofstream Out_count("Out_count.txt",ios::out) ;
 //把其中的5个权系数的变化保存到文件里
 ofstream outWFile1("W[2][0][0].txt",ios::out) ;
 ofstream outWFile2("W[2][1][1].txt",ios::out) ;
 ofstream outWFile3("W[1][0][0].txt",ios::out) ;
 ofstream outWFile4("W[1][1][0].txt",ios::out) ;
 ofstream outWFile5("W[3][0][1].txt",ios::out) ;

 while(ok<441)
 {
  count++;
  //20个样本输入
  for(i=0,ok=0 ; i<InMax ; i++)
  {
   for(j=0 ; j<InMax ; j++)
   {
      Out = NetWorkOut(i,j);

      AllLayer_D(i,j);
   
      err = Cost(Out,Out_Exp[i][j]);//计算误差
            
      if(err<e) ok++;  //是否满足误差精度
 
      else Change_W();//否修改权系数和阀值
   }
       
  }
  if((count%1000)==0)//每1000次,保存权系数
  {
   cout<<count<<"     "<<err<<endl;
   Out_count<<count<<"," ;
   Out_Error<<err<<"," ;
   outWFile1<<W[2][0][0]<<"," ;
   outWFile2<<W[2][1][1]<<"," ;
   outWFile3<<W[1][0][0]<<"," ;
   outWFile4<<W[1][1][0]<<"," ;
   outWFile5<<W[3][0][1]<<"," ;
   for(int p=1 ; p<Layer_Max ; p++)
   {
    for(int j=0 ; j<Layer_number[p] ; j++)
    {
     for(int k=0 ; k<Layer_number[p-1]+1 ; k++)
     {
      Out_W_File<<'W'<<'['<<p<<']'
                  <<'['<<j<<']'
            <<'['<<k<<']'
            <<'='<<W[p][j][k]<<' '<<' ';
     }
    }
   }
   Out_W_File<<'\n'<<'\n' ;
  }

 }
 cout<<err<<endl;
}//end

//打印权系数
void BP::BP_Print()
{
 //打印权系数
 cout<<"训练后的权系数"<<endl;
 for(int i=1 ; i<Layer_Max ; i++)
 {
  for(int j=0 ; j<Layer_number[i] ; j++)
  {
      for(int k=0 ; k<Layer_number[i-1]+1 ; k++)
   {
    cout<<W[i][j][k]<<"         ";
   }
   cout<<endl;
  }
 }
 cout<<endl<<endl;
}//end

//把结果保存到文件
void BP::After_Train_Out()
{
 int i,j ;
 ofstream Out_x1("Out_x1.txt",ios::out) ;
 
 ofstream Out_x2("Out_x2.txt",ios::out) ;
 
 ofstream Out_Net("Out_Net.txt",ios::out) ;
 
 ofstream Out_Exp("Out_Exp.txt",ios::out) ;

 ofstream W_End("W_End.txt",ios::out) ;

 ofstream Q_End("Q_End.txt",ios::out) ;

 ofstream Array("Array.txt",ios::out) ;

 ofstream Out_x11("x1.txt",ios::out) ;

 ofstream Out_x22("x2.txt",ios::out) ;

 ofstream Result1("result1.txt",ios::out) ;

 ofstream Out_x111("x11.txt",ios::out) ;

 ofstream Out_x222("x22.txt",ios::out) ;

 ofstream Result2("result2.txt",ios::out) ;

 
 for( i=0 ; i<InMax ; i++)
 {
  for(j=0 ; j<InMax ; j++)
  {
   Out_x11<<Input_Net[0][i]<<',';
   Out_x22<<Input_Net[1][j]<<"," ;
   Result1<<3*NetWorkOut(i,j)<<"," ;
   Out_x1<<Input_Net[0][i]<<"," ;

   Array<<Input_Net[0][i]<<"        " ;
  
      Out_x2<<Input_Net[1][j]<<"," ;

   Array<<Input_Net[1][j]<<"        " ;

      Out_Net<<3*NetWorkOut(i,j)<<"," ;

   Array<<Y(Input_Net[0][i],Input_Net[1][j])<<"        " ;

      Out_Exp<<Y(Input_Net[0][i],Input_Net[1][j])<<"," ;

   Array<<3*NetWorkOut(i,j)<<"        " ;

   Array<<'\n' ;
  }
  Out_x1<<'\n' ;
  Out_x2<<'\n' ;
  Out_x11<<'\n';
  Out_x22<<'\n';
  Result1<<'\n' ;
  
 }
 for(j=0 ; j<InMax ; j++)
 {
  for(i=0 ; i<InMax ; i++)
  {
   Out_x111<<Input_Net[0][i]<<',';
   Out_x222<<Input_Net[1][j]<<"," ;
   Result2<<3*NetWorkOut(i,j)<<"," ;
  }
  Out_x111<<'\n';
  Out_x222<<'\n' ;
  Result2<<'\n' ;
 }


    //把经过训练后的权系数和阀值保存到文件里
    for(i=1 ; i<Layer_Max ; i++)
 {
  for(int j=0 ; j<Layer_number[i] ; j++)
  {
      for(int k=0 ; k<Layer_number[i-1]+1 ; k++)
   {
   
    W_End<<W[i][j][k]<<"," ;//保存权系数
   }
  }
 }//end for
    
}//end

void main(void)
{   
 BP B;//生成一个BP类对象B
 B.Train();//开始训练
 B.BP_Print();//把结果打印出来
 B.After_Train_Out();//把结果保存到文件

}//end 

 
分享到:
评论

相关推荐

    BP算法项目代码与实验报告-MFC实现

    BP算法,全称为Backpropagation(反向传播)算法,是神经网络中最为经典和广泛使用的训练算法之一。本项目代码实现了BP算法,并基于MFC(Microsoft Foundation Classes)框架进行开发,这是一种由微软提供的用于创建...

    BP算法神经网络.zip

    BP算法,全称为Backpropagation(反向传播)算法,是神经网络中最为经典的学习算法之一,主要用于训练多层前馈神经网络。该算法通过梯度下降法来更新网络中的权重和阈值,以最小化预测输出与实际目标之间的误差。在...

    BP算法对IRIS数据进行分类

    **BP算法介绍** BP(Backpropagation)算法,即反向传播算法,是深度学习领域中最经典的训练多层前馈神经网络的方法。该算法通过梯度下降法来更新网络权重,使得网络损失函数逐渐减小,从而达到优化模型的目的。在...

    BP算法的C++实现

    BP算法,全称为Backpropagation(反向传播)算法,是一种在人工神经网络(Artificial Neural Network, ANN)中广泛使用的训练方法。该算法通过迭代调整权重和阈值,使得网络预测输出与实际目标值之间的误差逐渐减小...

    模式识别实验二 (感知器算法与BP算法)

    在这个实验中,我们使用Matlab编写了BP算法的实现,没有依赖任何外部库,这样可以更好地理解算法的内部运作。 `pre`函数作为预测函数,负责根据训练好的模型对新数据进行预测。它接收输入数据,经过前向传播计算...

    压缩感知-CS-BP算法(基追踪算法)

    CS BP算法,即基于基追踪(Base Pursuit, BP)的压缩感知算法,是实现这一理论的一种有效方法。 压缩感知的核心思想在于,许多实际的信号都具有稀疏性,即它们可以用较少的非零元素来表示。例如,在图像中,大部分...

    BP算法C程序

    BP算法,全称为Backpropagation(反向传播)算法,是一种在神经网络中进行训练的常用方法,尤其在监督学习中被广泛应用。该算法通过梯度下降法来更新权重,以最小化损失函数,从而使神经网络能更好地拟合训练数据。...

    BP算法的原理及应用(手写数字识别及智能小车寻径问题)-机器学习课程报告及仿真程序.rar

    BP算法现已成为人工神经网络中最引人注意应用最广泛的算法之一。本文简要介绍了BP算法的基本思想、数学模型、算法推导及算法的实现过程。另外,本文给出了BP算法的两个应用,其一为手写数字的识别问题,其二为智能...

    神经网络bp算法ppt讲义

    BP算法的主要思想是将输出层和隐层的误差信号反传到网络中,以便调整权值。该算法的实现主要包括以下几个步骤: 1. 建立多层前馈网络模型,包括输入层、隐层和输出层。 2. 定义网络误差,包括输出层和隐层的误差...

    SAR(ISAR)成像BP算法RD算法,MATLAB 程序(含插值方法比较,有无滤波比较).zip

    BP算法(Back Projection Algorithm)是SAR/ISAR成像处理中常用的一种算法。它基于几何原理,将雷达接收到的回波数据重新投射到目标的实际位置上,形成二维图像。该算法的优势在于能够直接处理原始数据,无需进行...

    python实现bp算法详代码和描述.zip

    这个zip文件“python实现bp算法详代码和描述.zip”提供了Python语言实现BP算法的详细代码,以及两个用于测试的实例,即test1和test2。通过分析这些内容,我们可以深入了解BP算法的基本原理和Python实现。 BP算法...

    CNN算法中BP算法权重调整过程

    BP算法在CNN中的权重调整过程 BP算法(Back Propagation)是一种按误差逆传播算法,用于训练多层前馈神经网络。该算法能学习和存储大量的输入-输出模式映射关系,而事前无需揭示这种映射关系的数学方程。BP学习网络...

    BP算法.rar

    BP算法,全称为Backpropagation,是神经网络中的一种核心优化算法,主要用于训练多层前馈神经网络。在深度学习领域,BP算法的地位至关重要,因为它能够有效地更新网络中每个权重和偏置,使得网络能够逐步逼近目标...

    基于BP算法的多层感知器代码(Matlab)

    ### 基于BP算法的多层感知器代码解析与知识点总结 #### 一、BP算法简介 反向传播(Back Propagation, BP)算法是一种用于训练人工神经网络的监督学习方法,尤其适用于多层感知器(Multi-Layer Perceptron, MLP)。...

    BP算法ISAR成像基于FEKO仿真模型

    BP算法,全称为Backpropagation(反向传播)算法,是一种在神经网络中优化权重的常用方法,尤其在处理监督学习任务时效率较高。在本项目中,BP算法被应用于ISAR(Inverse Synthetic Aperture Radar,逆合成孔径雷达...

    神经网络程序弹性BP算法等

    这里提到的“弹性Bp算法”(Elastic BP)是对传统BP算法的一种改进,它引入了弹性项以增强算法的收敛速度和性能。在程序包中,我们看到多个与神经网络训练相关的文件,比如`newcf_bpm_1.m`、`newcf_bp_2_net.mat`等...

    几个BP算法matlab实现程序

    本资料提供的是几种MATLAB实现BP算法的程序编程,旨在帮助初学者更好地理解和应用BP算法。 **BP算法基础** BP算法基于反向传播的思想,它通过梯度下降法来更新网络权重,以最小化损失函数。BP网络通常由输入层、...

Global site tag (gtag.js) - Google Analytics