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

📄 bp.cpp

📁 3层BP网络
💻 CPP
字号:
#include	<stdlib.h>
#include	<math.h>
#include	<conio.h>
#include	<stdio.h>
#include	<time.h>
#include	<conio.h>
#include	"data.h"
#include	"start_end_show.h"


GetTrainingData()		/*读取训练样本*/	
{
int		i,j,m;
float	datr;
if((fp=fopen("sample.txt","r"))==NULL)
      {
       printf("Cannot open file strike any key exit!\n");
       getch();
       exit(1);
      }
for(i=0;i<N;i++)		// 读入文件,以每行为单位,一行为一组训练数据,每行最后一个作为教师数据
      {j=0;
       while(j!=(IN+ON)&&fscanf(fp,"%f",&datr)!=EOF)
        {
		 if(j>IN-1) Study_Data[i].teach[j-IN]=datr;
         else       Study_Data[i].input[j]=datr;
         j++;
        }
      }
fclose(fp);
printf("\nThere are [%d] sample datas that have been loaded successfully!\n",N*(IN+ON));
printf("\nShow the data which has been loaded as follows:\n");
for(m=0;m<N;m++)		// 将读入的数据输出
	{for(i=0;i<IN;i++)
      {printf("Study_Data[%d].input[%d]=%f         ",m,i,Study_Data[m].input[i]);}
     for(j=0;j<ON;j++)
      {printf("Study_Data[%d].teach[%d]=%f\n",m,j,Study_Data[m].teach[j]);
	   printf("\n");}
    }
printf("\n\n\nPress any key to begin Study...");
getch();
system("CLS");
return 1;
}



initial()		/*初始化权、阈值子程序*/
{
int i;
int ii;
int j;
int jj;
int k;
int kk;
printf("\nRandom Weight value and Threshold value as follow:\n");
srand(time(NULL));		/*随机函数种子*/
printf("\nWeight Value:\n");
for(i=0;i<HN;i++) {
   for(j=0;j<IN;j++)    {Weight_H_I[i][j]=(float)(((rand()/32767.0)*2-1)/2);
/*初始化输入层到隐层的权值,随机模拟0.5~-0.5 */
     printf("\nWeight_H_I[%d][%d]=%f",i,j,Weight_H_I[i][j]);
     }
   }
for(ii=0;ii<ON;ii++) {
   for(jj=0;jj<HN;jj++)    {Weight_O_H[ii][jj]= (float)(((rand()/32767.0)*2-1)/2);
/*初始化隐层到输出层的权值,随机模拟0.5~-0.5 */
     printf("\nWeight_O_H[%d][%d]=%f",ii,jj,Weight_O_H[ii][jj]);
     }
   }
printf("\nThreshold Value:\n");
for(k=0;k<HN;k++) {
   Threshold_HN[k] = 1.0;	/*隐层阈值初始化 */
     printf("\nThreshold_HN[%d]=%f",k,Threshold_HN[k]);		
     }
for(kk=0;kk<ON;kk++) {
   Threshold_ON[kk] = 1.0;		/*输出层阈值初始化 */
     printf("\nThreshold_ON[%d]=%f\n",kk,Threshold_ON[kk]);		
    }
printf("\n\n\n\n\nPress any key to start calculating...:\n");
getch();
system("CLS");
printf("Please wait...");
return 1;
}



input_P(int m)		/*第m个学习样本输入子程序*/
{ int i;
   for(i=0;i<IN;i++)   {P[i]=Study_Data[m].input[i];}
   return 1;
}



input_T(int m)		/*第m个样本教师信号子程序*/
{int k;
for(k=0;k<ON;k++)    {T[k]=Study_Data[m].teach[k];}
return 1;
}



IN_OUT()		/*求净输入,输出*/
{
float u_H_I,u_O_H;
int i,j,k,l;
for(i=0;i<HN;i++)   {								/*input layer->hidden layer*/
    u_H_I=0.0;
    for(j=0;j<IN;j++)
    {u_H_I+=Weight_H_I[i][j]*P[j];}					/*加权和*/
     V_H_I[i]=u_H_I+Threshold_HN[i];				/*加入阈值*/
     Y_H_I[i]=1.0/(1.0+exp(-V_H_I[i]));				/*用activation function激活*/ 
    }
for(k=0;k<ON;k++) {									/*hidden layer->output layer*/		
    u_O_H=0.0;
    for(l=0;l<HN;l++)
    {u_O_H+=Weight_O_H[k][l]*Y_H_I[l];}
     V_O_H[k]=u_O_H+Threshold_ON[k];
     O[k]=1.0/(1.0+exp(-V_O_H[k]));
    }
return 1;
}



