//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();
}
BP神经网络算法实现
最新推荐文章于 2024-07-27 00:32:18 发布