BP神经网络算法实现

 
//BP神经网络算法实现

#include <stdio.h>
#include <math.h> 
#include <conio.h> 
#include <stdlib.h>

#define nh 3			/*输入层*/
#define ni 4			/*隐层*/
#define nj 1            /*输出层*/
#define nk 100          /*样本容量*/
#define test 70         /*测试集容量*/
#define nr 0.7          /*学习效率*/
#define EPS 0.00001

float x[nk][nh],d[nk][nj],whi[nh][ni],wij[ni][nj],thi[ni],thj[nj];
int h,i,j,k,ff; 
float xmin[nh],xmax[nh],dmin[nj],dmax[nj]; 
FILE *fp1,*fp2,*fp3,*fp4; 

void init(void); 
void startleaning(void);
void testsample(void); 
void readw(void); 
void readt(void);
void writew(void); 
float sigmoid(float a); 
double ranu(void); 
char filename1[]={"samplefile.txt"};

void init(void) 
{
	int min,max;  
	if(fp1==0)
	{ 
		system("cls"); 
		printf("Can not find the learning sample file!\n"); 
		exit(0);
	} 
	for(k=0;k<nk;k++)
	{ 
		for(h=0;h<nh;h++) 
			fscanf(fp1,"%f,",&x[k][h]);  //神经网络输入
		for(j=0;j<nj;j++) 
			fscanf(fp1,"%f,",&d[k][j]);  //神经网络输出
	} 
	for(h=0;h<nh;h++)
	{ 
		min=1;
		max=1; 
		for(k=0;k<nk;k++) 
		{ 
			if(x[k][h]<x[min][h]) min=k; 
			if(x[k][h]>x[max][h]) max=k; 
		} 
		xmin[h]=x[min][h]; 
		xmax[h]=x[max][h]; 
		for(k=0;k<nk;k++)				 /*神经网络输入归一化*/ 
			x[k][h]=(x[k][h]-xmin[h])/(xmax[h]-xmin[h]); 
		/*x[k][h]=x[k][h]/xmax[h];*/
	} 
	for(j=0;j<nj;j++) 
	{ 
		min=1;max=1; 
		for(k=0;k<nk;k++) 
		{ 
			if(d[k][j]<d[min][j])
				min=k; 
			if(d[k][j]>d[max][j]) 
				max=k; 
		} 
		dmin[j]=d[min][j]; 
		dmax[j]=d[max][j]; 
		for(k=0;k<nk;k++)				/*神经网络输出归一化*/ 
			d[k][j]=(d[k][j]-dmin[j])/(dmax[j]-dmin[j]); 
		/*d[k][j]=d[k][j]/dmax[j];*/
	}
}
/*----------------------------------------------------*/ 
void startlearning(void) 
{ 
	long int nt,n; 
	float t,error[nk],gerror,xj[nj],xi[ni],yj[nj],yi[ni],pxi[ni],pxj[nj];
	float u0=0,u1=0,u2=0,u3=0;
	float v0,v1,v2,v3;

	for(i=0;i<ni;i++) 
	{ 
		for(h=0;h<nh;h++) 
			whi[h][i]=-0.8+1.6*ranu();
		for(j=0;j<nj;j++) 
			wij[i][j]=-0.8+1.6*ranu();

		thi[i]=-0.5+ranu();
	} 
	for(j=0;j<nj;j++) 
		thj[j]=-0.5+ranu();
	fp2=fopen("w.txt","w+");			/*权值、阈值初始化*/


/*学习开始*/
	printf("\t\nPlease enter the learning times:\n"); 
	scanf("%ld",&nt);
	for(n=0;n<nt;n++)					/*学习次数*/
	{
		gerror=0; 
		for(k=0;k<nk;k++)				/*单样本循环*/ 
		{ 
			for(i=0;i<ni;i++) 
			{ 
				t=0; 
				for(h=0;h<nh;h++) 
					t+=whi[h][i]*x[k][h];
				xi[i]=t+thi[i];
				yi[i]=sigmoid(xi[i]);           /*隐层输出*/
			} 
			for(j=0;j<nj;j++) 
			{
				t=0;
				for(i=0;i<ni;i++)
					t+=wij[i][j]*yi[i];
				xj[j]=t+thj[j];
				yj[j]=sigmoid(xj[j]);
			}                                /*输出层输出*/

			for(j=0;j<nj;j++)				/*输出层单样本点误差变化率*/ 
				pxj[j]=yj[j]*(1-yj[j])*(yj[j]-d[k][j]);
			for(i=0;i<ni;i++)				/*隐层单样本点误差变化率*/ 
			{ 
				t=0;
				for(j=0;j<nj;j++)
					t+=pxj[j]*wij[i][j];
				pxi[i]=yi[i]*(1-yi[i])*t;
			}
			for(j=0;j<nj;j++)
			{
				//  thj[j]=thj[j]-nr*pxj[j];
				v0=thj[j];
				thj[j]=thj[j]-0.7*nr*pxj[j]+0.3*u0;
				// thj[j]=thj[j]-nr*pxj[j];
				u0=thj[j]-v0;
				for(i=0;i<ni;i++)
				{
					v1=wij[i][j];
					wij[i][j]=wij[i][j]-0.7*nr*pxj[j]*yi[i]+0.3*u1;
					u1=wij[i][j]-v1;
					//wij[i][j]=wij[i][j]-nr*pxj[j]*yi[i];     /*隐层到输出层权值修正,其中nr为步长*/
				}
			}
			for(i=0;i<ni;i++) 
			{
				v2=thi[i];
				thi[i]=thi[i]-0.7*nr*pxi[i]+0.3*u2;
				u2=thi[i]-v2;
				// thi[i]=thi[i]-nr*pxi[i];
				for(h=0;h<nh;h++)
				{
					v3=whi[h][i];
					whi[h][i]=whi[h][i]-0.7*nr*pxi[i]*x[k][h]+0.3*u3;
					u3=whi[h][i]-v3;
					//whi[h][i]=whi[h][i]-nr*pxi[i]*x[k][h];    /*输入层到隐层权值修正,其中nr为步长*/
				}
			}
			t=0; 
			for(j=0;j<nj;j++) 
				t+=(yj[j]-d[k][j])*(yj[j]-d[k][j])/2.0; 
			error[k]=t; 
			gerror+=error[k];							/*全局误差g(lobal)error*/ 
		}
		/*单样本循环结束*/ 

		if(gerror<EPS)
			break; 
	}
	/* 学习循环结束*/ 
	printf("%f,%f,%f,%f,%f,%f",thi[0],thj[0],wij[0][0],wij[0][1],whi[1][0],whi[0][1]);
	writew(); 
	printf("\t\nGlobal error=%f\n",gerror);
	printf("\t\nAre you satisfied with the global error?\n"); 
	printf("Press any key to choose a next task!\n"); 
	getch(); 
} 
/*-------------------------------------------------*/
void testsample(void) 
{
	float tx[nh],t,xj[nj],xi[ni],yj[nj],yi[ni]; 
	if(fp2==0) 
	{ 
		//   clrscr(); 
		printf("\t\ncan not find the weight file:w.txt\n"); 
		exit(0); 
	} 
	readw(); 

	
	for(ff=0;ff<test;ff++)                        /*测试样本预测、结果保存*/
	{
		for(h=0;h<nh;h++) 
			fscanf(fp3,"%f,",&tx[h]); 
		for(h=0;h<nh;h++) 
			tx[h]=(tx[h]-xmin[h])/(xmax[h]-xmin[h]); /*归一化处理*/
		for(i=0;i<ni;i++) 
		{ 
			t=0; 
			for(h=0;h<nh;h++) 
				t+=whi[h][i]*tx[h];
			xi[i]=t+thi[i];
			yi[i]=sigmoid(xi[i]);
		} 
		for(j=0;j<nj;j++) 
		{ 
			t=0; 
			for(i=0;i<ni;i++) 
				t+=wij[i][j]*yi[i];
			xj[j]=t+thj[j]; 
			yj[j]=sigmoid(xj[j]); 
		} 
		// printf("\t\nNetwork output:\n");        /*正向预测*/
		for(j=0;j<nj;j++)                         /*保存结果*/
		{ 
			yj[j]=yj[j]*(dmax[j]-dmin[j])+dmin[j]; 
			fprintf(fp4,"%f\n",yj[j]); 
		} 
		// tx[nh-1]=yj[0];
		//rewind(fp4); 
		//    for(h=0;h<nh;h++) /*测试样本输入*/
		// fscanf(fp3,"%f,",&tx[h]); 
 }

   printf("\t\nAre you satisfied with the output?\n"); 
   printf("Press any key to choose a next task!\n"); 
   getch();
} 
/*----------------------------------------------*/ 
void writew(void) 
{ 
rewind(fp2); 
for(h=0;h<nh;h++) 
 { 
  for(i=0;i<ni;i++) 
   fprintf(fp2,"%8.3f ",whi[h][i]); 
   fprintf(fp2,"\n"); 
 } 
fprintf(fp2,"\n"); 

for(i=0;i<ni;i++) 
 fprintf(fp2,"%8.3f ",thi[i]);
fprintf(fp2,"\n\n"); 

for(j=0;j<nj;j++) 
 { 
  for(i=0;i<ni;i++) 
   fprintf(fp2,"%8.3f ",wij[i][j]); 
  fprintf(fp2,"\n"); 
 } 
fprintf(fp2,"\n"); 
for(j=0;j<nj;j++) 
 fprintf(fp2,"%8.3f ",thj[j]); 
} 
/*------------------------------------------------*/ 
void readw(void) 
{ 
for(h=0;h<nh;h++) 
 for(i=0;i<ni;i++) 
   fscanf(fp2,"%f",&whi[h][i]); 
for(i=0;i<ni;i++) 
   fscanf(fp2,"%f",&thi[i]);
for(j=0;j<nj;j++) 
   for(i=0;i<ni;i++) 
      fscanf(fp2,"%f",&wij[i][j]); 
for(j=0;j<nj;j++) 
   fscanf(fp2,"%f",&thj[j]); 
} 
/*--------------------------------*/ 
float sigmoid(float a) 
{
	return (1.0/(1+exp(-a)));
}
/*--------------------------------*/ 
double ranu(void) 
{
	static double xrand=3.0; 
	double m=8589934592.0, a=30517578125.0; 
lp: xrand=fmod(xrand*a,m);     /*整除取余*/
   if(xrand>1.0) 
	   return(xrand/m); 
   else 
   {
	   xrand=1.0;
	   goto lp;
   }
}
/*----------------------------------*/ 

void main() 
{ 
fp1=fopen("sample.txt","r");
fp2=fopen("w.txt","r+");
fp3=fopen("test.txt","r+");
fp4=fopen("testre.txt","r+");
init();
  while(1)
 {
   system("cls"); 
   printf("\t\n    Please choose a next task...\n\n"); 
   printf("\t\n     (S) to start learning.\n"); 
   printf("\t\n     (T) to test samples.\n"); 
   printf("\t\n     (R) to resume learning.\n"); 
   printf("\t\n     (Q) quit.\n");
   switch(getchar()) 
  {
    case 's': startlearning();break; 
    case 't': testsample();break;
    case 'r': startlearning();break; 
    case 'q': exit(0);break; 
  } 
 }
fclose(fp1); 
fclose(fp2);
fclose(fp3);
fclose(fp4);
getch();
} 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值