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

📄 mainapp.cpp

📁 经典算法应用:神经网络算法的一个实际应用
💻 CPP
字号:
#include"bp_rbf.h"
 double randnumber()//-0.1~0.1的随机函数 
{
	return (sin(rand())/10) ;
}
//求某个节点的输出值
double f(int node,int layer){
	double sum=0;
for (int node2=0;node2<N[layer-1];node2++)
{
    sum=sum+w[layer][node][node2]*u[layer-1][node2];
}
sum=1.0/(1+exp(0-sum));
return sum;
}
//求误差函数对u的导数
double gf(int layer,int node){
	double sum=0;
for (int m=0;m<N[layer+1];m++)
sum=sum+e[layer+1][m]*u[layer+1][m]*(1-u[layer+1][m])*w[layer+1][m][node];
return sum;
}

//求前馈
void feed_forward()//前馈输出值
{
for (int layer=1;layer<=2;layer++)
 for(int node=0;node<N[layer];node++)
	 u[layer][node]=f(node,layer);
}
//求梯度
void compute_gradient()
{
for (int layer=2;layer>0;layer--)
{
  for(int node=0;node<N[layer];node++)
  {
	  if (layer==2) e[2][node]=u[2][node]-output[node];
	  else e[layer][node]=gf(layer,node);
  }

  for (int j=0;j<N[layer];j++)
		  for(int i=0;i<N[layer-1];i++)
			  {
                g[layer][j][i]=e[layer][j]*u[layer][j]*(1.0-u[layer][j])*u[layer-1][i];  
		     	  
		  }
}
}
//修改权值
void update_weights()
{
		for (int layer=1;layer<=2;layer++)
	    	for (int j=0;j<N[layer];j++)
		    	for(int i=0;i<N[layer-1];i++)
				{
					 temp_w_1[layer][j][i]=w[layer][j][i];
			       w[layer][j][i]=w[layer][j][i]-STUDY_SPEED*g[layer][j][i]+ALPHA*delta_w[layer][j][i];
				   temp_w_2[layer][j][i]=w[layer][j][i];
				   delta_w[layer][j][i]=temp_w_2[layer][j][i]-temp_w_1[layer][j][i];
				}
		
}
double erro()//误差
{
	double sum=0;
	
 sum=pow(fabs(u[2][0]-output[0]),2)+pow(fabs(u[2][1]-output[1]),2)+pow(fabs(u[2][2]-output[2]),2);
			
return sum;
}
//////////初始化,装载样例
void initial(FILE *fp)
{

 if(feof(fp)) 
 {
	 rewind(fp);
  k_k=(++k_k)%7;
  if(!k_k)  fprintf(fpwucha,"\n");
fprintf(fpwucha,"%16f",wucha);
	 wucha=0;
 }
 input[0]=1.0;
	for(int i=1;i<N_BUF;i++)
		fscanf(fp,"%f",input+i);
	 
	for(i=0;i<O_BUF;i++)
       fscanf(fp,"%d",output+i);
//	cout<<input[2]<<endl<<output[2]<<endl;
	//////////////////////至此读出一个样本的数据(input,output);
	for (int m=0;m<N_BUF;m++)
    u[0][m]=input[m];
				

}
void test()
{

FILE *fpt=NULL;
fpt=fopen("test.txt","r");
for (int i=0;i<=7;i++)
{
    initial(fpt);
	feed_forward();
	u[2][0]=floor(u[2][0]+0.5);
    u[2][1]=floor(u[2][1]+0.5);
    u[2][2]=floor(u[2][2]+0.5);
	cout<<u[2][0]<<"   "<<u[2][1]<<"   "<<u[2][2]<<endl;
    if(!((output[0]==u[2][0])&&(output[1]==u[2][1])&&(output[2]==u[2][2])))
		;
	else 
	{
		count++;
//	cout<<output[0]<<output[1]<<output[2]<<endl;
	}
}
fclose(fpt);

}
//////////////RBF的东东///////////////////////////////////////////////////////////////////////
/////////////////////文件定位////////////////////////////////
void  fseeking(FILE* fp,int row_no)
{  
	rewind(fp);
	if (!row_no) return;
  l:while((!feof(fp))&&(fgetc(fp)!='\n'))
	{
		file_time++;
	};
    //if(feof(fp)) return;
	row_no--;
	if (row_no) goto l; 
   else	return;
}       
 ////径向距离/////
