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

📄 main.cpp

📁 神经网络算法的C语言实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h> 

#include <string.h> 

#include <math.h> 

#include <time.h>

#include <iostream>

#define PI 3.14159

#define EPSILON 1E-6 


//3层的神经网络结构 
typedef struct tag_bpnnt 
{ 
  int in_n;     //输入层神经元数 

  int hidd_n;    //隐层神经元数 

  int out_n;      //输出层神经元 

  double *in_unit; //输入层神经元 

  double *hidd_unit; //隐层神经元 

  double *out_unit; //输出层神经元 



  double *hidd_delta;//隐层误差 

  double *out_delta; //输出层误差 

  double *hidd_dfda; 

  double *out_dfda; 

  double *target;   //目标向量 

  double **in_w;     //输入层权值 

  double **hidd_w; //隐层权值 



  //前一次结果(用于迭代) 

  double **prev_in_w; 

  double **prev_hidd_w; 

}BPNN_t; 



//分配1d内存 

double *bpnn_malloc1d(int n); 


//分配2d内存 

double **bpnn_malloc2d(int m,int n); 



//销毁2d内存 

void bpnn_mfree2d(double **pmem,int m); 



//计算sigmoid函数 

double sigmoid(double x); 



//建立神经网络 

BPNN_t *bpnn_create(int nIn,int nHidden,int nOut); 

//销毁网络 

void bpnn_destroy(BPNN_t *pNet); 



//初始化权值 

void bpnn_init_weight(double **w,int m,int n,int flag); 



//前向计算本层输出 

void bpnn_layerforward(double *layer1,double *layer2,double **conn,int n1,int n2); 



//计算输出层反传误差 

void bpnn_out_error(double *delta,double *dfda,double *target,double *output,int nj,double *err); 



//计算隐层反传误差 

void bpnn_hidd_error(double *delta_h,double *delta_o,double *dfda_h,double *dfda_o,int nh,int nout,double **w_ho,double *h_unit,double*err);
 


//计算整个网络输出 

void bpnn_nnforward(BPNN_t *pNet); 



//最速下降法训练一次 

double bpnn_train_steepest(BPNN_t *pNet,double eta,double **indata,double **targetdata,int np); 



//Levenberg-Marquardt训练 

double bpnn_train_lm(BPNN_t *pNet,double **indata,double **targetdata,int np,double *lamda); 



//gauss-jordan消元法解线性方程组 

void gauss_jordan(double *a,double *b,int n); 



//交换 

void SWAP(double x,double y) 
{
	if((x)!=(y)) 

	{ 
		x=x+y; 

		y=x-y; 

		x=x-y;
	}
}



//设置单位矩阵 

static void SetEye(double*mat,int n); 



//分配1d内存 

double *bpnn_malloc1d(int n) 

{ 

    double *pout; 

    pout=(double*)malloc(n*sizeof(double)); 

    return pout; 

} 



//分配2d内存 

//m为行数(组数),n为列数(每组个数) 

double **bpnn_malloc2d(int m,int n) 

{ 

    double **pout; 

    int i; 



    pout=(double**)malloc(m*sizeof(double*)); 

    for(i=0;i<m;i++) 

    { 

        pout[i]=(double*)malloc(n*sizeof(double)); 

	} 

    return pout; 

} 



//销毁2d内存 

void bpnn_mfree2d(double **pmem,int m) 

{ 

    int i; 

    for(i=0;i<m;i++) 

    { 

        free(pmem[i]); 

    } 

    free(pmem); 

    pmem=NULL; 

} 



/**////////////////////////////////////////////////////////////////////// 

//初始化权值 

// 参数 



//       flag-- 1随机初始化 0 全部清0[Page] 

//  m--上一层神经元数目 

//  n--下一层神经元数目 

/**///////////////////////////////////////////////////////////////////// 

void bpnn_init_weight(double **w,int m,int n,int flag) 

{ 

   int i,j; 



   srand((unsigned int)time(NULL)); 

   if(flag) //随机生成 

   { 

       for(i=0;i<m+1;i++) 

       for(j=0;j<n+1;j++) 

       { 

          //-1.0~1.0的随机值 

          w[i][j]=(double)(rand()%2000)/1000.0-1; 

       } 



   } 

   else //全部清0 

   { 

       for(i=0;i<m+1;i++) 

       for(j=0;j<n+1;j++) 

       { 

          w[i][j]=0.0; 

       } 

   } 



} 



//计算sigmoid函数 

double sigmoid(double x) 

{ 

   return 1.0/(1.0+exp(-x)); 

} 



/**////////////////////////////////////////////////////////////////////// 

//建立神经网络 

// 参数 

//       nIn  --输入层神经元数 

//       nHidden --隐层神经元数 

//       nOut  --输出层神经元数 

/**////////////////////////////////////////////////////////////////////// 

BPNN_t *bpnn_create(int nIn,int nHidden,int nOut) 

{ 

   BPNN_t *pNet; 

   pNet=(BPNN_t*)malloc(sizeof(BPNN_t)); 



   pNet->in_n=nIn; 

   pNet->hidd_n=nHidden; 

   pNet->out_n=nOut; 



   pNet->in_unit=bpnn_malloc1d(nIn+1); //增加1保存阀值分量b 

   pNet->hidd_unit=bpnn_malloc1d(nHidden+1); 

   pNet->out_unit=bpnn_malloc1d(nOut+1); 

   pNet->hidd_delta=bpnn_malloc1d(nHidden+1); 

   pNet->out_delta=bpnn_malloc1d(nOut+1); 

   pNet->hidd_dfda=bpnn_malloc1d(nHidden+1); 

   pNet->out_dfda=bpnn_malloc1d(nOut+1); 

   pNet->target=bpnn_malloc1d(nOut+1); 



   pNet->in_unit[0]=1.0; //阀值分量 

   pNet->hidd_unit[0]=1.0; 



   //网络权重 

   pNet->in_w=bpnn_malloc2d(nIn+1,nHidden+1); 

   pNet->hidd_w=bpnn_malloc2d(nHidden+1,nOut+1); 

   pNet->prev_in_w=bpnn_malloc2d(nIn+1,nHidden+1); 

   pNet->prev_hidd_w=bpnn_malloc2d(nHidden+1,nOut+1); 



   //初始化权值 

   bpnn_init_weight(pNet->in_w,nIn,nHidden,1); 

   bpnn_init_weight(pNet->hidd_w,nHidden,nOut,1); 

   bpnn_init_weight(pNet->prev_in_w,nIn,nHidden,0); 

   bpnn_init_weight(pNet->prev_hidd_w,nHidden,nOut,0); 



   return pNet; 

} 



//销毁网络 

void bpnn_destroy(BPNN_t *pNet) 

{ 

   int i; 

   int n1; 

   int n2; 

   n1=pNet->in_n; 

   n2=pNet->hidd_n; 


   free(pNet->in_unit); 

   free(pNet->hidd_unit); 

   free(pNet->out_unit); 

   free(pNet->hidd_delta); 

   free(pNet->out_delta); 

   free(pNet->hidd_dfda); 

   free(pNet->out_dfda); 

   free(pNet->target); 



   for(i=0;i<n1+1;i++) 

   { 

     free(pNet->prev_in_w[i]); 

     free(pNet->in_w[i]); 

   } 

   free(pNet->prev_in_w); 

   free(pNet->in_w); 



   for(i=0;i<n2+1;i++) 

   { 

     free(pNet->prev_hidd_w[i]); 

     free(pNet->hidd_w[i]); 

   } 

   free(pNet->prev_hidd_w); 

   free(pNet->hidd_w); 

   free(pNet); 



} 



/**////////////////////////////////////////////////////////////////////// 

//前向计算本层的输出 

// 参数 

//     layer1 --上一层神经元数组 

//     layer2 --该层神经元数组 

//     conn  --上层连接权值 

//  n1       --上层神经元个数 

//     n2     --本层神经元个数 

// 返回 

//  更新layer1,layer2 

/**////////////////////////////////////////////////////////////////////// 

void bpnn_layerforward(double *layer1,double *layer2,double **conn,int n1,int n2) 

{ 

   double sum; 

   int j,k; 


   layer1[0]=1.0; //以第0个代表阀值分量 

   for(j=1;j<n2+1;j++) 

   { 

     sum=0.0; 

     for(k=0;k<n1+1;k++) 

     {
		 sum+=conn[k][j]*layer1[k];
	 } 



     layer2[j]=sigmoid(sum); 

   } 

} 



/**//////////////////////////////////////////////////////////////////////[Page] 

//计算输出层反传误差(单个样本) 

// 参数 

//     delta --反传误差向量 

//     target --目标值 

//     output --网络输出值 

//  nj  --输出层神经元数 

//     err  --总误差 

// 返回 

//  更新err,delta 

/**////////////////////////////////////////////////////////////////////// 

void bpnn_out_error(double *delta,double *dfda,double *target,double *output,int nj,double*err) 

{ 

   int j; 

   double errsum=0.0; 



   for(j=0;j<nj+1;j++) 

   { 

     //求反传误差 

     delta[j]=output[j]*(1-output[j])*(target[j]-output[j]); 

     dfda[j]=output[j]*(1-output[j]); 

     errsum+=fabs(delta[j]); 

   } 

   *err=errsum; 



} 



/**////////////////////////////////////////////////////////////////////// 

//计算隐层反传误差(单个样本) 

// 参数 

//     delta_h --隐层反传误差向量 

//     delta_o --输出层反传误差 


//------------------ Page 8-----------------------

//     dfda_h 

//     dfda_h 

//     nh      --隐层神经元数目 

//  nout  --输出层神经元数 

//     w_ho  --隐层到输出层连接权值 

//     h_unit  --隐层神经元数组 

//     err     --总误差[Page] 

// 返回 

//  更新err,delta_h 

/**////////////////////////////////////////////////////////////////////// 

void bpnn_hidd_error(double *delta_h,double *delta_o,double *dfda_h,double *dfda_o,int nh,int nout,double **w_ho,double *h_unit,double *err) 

{ 

   int j,k; 

   double hidd,sum,sum2,errsum; 



   errsum=0.0; 

   for(j=0;j<nh+1;j++) 

   { 

     hidd=h_unit[j]; 

     sum=0.0; 

     sum2=0.0; 

     for(k=1;k<nout+1;k++) 

     { 

        sum+=delta_o[k]*w_ho[j][k]; 

        sum2+=dfda_o[k]*w_ho[j][k]; 

     } 

     delta_h[j]=hidd*(1-hidd)*sum; 

     dfda_h[j]=hidd*(1-hidd)*sum2; 

     errsum+=fabs(delta_h[j]); 

   } 

   *err=errsum; 



} 



//计算整个网络输出 

void bpnn_nnforward(BPNN_t *pNet) 

{ 

   int nIn,nHidd,nOut; 

   nIn=pNet->in_n; 

   nHidd=pNet->hidd_n; 

   nOut=pNet->out_n; 



   //计算输入层--隐层 


//----------------------- Page 9-----------------------

   bpnn_layerforward(pNet->in_unit,pNet->hidd_unit,pNet->in_w,nIn,nHidd); 

   //计算隐层--输出层 

   bpnn_layerforward(pNet->hidd_unit,pNet->out_unit,pNet->hidd_w,nHidd,nOut);

} 



/**////////////////////////////////////////////////////////////////////// 

//最速下降法的BP网络单次训练(全部样本) 

// 参数 

//    pNet      --已初始化的神经网络 

//    eta     --最速下降步长 

//    indata     --输入的样本数组 

//    targetdata--输出期望 

//  np         --样本个数 

// 返回 

//    返回更新后的平方误差 

//  更新pNet 

/**////////////////////////////////////////////////////////////////////// 

double bpnn_train_steepest(BPNN_t *pNet,double eta,double **indata,double **targetdata,int np) 

{ 

   int p,i,j,k; 

   int nIn,nHidd,nOut; 

   double errout,errh; 

   double esqrsum,esqr; 

   double **pGradIn,**pGradH; 



   nIn=pNet->in_n; 

   nHidd=pNet->hidd_n; 

   nOut=pNet->out_n; 



   pGradIn=bpnn_malloc2d(nIn+1,nHidd+1); 

   pGradH=bpnn_malloc2d(nHidd+1,nOut+1); 



   //累加梯度清0 

   for(j=0;j<=nIn;j++) 

   for(k=0;k<=nHidd;k++) 

   { 

     pGradIn[j][k]=0.0; 

   } 

   for(j=0;j<=nHidd;j++) 

   for(k=0;k<=nOut;k++) 

   { 

     pGradH[j][k]=0.0; 

   } 


//----------------------- Page 10-----------------------

   for(p=0;p<np;p++) 

   { 

     //输入数据 

     pNet->in_unit[0]=0.0; //无偏移[Page] 

     for(i=1;i<=nIn;i++) 

        pNet->in_unit[i]=indata[p][i-1]; 

     for(i=1;i<=nOut;i++) 

        pNet->target[i]=targetdata[p][i-1]; 



     bpnn_nnforward(pNet); 

     bpnn_out_error(pNet->out_delta,pNet->out_dfda,pNet->target,pNet->out_unit,nOut,&errout); 

     bpnn_hidd_error(pNet->hidd_delta,pNet->out_delta,pNet->hidd_dfda,pNet->out_dfda,nHidd,nOut,pNet->hidd_w,pNet->hidd_unit,&errh); 



     //累加梯度 

     for(j=0;j<=nIn;j++) 

     for(k=1;k<=nHidd;k++) 

     { 

        pGradIn[j][k]+=pNet->hidd_delta[k]*pNet->in_unit[j]; 

     } 

⌨️ 快捷键说明

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