//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(); } /*----------------By ahzhming@163.com海阔天空-------------------------*/