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

📄 main.cpp

📁 神经网络BP算法,实现数字识别 VC++代码实现
💻 CPP
📖 第 1 页 / 共 3 页
字号:
******************************************************************************/    
void InitializeApplication(NET* Net)     
{    
  INT  n, i,j;         
     
  for (n=0; n<NUM_DATA; n++) {    
      for (i=0; i<Y; i++) {    
          for (j=0; j<X; j++) {    
              if ( Pattern[n][i][j] == 'O' )    
                    Input[n][i*X+j]  = HI ;    
                else Input[n][i*X+j]  =LO ;     
              //NUM_DATA输入模式,输入层X*Y个神经元    
          }    
      }    
  }    
  f = fopen("result.txt", "w");    
}    
/******************************************************************************   
                      训练网络   
//将每个样本投入网络运作,Input是转换后的输入模式,Target为导师信号,通过布尔型   
//的Training和Ptotocoling值控制是否训练和打印输入/输出模式   
******************************************************************************/    
void SimulateNet(NET* Net, REAL* Input, REAL* Target, BOOL Training,BOOL Protocoling)    
{    
  REAL Output[M]; //用来记录输出层输出    
  SetInput(Net, Input,Protocoling);//设置输入层,获得输入层的输出    
  PropagateNet(Net);//计算网络各层的输出             
  GetOutput(Net, Output,Protocoling);//获得输出层的输出    
     
  ComputeOutputError(Net, Target);//计算输出层误差    
  if (Training) {    
    BackpropagateNet(Net);//误差反向传播    
    AdjustWeights(Net);//调整联接权    
  }    
}    
/******************************************************************************   
    获得输入层的输出            
******************************************************************************/    
void SetInput(NET* Net, REAL* Input,BOOL Protocoling)    
{    
  INT i;    
     
  for (i=1; i<=Net->InputLayer->Units; i++) {           
    Net->InputLayer->Output[i] = Input[i-1];      //输入层输入    
  }    
  if (Protocoling) {    
    WriteInput(Net, Input);//根据Protocoling值输出输入模式    
  }    
}    
/******************************************************************************   
//计算当前层的网络输出,upper 为当前层,LOWER为前一层                      
******************************************************************************/    
void PropagateLayer(NET* Net, LAYER* Lower, LAYER* Upper)     
{    
  INT  i,j;    
  REAL Sum;    
  
  for (i=1; i<=Upper->Units; i++) {    
    Sum = 0;    
    for (j=0; j<=Lower->Units; j++) {    
      Sum += Upper->Weight[i][j] * Lower->Output[j];  //计算本层的净输入    
    }     
  Upper->Activation[i] = Sum;//保留激活值    
  //计算本层的输出,激活函数必须是S形函数,这样才可导,这是BP网络的理论前提    
  Upper->Output[i]=1/(1+exp(-Sum));    
  }    
}    
/******************************************************************************   
              //计算整个网络各层的输出   
******************************************************************************/    
void PropagateNet(NET* Net)    
{    
  INT l;    
     
  for (l=0; l<NUM_LAYERS-1; l++) {    
    PropagateLayer(Net, Net->Layer[l], Net->Layer[l+1]);    
  }    
}    
/******************************************************************************   
//获得输出层的输出                
******************************************************************************/    
void GetOutput(NET* Net, REAL* Output,BOOL Protocoling)    
{    
  INT i;    
     
  for (i=1; i<=Net->OutputLayer->Units; i++) {     
    Output[i-1] = Net->OutputLayer->Output[i];//输出层输出    
  }    
  if (Protocoling) {    
    WriteOutput(Net, Output);//根据Protocoling值输出输出模式    
  }    
}    
/******************************************************************************   
                  //计算输出层误差,* Target是导师信号   
******************************************************************************/    
void ComputeOutputError(NET* Net, REAL* Target)     
{    
  INT  i;    
  REAL  Err,Out;    
     
  Net->Error = 0;    
  for (i=1; i<=Net->OutputLayer->Units; i++) {    
    Out = Net->OutputLayer->Output[i];//输出层的输出    
    Err = Target[i-1]-Out;//误差计算    
    Net->OutputLayer->Error[i] = Out * (1-Out) * Err;    
        //用delta规则计算误差,因为用了可导的s形函数    
    Net->Error += 0.5 * sqr(Err);//平方差公式    
  }    
}    
/******************************************************************************   
  //误差反向传播 Upper 为前层,Lower为后层 ,层数值大的为前层              
******************************************************************************/    
void BackpropagateLayer(NET* Net, LAYER* Upper, LAYER* Lower)     
{                                                                 
  INT  i,j;//循环变量    
  REAL Out, Err;    
     
  for (i=1; i<=Lower->Units; i++) {    
    Out = Lower->Output[i];//后层的输出    
    Err = 0;//用来记录隐含层输出的误差的估计值    
    for (j=1; j<=Upper->Units; j++) {    
      Err += Upper->Weight[j][i] * Upper->Error[j];    
    //误差的反馈,通过已经处理的前层的delta值和联接权去估计,有理论基础    
    }    
    Lower->Error[i] =Out * (1-Out) * Err;  //delta规则    
  }    
}    
/******************************************************************************   
              //整个网络误差的后传   
******************************************************************************/    
void BackpropagateNet(NET* Net)    
{    
  INT l;//循环变量    
     
  for (l=NUM_LAYERS-1; l>1; l--) {    
    BackpropagateLayer(Net, Net->Layer[l], Net->Layer[l-1]);//对每层处理    
  }    
}    
/******************************************************************************   
              //调整网络每一层的联接权   
******************************************************************************/    
void AdjustWeights(NET* Net)       
{    
  INT  l,i,j;//循环变量    
  REAL Out, Err, dWeight;    
  //记录后层的输出、当前层的输出误差、当前神经元联接权上次的调整量    
     
  for (l=1; l<NUM_LAYERS; l++) {    
    for (i=1; i<=Net->Layer[l]->Units; i++) {    
      for (j=0; j<=Net->Layer[l-1]->Units; j++) {    
        Out = Net->Layer[l-1]->Output[j];//后层的输出    
        Err = Net->Layer[l]->Error[i];//当前层的输出误差    
        dWeight = Net->Layer[l]->dWeight[i][j];    
        //将本神经元联接权上次的调整量取出,初始值为0,初始化网络时赋值的    
        Net->Layer[l]->Weight[i][j] += Net-> Eta * Err * Out + Net->Alpha * dWeight;    
        //Alpha为冲量参数,加快网络的收敛速度    
        Net->Layer[l]->dWeight[i][j] = Net->Eta * Err * Out;    
        //记录本次神经元联接权的调整量    
      }    
    }    
  }    
}    
/******************************************************************************   
//显示输入模式                
******************************************************************************/    
void WriteInput(NET* Net, REAL* Input)     
{    
  INT i;    
     
  for (i=0; i<N; i++) {    
    if (i%X == 0) {    
      fprintf(f, "\n");    
    }    
    fprintf(f, "%c", (Input[i] == HI) ? 'O' : ' ');    
  }    
  fprintf(f, " -> ");     
}    
/******************************************************************************   
//显示输出模式                
******************************************************************************/    
void WriteOutput(NET* Net, REAL* Output)    
{    
  INT  i;//循环变量    
  INT  Index;//用来记录最大输出值的下标,也就是最后识别的结果    
  REAL  MaxOutput;//用来记录最大的输出值    
       
  MaxOutput=0;//初始化    
  for (i=0; i<M; i++)    
  {       
      if(MaxOutput<Output[i]){    
          MaxOutput=MAX(MaxOutput,Output[i]);//保存最大值    
          Index=i;    
      }    
  }    
         
  fprintf(f, "%i\n", Index);//写进文件    
     
}    
/******************************************************************************   
              初始化测试样本   
******************************************************************************/    
void Initializetest()    
{    
    INT n,i,j;//循环变量    
       
    for (n=0; n<NUM_DATA; n++) {    
        for (i=0; i<Y; i++) {    
            for (j=0; j<X; j++)                                   
                if (testPattern[n][i][j]=='O')    
                    Inputtest[n][i*X+j] = HI;    
                else Inputtest[n][i*X+j] =LO;  //NUM_DATA输入模式,输入层X*Y个神经元                                       
        }    
    }    
}  

⌨️ 快捷键说明

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