void min_juli(int *set_number)//*j返回输入向量所在的聚类
{   
	
//	size_t size;
		int jj=0;
  double  sum_max=1000.0;
  double  sum=0.0;
  for(jj=1;jj<C_BUF;jj++)
  {
     for (int k=1;k<N_BUF;k++)
       sum+=pow(fabs(input[k]-w[1][jj][k]),2);
	 if(sum<sum_max)  
  {
	  *set_number=jj;
        sum_max=sum;
				}
	 sum=0;
    
  }
    return;
}
//////////////////向量相加////////////
void add_vector(double sum_x[N_BUF],float input[N_BUF])
{
	for (int i=1;i<N_BUF;i++)
		sum_x[i]+=input[i];
}
void sub_vector(double sum_x[N_BUF],float input[N_BUF])
{
	for (int i=1;i<N_BUF;i++)
		sum_x[i]-=input[i];
}
void sub_vector(double sum_x[C_BUF],double input[C_BUF],int pp)
{   
	int ppp=0;
	if (pp==N_BUF)  ppp=1;

	for (int i=ppp;i<pp;i++)
		sum_x[i]-=input[i];
	return;
}
double vector_width(double *sum_x)
{
	
 double sum=0.0;
 for (int i=1;i<N_BUF;i++)
	 sum+=sum_x[i]*sum_x[i];
  return sum;
}
//////////////k均值算法//////////////////////
void k_means()
{
	size_t size;
//	double  _min_change;
//	double  _min_max_change=0.0;
	double   min_change=10.0;//连续两次迭代的变化
	int set_number=0;//聚类序号
for (int i0=0;i0<max_layer;i0++)
		for (int i1=0;i1<max_node;i1++)
			for (int i2=0;i2<max_node;i2++)
		
				w[i0][i1][i2]=randnumber();//初始化权值
			
 
	 for(int ii=1;ii<C_BUF;ii++)
		theita[ii]=NULL;//指针初始化
  		
	fp=fopen("study.txt","r");
	if (fp==NULL){
				 cout<<"cannot open file"<<endl;      
	             exit(0);
	}
	int _i=0;

	while (!feof(fp))
	{
		for(int _j=1;_j<N_BUF;_j++)
		{
	    fscanf(fp,"%f",input+_j);
		w[1][_i][_j]=input[_j];
		}
	
			while (!feof(fp)&&(fgetc(fp)!='\n'));
     _i++;
	}
	rewind(fp);
		int   set_member_number=0;//某一个聚类中输入向量序号
while (min_change>EP2)//主循环
{  
	set_member_number=0;

	while (!feof(fp))
	{   
		//fseek(fp,(long)(set_member_number*EACH_LINE_OFFSET),0);
	    for(int i=1;i<N_BUF;i++)
		fscanf(fp,"%f",input+i);//读出一个输入向量
		while (!feof(fp)&&(fgetc(fp)!='\n'));
	  min_juli(&set_number); //返回一个距离最小的聚类序号
			if(!theita[set_number])
		{
			theita[set_number]=(int*)malloc(sizeof(int));
		   *(theita[set_number])=set_member_number;
		}
			else{
		size=_msize(theita[set_number]);
	 theita[set_number]=(int*)realloc(theita[set_number],sizeof(int)+size);
	 *(theita[set_number]+size/4)=set_member_number;
		}	  
	 set_member_number++;
	    
	}
             /////计算中心//////////

  	for(int i=1;i<C_BUF;i++)
	{ 
		  cout<<*(theita[i])<<"theita[]i   "<<i<<endl;
		if(theita[i])
		{
       size=_msize(theita[i]);
	 			int m=size/4;//该聚类中元素个数	
			double sum_x[N_BUF];
			for(int s=0;s<N_BUF;s++)
				sum_x[s]=0.0;
	
				for (int mm=0;mm<m;mm++)
		{	
					
			fseeking(fp,(*(theita[i]+mm)));
			for (int k1=1;k1<N_BUF;k1++)
			fscanf(fp,"%f",input+k1);
		while((!feof(fp))&&(fgetc(fp)!='\n'));

		    add_vector(sum_x,input);				
    		}
		for(int k=1;k<N_BUF;k++)
		{  
			temp_w_1[1][i][k]=w[1][i][k];
			w[1][i][k]=sum_x[k]/m;
	   		 
		}
		   sub_vector(temp_w_1[1][i],w[1][i],N_BUF);
		 	min_change=vector_width(temp_w_1[1][i]);
	
		}
		else 
		{
				for(int k=1;k<N_BUF;k++)
					w[1][i][k]=0;
		}
	}
		rewind(fp);
    if(min_change>EP2)//迭代没有结束,则放弃此次聚类集合
			{
	
  for(int i_free=0;i_free<C_BUF;i_free++)
	  free(theita[i_free]);
  for(int ii=0;ii<C_BUF;ii++)
		theita[ii]=NULL;//指针初始化
	}
 
}//////////主循环结束////////////


	/////////计算核函数的形状参数////////////////////
	for(int ss=0;ss<C_BUF;ss++)//高斯因子初始化
		gaosi_yinzi[ss]=0.0;
	
   for(int j=1;j<C_BUF;j++)//开始计算
   {   
	  
	   if(theita[j]) 
	   {
	        size=_msize(theita[j]);
			int m=size/4;//该聚类中元素个数	
			double sum_x[N_BUF];
			for(int s=0;s<N_BUF;s++)
				sum_x[s]=w[1][j][s];				
			for (int mm=0;mm<m;mm++)
				{	
			     fseeking(fp,*(theita[j]+mm));
			     for (int kk=1;kk<N_BUF;kk++)
		       	 fscanf(fp,"%f",input+kk);
				while((!feof(fp))&&(fgetc(fp)!='\n'));
		         sub_vector(sum_x,input);
			    gaosi_yinzi[j]+=vector_width(sum_x);
				}
   	  gaosi_yinzi[j]/=m;
	}
   }
  
	fclose(fp);	

}
/////////////////////////计算隐藏层输出/////////////
void compute_u1()
{    
      double x[N_BUF];
	
	for(int j=1;j<C_BUF;j++)
	{    
		for (int xx=1;xx<N_BUF;xx++)
		x[xx]=input[xx];
       sub_vector(x,w[1][j],N_BUF);

		if (gaosi_yinzi[j])
	   u[1][j]=exp((0.0-vector_width(x))/(2.0*gaosi_yinzi[j]));
	  else u[1][j]=0;
	}
	u[1][0]=1;
	return;
}
////////////////////////////训练第二层权值/////////////////////////
void lms()
{
	double ee[C_BUF];
	double e_e;
	count=0;
for (int j=0;j<O_BUF;j++)
{  
	u[2][j]=0.0;
   for(int jj=0;jj<C_BUF;jj++)
    u[2][j]=u[2][j]+w[2][j][jj]*u[1][jj];
     u[2][j]=1.0/(1+exp(0-u[2][j]));
   e_e=u[2][j]-output[j];
    for (int jjj=0;jjj<C_BUF;jjj++)
	{
		 temp_w_1[2][j][jjj]=w[2][j][jjj];
	   ee[jjj]=e_e*u[1][jjj]*STUDY_SPEED;
	   w[2][j][jjj]=w[2][j][jjj]-ee[jjj]+ALPHA*delta_w[2][j][jjj];
	   temp_w_2[2][j][jjj]=w[2][j][jjj];
	   delta_w[2][j][jjj]=temp_w_2[2][j][jjj]-temp_w_1[2][j][jjj];
	   }
	  // ee[jjj]=e_e*u[1][jjj]*STUDY_SPEED;
  //sub_vector(w[2][j],ee,C_BUF);
}
}
void rbf_test()
{
FILE * fp_test=NULL;
fp_test=fopen("test.txt","r");
if(!fp_test)
{
cout<<"cannot open file"<<endl;
	 exit(0);
}
while (!feof(fp_test))
{
 for(int i=1;i<N_BUF;i++)
	 fscanf(fp_test,"%f",input+i);
  for(int j=0;j<O_BUF;j++)
	 fscanf(fp_test,"%d",output+j);
   compute_u1();
  for(int j_j=0;j_j<O_BUF;j_j++)
 {
    u[2][j_j]=0.0;
    for(int jj=0;jj<C_BUF;jj++)
    u[2][j_j]=u[2][j_j]+w[2][j_j][jj]*u[1][jj];
   u[2][j_j]=1.0/(1+exp(0-u[2][j_j]));
 }
         u[2][0]=floor(u[2][0]+0.5);
    u[2][1]=floor(u[2][1]+0.5);
    u[2][2]=floor(u[2][2]+0.5);
	cout<<u[2][0]<<"   "<<u[2][1]<<"   "<<u[2][2]<<endl;
    if(!((output[0]==u[2][0])&&(output[1]==u[2][1])&&(output[2]==u[2][2])))
		;
	else 
	{
		count++;
	}

}
 fclose(fp_test);
}
////////////////////////主函数入口//////////////////////////
int main()
{  
	
////////////////////////对权值初始化为-0.1~0.1之间的随机数
//	FILE * fpw=NULL;
//	if (!(fpw=fopen("权值.txt","r")))
	{
	for (int i0=0;i0<max_layer;i0++)
		for (int i1=0;i1<max_node;i1++)
			for (int i2=0;i2<max_node;i2++)
				w[i0][i1][i2]=randnumber();
	}
/*else /////////////读取权值
	{
	for ( int i0=0;i0<max_layer;i0++)
		for ( int i1=0;i1<max_node;i1++)
			for ( int i2=0;i2<max_node;i2++)
			{
		    fseek(fpw,11L,1);
			fscanf(fpw,"%f",&w[i0][i1][i2]);
			}
	
	fclose(fpw);
}*/
 	fpwucha=fopen("bp结果\\误差变化序列.txt","w");
 if (!fpwucha){
	 cout<<"cannot open file"<<endl;
	 exit(0);
 }
			////////////////////////////
			//打开训练文件
		fp=fopen("study.txt","r");
	if (fp==NULL){
				 cout<<"cannot open file"<<endl;
	 exit(0);
	}
printf("正在训练,请稍等.......");
	//开始时钟
	clock_t t1=clock();
	if (t1==clock_t(-1)){
		cerr<<"sorry ,no clock\n";
		exit(1);
	}
   while (wucha>EP){
		initial(fp);
		feed_forward();
	    compute_gradient();
        update_weights();
		wucha+=erro();
		bp_test_time++;
   }
	//结束时钟
      clock_t t2=clock();
	if (t2==clock_t(-1)){
		cerr<<"sorry ,no clock\n";
		exit(1);
	}  
	cout<<"\r"<<"        训练结束!            "<<endl;
	cout<<"训练时间为"<<"     "<<double(t2-t1)/CLOCKS_PER_SEC<<"seconds"<<"(这个时间包括了读写文件时间,可以精确)"<<endl;
    cout<<"训练轮数为   "<<bp_test_time<<endl;
   	fclose(fp);
    fclose(fpwucha);
/////////////测试样例
		test();
		cout<<"识别个数为"<<count<<endl<<"识别率为"<<(count/TEST_SETS)*100<<"%"<<"最后误差为"<<wucha<<endl;

		FILE *fp2;//保存权值
		fp2=fopen("bp结果\\权值.txt","w");
		if (fp2==NULL)
		{
			exit(0);
		}
	for (int layer=1;layer<=2;layer++)
	    	for (int j=0;j<N[layer];j++)
		    	for(int i=0;i<N[layer-1];i++)
					fprintf(fp2,"w[%d][%d][%d]=%f\n",layer,j,i,w[layer][j][i]);
				fclose(fp2);
////////////////////////////////////////rbf训练////////////////////
				//////////计算读一行字符所需要的时间///////
			FILE * fp_test=fopen("study.txt","r");
				if (fp_test==NULL){
				 cout<<"cannot open file"<<endl;      
	             exit(0);
				}
				clock_t t_test1=clock();
				while(!(feof(fp_test))&&(fgetc(fp_test)!='\n'));
                clock_t t_test2=clock();
				if (t_test2==clock_t(-1)){
		cerr<<"sorry ,no clock\n";
		exit(1);
	}  
				double file_time_each=double(t_test2-t_test1)/CLOCKS_PER_SEC/EACH_LINE_OFFSET*100000000 ;
							fclose(fp_test);
			wucha=1;
			k_k=-1;
			fpwucha=fopen("rbf结果\\误差.txt","w");
			//	开始时钟
          clock_t   t11=clock();
				k_means();
			   fp=fopen("study.txt","r");
            	if (fp==NULL){
				 cout<<"cannot open file"<<endl;      
	             exit(0);
				}
				while(wucha>EP)
				{   
					if (feof(fp)) rewind(fp);
                   for(int i=1;i<N_BUF;i++)
	             	fscanf(fp,"%f",input+i);
	               	for(i=0;i<O_BUF;i++)
                   fscanf(fp,"%d",output+i);
				 	compute_u1();
					lms();
                	wucha=0.0;
					wucha=erro();
					  k_k=(++k_k)%7;
  if(!k_k)  fprintf(fpwucha,"\n");
fprintf(fpwucha,"%16f",wucha);
					rbf_test_time++;
					}
              //结束时钟
          clock_t    t22=clock();
			  	if (t22==clock_t(-1)){
		cerr<<"sorry ,no clock\n";
		exit(1);
	}  
				fclose(fpwucha);
//	cout<<"\r"<<"        训练结束!            "<<endl;
	cout<<"训练时间为"<<"     "<<double(t22-t11)/CLOCKS_PER_SEC-file_time*file_time_each<<"seconds"<<"(这个时间包括了读写文件时间,可以精确)"<<endl;
	  cout<<"训练轮数为   "<<rbf_test_time<<endl;
				fclose(fp);
               rbf_test();
			   cout<<count<<"   "<<endl;
			   	FILE *fp2_rbf;//保存权值
		fp2_rbf=fopen("rbf结果\\权值.txt","w");
		if (fp2_rbf==NULL)
		{
			exit(0);
		}
		
	for ( layer=1;layer<=2;layer++)
	    	for (int j=0;j<N[layer];j++)
		    	for(int i=0;i<N[layer-1];i++)
					fprintf(fp2_rbf,"w[%d][%d][%d]=%f\n",layer,j,i,w[layer][j][i]);
				fclose(fp2_rbf);
  	
		return 0;
}

⌨️ 快捷键说明

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