int Err_O_H(int m)		/*误差分析,δk, output unit*/					
{int k;						
float abs_err[ON];
float sqr_err=0.0;
for (k=0;k<ON;k++)   {
    abs_err[k]=T[k]-O[k];
    sqr_err+=(abs_err[k])*(abs_err[k]);
    d_err[k]=abs_err[k]*O[k]*(1.0-O[k]);		/*δk*/
    err_m[m]=sqr_err/2;							/*E(n)*/
   }
return 1;
}


int Err_H_I()		/*δj, hidden unit*/
{
int j,k;
float sigma;
for(j=0;j<HN;j++) {
   sigma=0.0;
   for(k=0;k<ON;k++)
    {sigma+=d_err[k]*Weight_O_H[k][j];}			
     e_err[j]=sigma*Y_H_I[j]*(1-Y_H_I[j]);		/*δj*/
   }
return 1;
}


float Err_Sum()		/*总误差*/
{int m;
float total_err=0.0;
for(m=0;m<N;m++)
    {total_err+=err_m[m];}			/* N*EAV */
return total_err;
}

/*新旧权值更新量交替--改进型Bp算法// */
saveWV()
{
int i;
int k;
int j;
int l;
for(i=0;i<HN;i++)    {
    for(j=0;j<IN;j++)
      {old_W[i][j] =b*e_err[i]*P[j];}
    }
for(k=0;k<ON;k++){
    for(l=0;l<HN;l++)
      {old_V[k][l] =a*d_err[k]*Y_H_I[l];}
    }
return 1;
}



/*更新权值,阈值*/
/*输出层*/
int Delta_O_H(int n,int study)
{int k,j;
if((n<=1)||(study=1))
   {
    for (k=0;k<ON;k++)   
	{
      for (j=0;j<HN;j++)
        {
		  Weight_O_H[k][j]=Weight_O_H[k][j]+a*d_err[k]*Y_H_I[j];
		}	/*wkj=wkj+步长*delta_kj*Y_H_I*/
	  Threshold_ON[k]+=a*d_err[k];
    }
   }
else
   {
    for (k=0;k<ON;k++)
	{
      for (j=0;j<HN;j++)
        {
		  Weight_O_H[k][j]=Weight_O_H[k][j]+(1.0-alpha)*a*d_err[k]*Y_H_I[j]+alpha*old_V[k][j];
		}
	  Threshold_ON[k]+=a*d_err[k];
	}
   }
return 1;
}
/*隐层*/
Delta_H_I(int n,int study)
{int i,j;
if((n<=1)||(study=1))
{
   for (j=0;j<HN;j++)   
   {
      for (i=0;i<IN;i++)
        {
		 Weight_H_I[j][i]=Weight_H_I[j][i]+b*e_err[j]*P[i];
		}
      Threshold_HN[j]+=b*e_err[j];
   }
}
else
{
   for(j=0;j<HN;j++)    
   {
     for(i=0;i<IN;i++)
       {
		 Weight_H_I[j][i]=Weight_H_I[j][i]+(1.0-alpha)*b*e_err[j]*P[i]+alpha*old_W[j][i];
		}
     Threshold_HN[j]+=b*e_err[j];
    }
}
return 1;
}

/*保存更新*/
void SaveThreshold()
{ 
int i,j,k;
int ii,jj,kk;
   /*save weight*/
   if((fp=fopen("weight.txt","a"))==NULL)
    {
      printf("Cannot open file strike any key exit!");
      getch();
      exit(1);
    }
   for(i=0;i<HN;i++)
     {
	   for(j=0;j<IN;j++)   
		fprintf(fp,"Weight_H_I[%d][%d]=%f\n",i,j,Weight_H_I[i][j]); }	// 将Weight_H_I[i][j](输入到隐层)的值写入weight.txt
   fprintf(fp,"\n");
   
   for(ii=0;ii<ON;ii++)
     {for(jj=0;jj<HN;jj++)   fprintf(fp,"Weight_O_H[%d][%d]=%f\n",ii,jj,Weight_O_H[ii][jj]);}	// 将Weight_O_H[i][j](隐层到输出)的值写入weight.txt
   fprintf(fp,"\n");
   fclose(fp);
   
   printf("\nThe result of weight.txt has been saved successfully!");
   
   if((fp=fopen("threshold.txt","a"))==NULL)
    {
      printf("Cannot open file strike any key exit!");
      getch();
      exit(1);
    }
   for(k=0;k<ON;k++)    
	   fprintf(fp,"Threshold_ON[%d]=%f\n",k,Threshold_ON[k]);		//	将权值写入Threshold.txt
   for(kk=0;kk<HN;kk++)   
	   fprintf(fp,"Threshold_HN[%d]=%f\n",kk,Threshold_HN[kk]);
   fclose(fp);
   
   printf("\nThe result of threshold.txt has been saved successfully!\n\n\n\n\nPress any key to Test...");
   getch();
   system("CLS");
}

/*读取测试样本*/
GetTestData()
{int i,j,m;
float datr;
if((fp=fopen("test.txt","r"))==NULL)
      {
       printf("Cannot open file strike any key exit!");
       getch();
       exit(1);
      }
for(i=0;i<N;i++)
      {j=0;
       while(j!=(IN+ON)&&fscanf(fp,"%f",&datr)!=EOF)
        {
		   if(j>IN-1)	Test_Data[i].expect[j-IN]=datr;
			else	Test_Data[i].input[j]=datr;
         j++;
        }
      }
fclose(fp);

printf("\nThere are [%d] test datas that have been loaded successfully!\n",N*(IN+ON));

printf("\nShow the data which has been loaded as follows:\n");
for(m=0;m<N;m++)
    {for(i=0;i<IN;i++)
      {printf("Test__Data[%d].input[%d]=%f         ",m,i,Test_Data[m].input[i]);}
     for(j=0;j<ON;j++)
      {printf("Test__Data[%d].expec[%d]=%f\n",m,j,Test_Data[m].expect[j]);
	   printf("\n");}
    }
printf("\n\n\n\nPress any key to calculating...");
getch();
system("CLS");
return 1;
}


/*样本测试及结果*/
Test()
{int i,j,k,m;
float net1[HN],net2[ON],H_net[HN],O_net[ON];
for(m=0;m<N;m++)
     {for(i=0;i<HN;i++)
        {net1[i]=0.0;
         for(j=0;j<IN;j++)
            {net1[i]+=Test_Data[m].input[j]*Weight_H_I[i][j];
            }
         net1[i]=net1[i]+Threshold_HN[i];
         H_net[i]=1.0/(1.0+exp(-net1[i]));
        }
      for(k=0;k<ON;k++)
        {net2[k]=0.0;
         for(j=0;j<HN;j++)
            {net2[k]+=H_net[j]*Weight_O_H[k][j];
            }
         net2[k]=net2[k]+Threshold_ON[k];
         O_net[k]=1.0/(1.0+exp(-net2[k]));
         printf("\nTest result[%d]=%f\n",m,O_net[k]);
        }
     }
return 0;
}

Online_Test()		// 预测数据
{int i,j,k;
float datr,TS[IN];
float net1[HN],net2[ON],H_net[HN],O_net[ON];
printf("\nPlease Input %d test datas with a space between each two datas:\n",IN);
for(i=0;i<IN;i++)
     {scanf("%f",&datr);
      TS[i]=datr;
     }
for(i=0;i<HN;i++)
        {net1[i]=0.0;
         for(j=0;j<IN;j++)
            {net1[i]+=TS[j]*Weight_H_I[i][j];
            }
         net1[i]=net1[i]+Threshold_HN[i];
         H_net[i]=1.0/(1.0+exp(-net1[i]));
        }
for(k=0;k<ON;k++)
        {net2[k]=0.0;
         for(j=0;j<HN;j++)
            {net2[k]+=H_net[j]*Weight_O_H[k][j];
            }
         net2[k]=net2[k]+Threshold_ON[k];
         O_net[k]=1.0/(1.0+exp(-net2[k]));
         printf("\nTest result:%f\n",O_net[k]);
        }
return 0;
}

OnlineSet()			/* 进入/退出数据预测函数 */
{char s;
printf("\n\n\n\nIf you want to test the data you inputted now,press y(or other button except q);\nOr press q to quit Test!\n");
while(1){
       s=getch();
       switch(s) {
           case 'q':
                    system("CLS");
                    End_Show();
           default:
                    Online_Test();
					break;
                 }
       printf("\nTo continue testing press y(or other button except q);\nOr press q to quit Test!\n");
          }
getch();
return 0;
}



void main()
{
float Pre_error;
float sum_err;
long int study;
long int flag;
int n=2;	/*n=1:普通Bp算法;n=2:改进型Bp算法*/
flag=100000000000;
a=0.1;
b=0.1;
alpha=0.5;
study=0;
Pre_error=0.000001;		/*可接受误差*/
Start_Show();
GetTrainingData();
initial();
do
   {int m;
    ++study;
    for(m=0;m<N;m++)
     {input_P(m);
      input_T(m);
      IN_OUT();
      Err_O_H(m);
      Err_H_I();
      Delta_O_H(n,study);
      Delta_H_I(n,study);
      saveWV();
     }
   sum_err=Err_Sum();
   if(study>flag)
    {
     printf("\n**********************************************\n");
     printf("The program is ended by itself because of error!\nThe learning times is surpassed!\n");
     printf("************************************************\n");
     
	 getch();
     
	 break;
    }
}while ((sum_err)>Pre_error);

printf("\n****************\n");
printf("\nThe program have studied for [%ld] times! %f %f\n",study,T,O);
printf("\n****************\n");
SaveThreshold();       
GetTestData();
printf("\nThe Result of the Test As follows:\n");
Test();
OnlineSet();
End_Show();
}

⌨️ 快捷键说明

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