📄 nat.c
字号:
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <malloc.h>
#include <string.h>
/* define constant used throughout function */
#define NMXUNIT 20/*max no of units in a layer*/
#define NMXHLR 5/* max no. of hidden layer*/
#define NMXOATTR 20/*max no. of output feature*/
#define NMXINP 200/*max no. of input samples*/
#define NMXIATTR 20/*max no. of input features*/
#define SEXIT 3/*exit successfully*/
#define RESTRT 2/*restart */
#define FEXIT 1/*exit in failure*/
#define CONTNE 0/*continue calculation*/
/* Data base:declarations of variables */
float eta; /** learning rate **/
float alpha; /**momentum rate **/
float err_curr; /** normalized error **/
float maxe; /**max allowed system error **/
float maxep; /**max allowed pattern error**/
float *wtptr[NMXHLR+1];
float *outptr[NMXHLR+2];
float *errptr[NMXHLR+2];
float *delw[NMXHLR+1];
float target[NMXINP][NMXOATTR];
float input[NMXINP][NMXIATTR],ep[NMXINP];
float outpt[NMXINP][NMXOATTR];
int nunit[NMXHLR+2],nhlayer,ninput,ninattr,noutattr;
int result,cnt,cnt_num;
int nsnew,nsold;
char task_name[20];
FILE *fp1,*fp2,*fp3,*fopen();
int fplot10;
/*random number generator(computer independent)*/
long randseed=568731L;
int random()
{
randseed=15625l*randseed+22221L;
return((randseed>>16)& 0x7FFF);
}
/*allocate dynamic storage for the net*/
init()
{
int len1,len2,i,k;
float *p1,*p2,*p3,*p4;
len1=len2=0;
nunit[nhlayer+2]=0;
for (i=0;i<(nhlayer+2);i++){
len1 +=(nunit[i]+1)*nunit[i+1];
len2 +=nunit[i]+1;
}
p1=(float *) calloc(len1+1,sizeof(float));
p2=(float *) calloc(len2+1,sizeof(float));
p3=(float *) calloc(len2+1,sizeof(float));
p4=(float *) calloc(len1+1,sizeof(float));
/* set up initial pointers */
wtptr[0]=p1;
outptr[0]=p2;
errptr[0]=p3;
delw[0]=p4;
/* set up the rest of pointers */
for (i=1;i<(nhlayer+1);i++){
wtptr[i]=wtptr[i-1]+nunit[i]*(nunit[i-1]+1);
delw[i]=delw[i-1]+nunit[i]*(nunit[i-1]+1);
}
for (i=1;i<(nhlayer+2);i++){
outptr[i]=outptr[i-1]+nunit[i-1]+1;
errptr[i]=errptr[i-1]+nunit[i-1]+1;
}
/* set up threshold outputs */
for (i=0;i<nhlayer+1;i++){
*(outptr[i]+nunit[i])=1.0;
}
}
/* initialize weights with random number between
-.5 and +.5 */
initwt()
{
int i,j;
for(j=0;j<nhlayer+1;j++)
for(i=0;i<(nunit[j]+1)*nunit[j+1];i++){
*(wtptr[j]+i)=random()/pow(2.,15.)-.5;
*(delw[j]+i)=0.;
}
}
set_up()
{
int i;
eta=.9;
printf("\nMomentum rate eta(default=.9)?:");
scanf("%f",&eta);
alpha=.7;
printf("\nLeaning rate alpha (default=.7)?:");
scanf("%f",&alpha);
maxe=.01,maxep=.001;
printf("\nMax total error(default=.01)?:");
scanf("%f",&maxe);
printf("\nMax individual error(default=.001)?:");
scanf("%f",&maxep);
cnt_num=1000;
printf("\nMax number of iteration(default=1000)?:");
scanf("%d",&cnt_num);
printf("\nNumber of hidden layers?:");
scanf("%d",&nhlayer);
for(i=0;i<nhlayer;i++){
printf("\n\nNumber of units for hidden layer %d?:",i+1);
scanf("%d",&nunit[i+1]);
}
printf("\nCreate error file ?if so type 1,or type 0:");
scanf("%d",&fplot10);
printf("\nExecution starts");
nunit[nhlayer+1]=noutattr;
nunit[0]=ninattr;
}
/* read file for net architecture and learning
parameters.file name has suffix _v.dat */
dread (taskname)
char *taskname;
{
int i,j,c;
char var_file_name[20];
strcpy(var_file_name,taskname);
strcat(var_file_name,"_v.dat");
if((fp1=fopen(var_file_name,"r"))==NULL)
{
perror("\n Cannot open data file");
exit(0);
}
fscanf(fp1,"%d %d %d %f %f %d %d\n",&ninput,&noutattr,
&ninattr,&eta,&alpha,&nhlayer,&cnt_num);
for (i=0;i<nhlayer+2;i++)
{
fscanf(fp1," %d ",&nunit[i]);
}
if((c=fclose(fp1)) != 0)
printf("\n File cannot be closed %d",c);
}
/* read file containing weights and thresholds.
file name has suffix_w.dat */
wtread (taskname)
char *taskname;
{
int i,j,c;
char wt_file_name[20];
strcpy(wt_file_name,taskname);
strcat(wt_file_name,"_w.dat");
if((fp2=fopen(wt_file_name,"r"))==NULL)
{
perror("\n Cannot open data file");
exit(0);
}
for(i=0;i<nhlayer+1;i++){
for(j=0;j<(nunit[i]+1)*nunit[i+1];j++){
fscanf(fp2," %f ",(wtptr[i]+j));
}
fscanf(fp2,"\n");
}
if((c=fclose(fp2)) != 0)
printf("\nFile cannot be closed %d",c);
}
/* create file for net architecture and learning
paramters .File name has suffix _v.dat */
dwrite(taskname)
char *taskname;{
int i,j,c;
char var_file_name[20];
strcpy(var_file_name,taskname);
strcat(var_file_name,"_v.dat");
if((fp1=fopen(var_file_name,"w+"))==NULL)
{
perror("Cannot open data file");
exit(0);
}
fprintf(fp1,"%d %d %d %f %f %d %d\n",ninput,noutattr,
ninattr,eta,alpha,nhlayer,cnt_num);
for(i=0;i<nhlayer+2;i++){
fprintf(fp1," %d ",nunit[i]);
}
fprintf(fp1,"\n%d %f",cnt,err_curr);
fprintf(fp1,"\n");
for(i=0;i<ninput;i++){
for (j=0;j<noutattr;j++)
fprintf(fp1,"%f",outpt[i][j]);
fprintf(fp1,"\n");
}
if((c=fclose(fp1)) !=0)
printf("\nFile cannot be closed %d",c);
}
/* create file for saving weights and thresholds
lerning from training. file name has suffix
_w.dat */
wtwrite(taskname)
char *taskname;
{
int i,j,c,k;
char wt_file_name[20];
strcpy(wt_file_name,taskname);
strcat(wt_file_name,"_w.dat");
if((fp2=fopen(wt_file_name,"w+"))==NULL)
{
perror("Cannat open data file");
exit(0);
}
k=0;
for(i=0;i<nhlayer+1;i++)
{
for(j=0;j<(nunit[i]+1)*nunit[i];j++)
{
if(k==8)
{
k=0;
fprintf(fp2,"\n");
}
fprintf(fp2," %f ",*(wtptr[i]+j));
k++;
}
}
if((c=fclose(fp2)) != 0)
printf("\nFile cannot be closed %d",c);
}
/* bottom_up calculation of net for input pattern i */
void forward(i)
{
int m,n,p,offset;
float net;
/* input level output calculation */
for(m=0;m<ninattr;m++)
*(outptr[0]+m)=input[i][m];
/* hidden & output layer output calcultion */
for(m=1;m<nhlayer+2;m++){
for(n=0;n<nunit[m];n++){
net=0.0;
for(p=0;p<nunit[m-1]+1;p++){
offset=(nunit[m-1]+1)*n+p;
net += *(wtptr[m-1]+offset)
*(*(outptr[m-1]+p));
}
*(outptr[m]+n)=1/(1+exp(-net));
}
}
for(n=0;n<nunit[nhlayer+1];n++)
outpt[i][n]=*(outptr[nhlayer+1]+n);
}
/* several condition are checked to see whether
leraning should terminate */
int introspective(nfrom,nto)
int nfrom;
int nto;
{
int i,flag;
/* reached max iteration ?*/
if(cnt>=cnt_num)return(FEXIT);
/* error for each pattern small enough?*/
nsnew=0;
flag=1;
for(i=nfrom;(i<nto) && (flag==1);i++){
if(ep[i]<=maxep)nsnew++;
else flag=0;
}
if(flag==1) return(SEXIT);
/* system total error small enough? */
if(err_curr <=maxe)return(SEXIT);
return(CONTNE);
}
/* threshold is treated as weight of link from
a virtual node whose output value is unity */
int rumelhart(from_snum,to_snum)
int from_snum;
int to_snum;
{
int i,j,k,m,n,p,offset,index;
float out;
char *err_file="criter.dat";
nsold=0;
cnt=0;
result=CONTNE;
if(fplot10==1)
if((fp3=fopen(err_file,"w"))==NULL)
{
perror("Cannot open error file");
exit(0);
}
do {
err_curr=0.0;
for(i=from_snum;i<to_snum;i++){
forward(i);
for(m=0;m<nunit[nhlayer+1];m++){
out = *(outptr[nhlayer+1]+m);
*(errptr[nhlayer+1]+m)=(target[i][m]-out)
*(1-out)*out;
}
for(m=nhlayer+1;m>=1;m--){
for(n=0;n<nunit[m-1]+1;n++){
*(errptr[m-1]+n)=0.0;
for(p=0;p<nunit[m];p++){
offset=(nunit[m-1]+1)*p+n;
*(delw[m-1]+offset)=eta*(*(errptr[m]+p))
*(*(outptr[m-1]+n))
+alpha*(*(delw[m-1]+offset));
*(errptr[m-1]+n) += *(errptr[m]+p)*(*(wtptr[m-1]+offset));
}
*(errptr[m-1]+n)= *(errptr[m-1]+n)*(1-*(outptr[m-1]+n))
*(*(outptr[m-1]+n));
}
}
/* weight changes */
for(m=1;m<nhlayer+2;m++){
for(n=0;n<nunit[m];n++){
for(p=0;p<nunit[m-1]+1;p++){
offset=(nunit[m-1]+1)*n+p;
*(wtptr[m-1]+offset) += *(delw[m-1]+offset);
}
}
}
ep[i]=0.0;
for(m=0;m<nunit[nhlayer+1];m++){
ep[i] += fabs((target[i][m]-*(outptr[nhlayer+1]+m)));
}
err_curr +=ep[i]*ep[i];
}
err_curr=.5*err_curr/ninput;
if(fplot10==1)
fprintf(fp3,"%ld,%2.9f\n",cnt,err_curr);
cnt++;
result=introspective(from_snum,to_snum);
}while(result==CONTNE);
/* update output with changed weights */
for(i=from_snum;i<to_snum;i++)forward(i);
for(i=0;i<nhlayer+1;i++){
index=0;
for(j=0;j<nunit[i+1];j++)
{
printf("\n\nWeights between unit %d of layer %d",
j,i+1);
printf("and units of layer %d\n",i);
for(k=0;k<nunit[i];k++)
printf("%f",*(wtptr[i]+index++));
printf("\nThreshold of unit %d of layer %d is %f",
j,i+1,*(wtptr[i]+index++));
}
}
for(i=0;i<ninput;i++)
for(j=0;j<noutattr;j++)
printf("\n\n sample %d output %d=%ftarget %d=%f",
i,j,outpt[i][j],j,target[i][j]);
printf("\n\nTotal number of iteration is %d",cnt);
printf("\nNormalized system error is %f\n\n\n",err_curr);
return(result);
}
/* read in the input data file specified by user
during the interactive session */
user_session()
{
int i,j,showdata;
char fnam[20],dtype[20];
FILE *fp;
printf("\nStart of learning session");
printf("\n\t Enter the task name:");
scanf("%s",task_name);
printf("\n How many features in input pattern?:");
scanf("%d",&ninattr);
printf("\nHow many output units?:");
scanf("%d",&noutattr);
printf("\nTotal number of input sample?:");
scanf("%d",&ninput);
strcpy(fnam,task_name);
strcat(fnam,".dat");
printf("\nInput file name is %s",fnam);
if((fp=fopen(fnam,"r"))==NULL)
{
printf("\nFile %s does not exist",fnam);
exit(0);
}
printf("\n Do you want to look at data just read?");
printf("\nAnswer yes or no:");
scanf("%s",dtype);
showdata=((dtype[0]=='y')||(dtype[0]=='y'));
for(i=0;i<ninput;i++){
for(j=0;j<ninattr;j++){
fscanf(fp,"%f",&input[i][j]);
if(showdata)printf("%f",input[i][j]);
}
for(j=0;j<noutattr;j++){
fscanf(fp,"%f",&target[i][j]);
if(showdata)printf("%f\n",target[i][j]);
}
}
if((i=fclose(fp)) != 0)
{
printf("\nFile cannot be closed %d",i);
exit(0);
}
}
/* main body of learning */
learning ()
{
int result;
user_session();
set_up();
init();
do {
initwt();
result=rumelhart(0,ninput);
}while(result==RESTRT);
if(result==FEXIT)
{
printf("\nMax number of iterations reached,");
printf("\nbut failed to decrease system");
printf("\n error sufficiently");
}
dwrite(task_name);
wtwrite(task_name);
}
/* main body of output generation */
output_generation()
{
int i,m,nsample;
char ans[10];
char dfile[20];
char fname[20];
FILE *fp;
printf("\n Generation of output for a new pattern");
printf("\n\t Presenttask name is %s",task_name);
printf("\n\t Work on a different task?");
printf("\n\tAnswer yes or no:");
scanf("%s",ans);
if((ans[0]=='y') || (ans[0]=='y'))
{
printf("\n\tType the task name:");
scanf("%s",task_name);
dread(task_name);
init();
wtread(task_name);
for (i=0;i<10;i++){
}
}
/* input data for output generation are created */
printf("\n Enter file name for patterns to");
printf(" be processed:");
scanf("%s",dfile);
if((fp1=fopen(dfile,"r"))==NULL)
{
perror("Cannot open file");
exit(0);
}
printf("\nEnter number of patterns for processing:");
scanf("%d",&nsample);
for(i=0;i<nsample;i++)
for(m=0;m<ninattr;m++)
fscanf(fp1,"%f",&input[i][m]);
/* output generation calculation starts */
printf("\n enter output file name=>");
scanf("%s",fname);
if((fp=fopen(fname,"w+"))==NULL)
{
printf("connot open file");
exit(0);
}
for(i=0;i<nsample;i++)
{
forward(i);
for(m=0;m<noutattr;m++){
printf("\n sample %d output %d=%f",
i,m,*(outptr[nhlayer+1]+m));
printf("\n");
fprintf(fp,"%d %f\n",i,*(outptr[nhlayer+1]+m));
}
}
printf("\nOutput have been generated");
if((i=fclose(fp1)) != 0)
printf("\nFile cannot be closed %d",i);
}
/* ***********MAIN*************** */
main()
{
char select[20],cont[10];
strcpy(task_name,"*******");
do {
printf("\n Select L(earning) or O(utput generation)\n");
do {
scanf("%s",select);
switch(select[0]){
case'o':
case'O':
output_generation();
break;
case'l':
case'L':
learning();
break;
default:
printf("\nanswer learning or output generation");
break;
}
} while((select[0] != 'o') && (select[0] != 'O')
&&(select[0] != 'l')&&(select[0] != 'L'));
printf("\nDo you want to continue?");
scanf("%s",cont);
}while((cont[0]=='y')||(cont[0]=='Y'));
printf("\nIt is all finished.");
printf("\n Good bye");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -