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

📄 backpropogation.c

📁 人工神经元BP网络的实现
💻 C
字号:
#include <stdio.h>
#include <math.h>
#define sixfour 64
#define ten 10
#define size1 5 
#define size2 5
void main()
{	float w1[sixfour][size1],w3[size1];//各层的权值
    float w2[size1][size1];   	
    float in[2*ten][sixfour+1];  //输入数据,其中,第sixfour+1个元素是期望输出值
	float hide1[size1],hide2[size1];//第一、二隐层的输出数据
	float delta,delta1[size1],delta2[size1];//输出层、第一、二隐层的局部梯度
	double output;            //实际输出值
	float yita;              //学习步长
	float error;             //误差  
	float temp[size1],ini;     //用于存放中间结果 
	int i,j,k,l,m,n,mid;           //计数器 
    double  iptr,x;
	int s;
	float sigmoid(float x); //函数原型,本程序激活函数采用sigmoid函数
	double modf(double,double * );
	FILE *fp,*fp2,*weight1,*weight2;    //fp是训练数据文件,fp2是输出文件,weight1,weight2是输出的权值文件,weight1
	                                  //用于保存训练是的权值,weight2是识别时的权值文件
	yita=0.8;
   
// 读入训练数据in[][]
	if((fp=fopen("train.txt","r"))==NULL)
	{printf("\n the file train.txt can not be opened");
	exit(0);
	}

    if((fp2=fopen("output.txt","w"))==NULL)
	{printf("\n can't create the output.txt file");
	exit(0);
	}
   
   if((weight2=fopen("weight.txt","r"))==NULL)
	{printf("\n the file weight.txt can not be opened");
     exit(0);
	}

   
   
   //读入并产生输入数据,读入十个标准样本,通过对这十个标准样本随机加噪,另外产生十个样本,
   //这二十个样本作为训练数据进行训练
	for(i=0;i<ten;i++)
   	for(j=0;j<sixfour+1;j++)
			fscanf(fp,"%f",&in[i][j]);


/*
	//随机加噪声
	srand((unsigned)time(NULL));
	s=rand();
for(k=ten;k<2*ten;k++)
  {in[k][sixfour]=in[k-ten][sixfour];
   for(n=0;n<5;n++)
   {srand(s);
   s+=1;
	mid=rand()%64;
    if(in[k-ten][mid]>0.5)
		in[k][mid]=0.0;
	else
		in[k][mid]=1.0;
   }
} 



 if((weight1=fopen("weight.txt","w"))==NULL)
	{printf("\n the file weight.txt can not be opened");
     exit(0);
	}
	
	


//初始化第一隐层权值w1[][]
  for(i=0;i<sixfour;i++)
	 for(j=0;j<size1;j++)
	 {ini=rand()%100;
	  ini/=100;
	  if(ini>0.5) ini-=1;
	  w1[i][j]=ini;
     }

//初始化第二隐层权值w2[][]和输出层权值w3[[]
for(i=0;i<size1;i++)
{ ini=rand()%100;
  ini/=100;
  if(ini>0.5) ini-=1;
  w3[i]=ini;
 for(j=0;j<size2;j++)
	  {ini=rand()%100;
	  ini/=100;
	  if(ini>0.5) ini-=1;
	  w2[i][j]=ini;
	  }
 }

//主循环
do
{   error=0.0;
 for(m=0;m<2*ten;m++)
	{    delta=0.0;
         output=0.0;
	     for(i=0;i<size1;i++)
		 {  temp[i]=0.0;
	        hide1[i]=0.0;
	        hide2[i]=0.0;
		    delta1[i]=0.0;
		    delta2[i]=0.0;
		 }
	   //计算第一隐层的输出
	for(i=0;i<size1;i++)
		{for(k=0;k<sixfour;k++)
		  {hide1[i]+=w1[k][i]*in[m][k];}
		 hide1[i]=sigmoid(hide1[i]);
		}

		//计算第二隐层的输出
		for(i=0;i<size1;i++)
		  {for(j=0;j<size1;j++)
			 {hide2[i]+=w2[j][i]*hide1[j]; }
    	  hide2[i]=sigmoid(hide2[i]);
		  }

		//计算输出节点的输出	 
	    	  for(i=0;i<size1;i++)
			   {output+=w3[i]*hide2[i]; }
    	output=sigmoid(output);
		
			//输出层的误差
			error+=fabs(output-in[m][sixfour]);
    	
			//计算输出层的局部梯度
			delta=output*(1-output)*(in[m][sixfour]-output);

			//计算第二隐层的局部梯度   
			for(i=0;i<size1;i++)
				   temp[i]+=delta*w3[i];
			   for(i=0;i<size1;i++)
				   delta2[i]=hide2[i]*(1-hide2[i])*temp[i];

               //计算第一隐层的局部梯度
			   for(i=0;i<size1;i++)
                   temp[i]=0.0;  

                for(j=0;j<size1;j++)
					  for(i=0;i<size1;i++)
					  {temp[j]+=delta2[i]*w2[j][i];}
				    for(i=0;i<size1;i++)
					  {delta1[i]=hide1[i]*(1-hide1[i])*temp[i];}
                  
            //修正输出层权值
                     for(i=0;i<size1;i++)
					   w3[i]+=yita*delta*hide2[i];
					 
            //修正第二隐层权值           
					 for(i=0;i<size1;i++)
						   for(j=0;j<size1;j++)
						   {w2[i][j]+=yita*delta2[j]*hide1[i];
						 //  printf("the weight1 is:%f\n",w2[i][j]);
						   }

           //修正第一隐层权值
							   for(i=0;i<sixfour;i++)
    							     for(j=0;j<size1;j++)
									 {w1[i][j]+=yita*delta1[j]*in[m][i];
									
									 }
      }
 error=error/(2*ten);
 printf("the error is:%f\n",error);
}while(error>0.06 );


//将训练好的权值保存在weight.txt文件中
for(i=0;i<sixfour;i++)
  for(j=0;j<size1;j++)
  {fprintf(weight1,"%f\n",w1[i][j]);}
      fprintf(weight1,"\n\n\n");

   for(i=0;i<size1;i++)
	  for(j=0;j<size1;j++)
	  {fprintf(weight1,"%f\n",w2[i][j]);}
         fprintf(weight1,"\n\n\n");

	  for(i=0;i<size1;i++)
	  {fprintf(weight1,"%f\n",w3[i]);}
	      fprintf(weight1,"\n\n\n");

*/


for(i=0;i<sixfour;i++)
  for(j=0;j<size1;j++)
	  fscanf(weight2,"%f",&w1[i][j]);

   for(i=0;i<size1;i++)
	  for(j=0;j<size1;j++)
		  fscanf(weight2,"%f",&w2[i][j]);

	  for(i=0;i<size1;i++)
		  fscanf(weight2,"%f",&w3[i]);


//开始进行字符识别 


//随机加噪声
 srand((unsigned)time(NULL));
 s=rand();
for(k=0;k<ten;k++)
  {
   for(n=0;n<5;n++)
   {srand(s);
    s+=1;
	mid=rand()%64;
    if(in[k][mid]>0.5)
		in[k][mid]=0.0;
	else
		in[k][mid]=1.0;
   }
}


for(m=0;m<ten;m++)
{
	output=0.0;
       for(i=0;i<ten;i++)
	   { hide1[i]=0.0;
         hide2[i]=0.0;
	   }
//计算第一隐层的输出
     	 for(i=0;i<size1;i++)
		 {for(k=0;k<sixfour;k++)
			{hide1[i]+=w1[k][i]*in[m][k];}
         hide1[i]=sigmoid(hide1[i]);
		 }

//计算第二隐层的输出
		 for(i=0;i<size1;i++)
		   {for(j=0;j<size1;j++)
				 {hide2[i]+=w2[j][i]*hide1[j];}
             hide2[i]=sigmoid(hide2[i]);
		   }
		 	
//计算输出结果
	 for(i=0;i<size1;i++)
	   {output+=w3[i]*hide2[i];}
	    output=sigmoid(output);
//识别结束
//fprintf(fp2,"%f",in[m][sixfour]);
fprintf(fp2,"\n\n期望输出值为:%f\n",10*in[m][sixfour]);
output=10*output;
x=modf(output,&iptr);
if(x>0.5)
    output=(iptr)+1.0;
   else output=iptr;
fprintf(fp2,"实际输出值为%f\n",output);
}
fclose(fp);
fclose(fp2);
fclose(weight2);
}

float sigmoid(float x)
{	float w;
	 w=1/(1+exp(-1.0*x));
	 return w;
}

⌨️ 快捷键说明

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