home *** CD-ROM | disk | FTP | other *** search
- /* ************************************************** */
- /* file bp.c: contains the main program and network */
- /* creation routines. */
- /* */
- /* Copyright (c) 1991 by Donald R. Tveter */
- /* */
- /* ************************************************** */
-
- #include <stdio.h>
- #include <signal.h>
- #include <setjmp.h>
-
- #ifdef DOS16
- #include <stdlib.h>
- #include <time.h>
- #endif
-
- #ifdef DOS32
- #include <stdlib.h>
- #include <time.h>
- #endif
-
- #ifdef UNIX
- #include <malloc.h>
- #define SIGINT 2
- #define CLOCKS_PER_SEC 1000000.0
- extern long clock();
- #endif
-
- #ifdef INTEGER
- #include "ibp.h"
- #else
- #include "rbp.h"
- #endif
-
- /* an addition for large data sets */
-
- INT32 g = 0;
-
- /* built-in C functions */
-
- extern int rand();
- extern void srand();
-
- /* functions from io.c */
-
- #ifdef INTEGER
- extern int scale();
- extern REAL unscale();
- #endif
-
- extern void help(), printweights();
- extern void restoreweights(), saveweights(), texterror();
- extern WTTYPE rdr();
- extern int pg(), printoutunits(), readch(), readint();
- extern REAL readchar();
- extern char *readstr();
-
- /* functions from misc.c */
-
- extern void clear(), nullpatterns(), findendofpats(), kick();
- extern void setonepat(), setoutputpat(), whittle();
- extern int loadpat(), patcheck(), run();
-
- /* global variables used in all versions */
-
- char activation; /* activation function, p or s */
- WTTYPE alpha; /* momentum term */
- char backprop; /* flags whether to back propagate error for */
- /* units close to their targets */
- int benchmark; /* flags benchmarking in progress */
- int bufferend; /* index of last character in input line */
- int bufferptr; /* position of next character in buffer */
- char buffer[buffsize];/* holds contents of one input line */
- int ch; /* general purpose character variable */
- FILE *copy; /* file pointer to copy file */
- char copyflag; /* + for copying, - for no copy */
- jmp_buf cmdloopstate; /* to save state in case of a SIGINT */
- WTTYPE D; /* sigmoid sharpness */
- FILE *data; /* file for original data */
- char *datafilename; /* copy of the data file name saved here */
- WTTYPE dbdeta; /* the initial eta value for the DBD method */
- WTTYPE decay; /* the decay parameter for the DBD method */
- char deriv; /* flags type of derivative to use */
- char echo; /* controls echoing of characters during input */
- char emptystring; /* for unused string values */
- REAL errorperunit; /* average unsquared error on output layer */
- WTTYPE eta; /* basic learning rate */
- WTTYPE eta2; /* learning rate for lower layers */
- WTTYPE etamax; /* the maximum eta for the DBD method */
- int extraconnect; /* flags the use of connections between */
- /* non-adjacent layers */
- FILE *filestack[4]; /* allows for nested reads from files */
- int filestackptr; /* has the index of the current file */
- int format[maxformat];/* each value in format indicates where to put */
- /* a blank for compressed output mode or a */
- /* carriage return for real output */
- int goal; /* successes desired when benchmarking */
- UNIT *hlayer; /* pointer to list of units in second layer */
- UNIT *ilayer; /* pointer to list of units in third layer */
- char informat; /* controls format to read numbers */
- WTTYPE initialkick; /* the range weights are initialized to */
- char *inputfile; /* name of file to take extra commands from */
- int iter; /* for counting iterations in one run */
- UNIT *jlayer; /* pointer to list of units in fourth layer */
- WTTYPE kappa; /* the DBD learning parameter */
- UNIT *klayer; /* pointer to list of units in fifth layer */
- WTTYPE kicksize; /* range of random weights when benchmarking */
- LAYER *last; /* has address of the output layer */
- int lastprint; /* last iteration pattern responses printed */
- int lastsave; /* last time weights were saved */
- INT32 lineno; /* counts lines for paging */
- int maxiter; /* maximum iterations when benchmarking */
- int maxtries; /* max networks to try when benchmarking */
- short nlayers; /* number of layers in network */
- WTTYPE noise; /* noise parameter for dbd and qp */
- int npats; /* number of patterns currently in use */
- char outformat; /* controls format to print output */
- char outstr[OUTSTRSIZE]; /* the output string */
- int pagesize; /* size of page for pg */
- char patform; /* flags general or classification pattern format */
- REAL pct_right; /* % of training patterns correct */
- int prevnpats; /* previous number of patterns, initially 0 */
- int printrate; /* printrate when benchmarking */
- WTTYPE qmark; /* value for ? in compressed input */
- int readerror; /* flags an error in reading a value */
- int readingpattern; /* flags reading pattern state */
- char ringbell; /* flag to ring bell when finished */
- int right; /* number of training patterns learned */
- int saverate; /* rate at which to save weights */
- unsigned seed; /* seed for generating random weights */
- SEEDNODE *seedstart; /* the list of user defined seeds */
- short skiprate; /* number of times to bypass a learned pattern */
- LAYER *start; /* has address of the input layer */
- char summary; /* flags summary output mode */
- int testpat; /* pattern to skip when benchmarking; else 0 */
- char *testfile; /* file to take test patterns from */
- WTTYPE theta1; /* the DBD parameter */
- WTTYPE theta2; /* 1 - theta1 */
- WTTYPE toler; /* value used in testing for completion */
- WTTYPE toosmall; /* weights smaller than toosmall were removed */
- #ifdef INTEGER
- INT32 totaldiff; /* totals errors to find average error per unit */
- #else
- REAL totaldiff;
- #endif
- int totaliter; /* counts total iterations for the program */
- char *trainfile; /* file to take training patterns from */
- int unlearned; /* number unlearned in last learning cycle */
- char update; /* flags type of update rule to use */
- char up_to_date_stats;/* + does an extra forward pass after update */
- int wrong; /* number of training patterns unlearned */
- char w[8] = "weights";/* the string, weights */
- char *wtfile; /* file to write weights to */
- char wtformat; /* controls format to save and restore weights */
- char wtlimithit; /* flags whether the limit has been hit */
- int wttotal; /* total number of weights in use */
-
- /* global variable for the symmetric integer version */
-
- #ifdef SYMMETRIC
- WTTYPE stdthresh; /* the standard threshold weight value */
- #endif
-
- /* given a layer no. and unit no. locateunit returns the address */
- UNIT *locateunit(layerno,unitno)
- int layerno, unitno;
- {int i;
- UNIT *u;
- LAYER *layer;
-
- layer = start;
- for(i=1;i<=(layerno-1);i++) layer = layer->next;
- u = (UNIT *) layer->units;
- while (u != NULL && u->unitnumber != unitno) u = u->next;
- if (u == NULL)
- printf("there is no unit %3d in layer %3d\n",unitno,layerno);
- return(u);
- }
-
- #ifdef SYMMETRIC
-
- INT32 wtaddress(i,j,biasunit,type,size) /* Returns the address of a */
- int i,j; /* weight (1), olddw (2), */
- int biasunit; /* eta (3), total (4), */
- int type; /* or slope (5) */
- int size; /* One is created if it */
- /* doesn't already exist. */
- { int k;
- INT32 addr;
- UNIT *u;
- WTNODE *w;
-
- if (biasunit) addr = (INT32) malloc(size);
- else if (j >= i) addr = (INT32) malloc(size);
- else /* the item already exists, so find its address */
- {
- u = locateunit(2,j);
- w = (WTNODE *) u->wtlist;
- k = 1;
- while (k < i)
- {
- w = w->next;
- k = k + 1;
- };
- if (type == 1) addr = (INT32) w->weight;
- else if (type == 2) addr = (INT32) w->olddw;
- else if (type == 3) addr = (INT32) w->eta;
- else if (type == 4) addr = (INT32) w->total;
- else addr = (INT32) w->slope;
- };
- return(addr);
- }
-
- void setweight(w,i,j,biasunit) /* set initial values in w */
- WTNODE *w;
- short i, j;
- int biasunit;
- {WTTYPE *s;
-
- s = (WTTYPE *) wtaddress(i,j,biasunit,1,WTSIZE);
- *s = 0;
- w->weight = s;
- s = (WTTYPE *) wtaddress(i,j,biasunit,2,WTSIZE);
- *s = 0;
- w->olddw = s;
- s = (WTTYPE *) wtaddress(i,j,biasunit,3,WTSIZE);
- *s = eta;
- w->eta = s;
- #ifdef INTEGER
- w->total = (INT32 *) wtaddress(i,j,biasunit,4,sizeof(INT32));
- #else
- w->total = (REAL *) wtaddress(i,j,biasunit,4,sizeof(REAL));
- #endif
- }
-
- #else
-
- void setweight(w,i,j,biasunit) /* set initial values in w */
- WTNODE *w;
- short i,j;
- int biasunit;
- {
- w->weight = 0;
- w->olddw = 0;
- w->slope = 0;
- w->eta = dbdeta;
- }
-
- #endif
-
- LAYER *mklayer(prevlayer,n) /* creates a layer of n units, pointers */
- LAYER *prevlayer; /* and weights back to the units in the */
- int n; /* previous layer and links this new */
- /* layer into the list of layers */
- {UNIT *front, *p, *q, *bias, *prev, *ptr;
- WTNODE *wfront, *wprev, *w;
- LAYER *lptr;
- int i, j, count;
-
- /* make a list of nodes in this layer */
-
- count = 1;
- front = (UNIT *) malloc(sizeof(UNIT));
- front->unitnumber = count;
- front->layernumber = nlayers;
- prev = front;
- for(i=1;i<n;i++)
- {
- count = count + 1;
- ptr = (UNIT *) malloc(sizeof(UNIT));
- prev->next = ptr;
- ptr->unitnumber = count;
- ptr->layernumber = nlayers;
- prev = ptr;
- };
- prev->next = NULL;
-
- /* make a LAYER node to point to this list of units */
-
- lptr = (LAYER *) malloc(sizeof(LAYER));
- lptr->unitcount = n;
- lptr->patstart = NULL;
- lptr->currentpat = NULL;
- lptr->backlayer = prevlayer;
- lptr->next = NULL;
- (UNIT *) lptr->units = front; /* connect the list of units */
-
- /* return if this is the input layer */
-
- if (prevlayer == NULL) return(lptr);
- prevlayer->next = lptr;
-
- /* If we are working on a deeper layer, for every node in this layer, */
- /* create a linked list back to units in the previous layer. */
-
- i = 1;
- q = front;
- while (q != NULL) /* do a unit */
- {
- j = 1; /* handle first connection */
- p = (UNIT *) prevlayer->units;
- wfront = (WTNODE *) malloc(sizeof(WTNODE));
- wttotal = wttotal + 1;
- (WTNODE *) q->wtlist = wfront;
- wprev = wfront;
- (UNIT *) wfront->backunit = p;
- setweight(wfront,i,j,0);
- p = p->next;
- while (p != NULL) /* handle rest of connections */
- {
- j = j + 1;
- w = (WTNODE *) malloc(sizeof(WTNODE));
- wttotal = wttotal + 1;
- wprev->next = w;
- (UNIT *) w->backunit = p;
- setweight(w,i,j,0);
- wprev = w;
- p = p->next;
- };
- j = j + 1;
- bias = (UNIT *) malloc(sizeof(UNIT)); /* create a bias unit */
- bias->oj = scale(1.0);
- bias->layernumber = nlayers;
- bias->unitnumber = 32767; /* bias unit is unit 32767 */
- w = (WTNODE *) malloc(sizeof(WTNODE)); /* connect to end of list */
- wttotal = wttotal + 1;
- wprev->next = w;
- (UNIT *) w->backunit = bias;
- setweight(w,n+2,i,1);
- w->next = NULL;
- q = q->next;
- i = i + 1;
- };
- return(lptr);
- }
-
- #ifndef SYMMETRIC
-
- void connect(a,b,range) /* add a connection from unit a to unit b */
- UNIT *a, *b; /* connections go in increasing order */
- WTTYPE range;
-
- {WTNODE *wnew, *w, *wprev;
- UNIT *wunit;
- int farenough;
-
- wnew = (WTNODE *) malloc(sizeof(WTNODE));
- wttotal = wttotal + 1;
- wnew->eta = dbdeta;
- wnew->weight = range * rand() / 32768;
- if (rand() > 16383) wnew->weight = -wnew->weight;
- wnew->olddw = 0;
- wnew->slope = 0;
- (UNIT *) wnew->backunit = a;
- w = (WTNODE *) b->wtlist;
- wprev = NULL;
- wunit = (UNIT *) w->backunit;
- farenough = 0; /* insert the weight in order */
- while (w != NULL && !farenough)
- if (wunit->layernumber > a->layernumber) farenough = 1;
- else if (wunit->layernumber == a->layernumber)
- while (w != NULL && !farenough)
- {
- if (wunit->unitnumber < a->unitnumber &&
- wunit->layernumber == a->layernumber)
- {
- wprev = w;
- w = w->next;
- wunit = (UNIT *) w->backunit;
- }
- else farenough = 1;
- }
- else
- {
- wprev = w;
- w = w->next;
- wunit = (UNIT *) w->backunit;
- };
- if (wprev == NULL)
- {
- wnew->next = w;
- (WTNODE *) b->wtlist = wnew;
- }
- else
- {
- wnew->next = w;
- wprev->next = wnew;
- };
- }
-
- void addhiddenunit(layerno,range)
- int layerno; /* add hidden unit to end of the layer */
- WTTYPE range;
- {
- LAYER *lptr, *prevlayer, *nextlayer;
- UNIT *u, *prevu, *p, *bias;
- WTNODE *wnode;
- int i, unitno;
-
- lptr = start;
- for (i=1;i <= (layerno - 1); i++) lptr = lptr->next;
- unitno = lptr->unitcount;
- lptr->unitcount = unitno + 1;
- prevu = locateunit(layerno,unitno);
- if (prevu == NULL) return;
- u = (UNIT *) malloc(sizeof(UNIT));
- prevu->next = u;
- u->next = NULL;
- u->unitnumber = unitno + 1;
- u->layernumber = layerno;
- bias = (UNIT *) malloc(sizeof(UNIT));
- bias->oj = scale(1.0);
- bias->layernumber = layerno;
- bias->unitnumber = 32767; /* bias unit is unit 32767 */
- wnode = (WTNODE *) malloc(sizeof(WTNODE));
- wttotal = wttotal + 1;
- wnode->weight = range * rand() / 32768;
- if (rand() > 16383) wnode->weight = -wnode->weight;
- wnode->olddw = 0;
- wnode->slope = 0;
- wnode->eta = dbdeta;
- wnode->next = NULL;
- (UNIT *) wnode->backunit = bias;
- (WTNODE *) u->wtlist = wnode;
- prevlayer = lptr->backlayer;
- p = (UNIT *) prevlayer->units;
- while (p != NULL)
- {
- connect(p,u,range);
- p = p->next;
- };
- nextlayer = lptr->next;
- p = (UNIT *) nextlayer->units;
- while (p != NULL)
- {
- connect(u,p,range);
- p = p->next;
- };
- }
-
- #endif
-
- void readpatson(layer,command)
- LAYER *layer;
- int command;
-
- {PATLIST *pl;
- int i, answer, veclength;
- WTTYPE *val;
-
- pl = (PATLIST *) malloc(sizeof(PATLIST));
- pl->next = NULL;
- pl->bypass = 0; /* number of times to bypass this pattern */
- pl->pats = NULL; /* no patterns read yet */
- if (layer->patstart == NULL) (PATLIST *) layer->patstart = pl;
- else layer->currentpat->next = pl;
- layer->currentpat = pl;
-
- if (layer == last && (patform == 'c' || patform == 'C'))
- {
- answer = readint(1,last->unitcount,command);
- if (readerror) return;
- val = (WTTYPE *) malloc(sizeof(WTTYPE));
- *val = answer;
- pl->pats = val;
- return;
- };
- veclength = layer->unitcount;
- val = (WTTYPE *) malloc(veclength * sizeof(WTTYPE));
- pl->pats = val;
- for (i=1;i<=veclength;i++)
- {
- if (informat == 'r') *val++ = rdr(GE,(REAL) HCODE,command);
- else *val++ = scale(readchar());
- if (readerror)
- {
- if (readerror == 2 && i == 1) readerror = 2; else readerror = 1;
- return;
- };
- };
- return;
- }
-
- int readpats(number,command)
- int number, command;
- { int i, j;
- PATLIST *pl;
-
- for (i=1;i<=number;i++)
- {
- readpatson(start,command);
- if (readerror == 1) goto failure;
- if (readerror == 2) /* EOF */ break;
- readpatson(last,command);
- if (readerror) goto failure;
- };
- if (readerror == 0) return(number);
- else if (readerror == 2)
- {
- popfile();
- return(i-1);
- };
-
- failure:
- printf("error while reading pattern %d\n",i);
- popfile();
- pl = (PATLIST *) start->patstart;
- for (j=1;j<=prevnpats + i - 2;j++) pl = pl->next;
- pl->next = NULL;
- pl = (PATLIST *) last->patstart;
- for (j=1;j<=prevnpats + i - 2;j++) pl = pl->next;
- pl->next = NULL;
- return(i-1);
- }
-
- void init()
- {int i;
-
- activation = 'p';
- alpha = scale(0.5);
- backprop = 1;
- benchmark = 0;
- bufferend = 0;
- bufferptr = buffsize + 1;
- ch = ' ';
- copyflag = '-'; /* default is to not make a copy */
- D = scale(1.0);
- dbdeta = scale(0.5);
- decay = scale(0.5);
- deriv = 'd';
- echo = '-';
- eta = scale(0.5);
- eta2 = eta;
- etamax = scale(30.0);
- extraconnect = 0;
- format[0] = 0;
- for(i=1;i<=maxformat-1;i++) format[i] = format[i-1] + 10;
- goal = 10;
- informat = 'c';
- initialkick = -1;
- kappa = scale(0.5);
- kicksize = scale(1.0);
- lastprint = 0;
- lastsave = 0;
- maxiter = 1000;
- maxtries = 10;
- noise = 0;
- outformat = 'r';
- pagesize = 24;
- patform = 'g';
- pct_right = 0.0;
- prevnpats = 0;
- qmark = scale(0.5);
- right = 0;
- ringbell = '-';
- skiprate = 0;
- testpat = 0;
- saverate = MAXINT;
- seedstart = (SEEDNODE *) malloc(sizeof(SEEDNODE));
- seedstart->val = 0;
- seedstart->next = NULL;
- #ifdef SYMMETRIC
- stdthresh = -32768; /* indicates no threshold set */
- #endif
- summary = '+';
- theta1 = scale(0.5);
- theta2 = scale(1.0) - theta1;
- toler = scale(0.1);
- toosmall = -1; /* indicates no weights whittled away */
- totaliter = 0;
- update = 'p';
- up_to_date_stats = '-';
- wrong = 0;
- wtfile = &w[0];
- wtformat = 'r';
- wtlimithit = 0;
- wttotal = 0;
- }
-
- int nonetwork()
- {
- if (start != NULL) return(0);
- pg("there is no network\n");
- return(1);
- }
-
- int nopatterns()
- {
- if (npats != 0) return(0);
- pg("there are no patterns\n");
- return(1);
- }
-
- /* for a SIGINT, restart in cmdloop */
- #ifdef UNIX
- void restartcmdloop()
- #else
- void restartcmdloop(int dummy)
- #endif
- {
- while (data != stdin) popfile();
- benchmark = 0;
- signal(SIGINT,restartcmdloop);
- longjmp(cmdloopstate,1);
- }
-
- void cmdloop() /* read commands and process them */
- {
- int finished, layerno, unitno, layer1, layer2, node1, node2;
- int i, itemp, itemp2, successes, tries, sumiter, dobenchmark;
- INT32 itemp32;
- WTTYPE temp, temp2;
- REAL averageiter, averagecpu;
- LAYER *p;
- UNIT *u, *n1, *n2;
- char string[81];
- WTNODE *w;
- SEEDNODE *s, *sprev;
- long cputime, prevcputime, totalcpu;
-
- setjmp(cmdloopstate); /* restart here from SIGINT */
- finished = 0;
- do{
- #ifdef SYMMETRIC
- if (data == stdin) pg("[?!*AaBbCdefhiklmnOoPpQqRrSsTtWwx]? ");
- #else
- if (data == stdin) pg("[?!*AaBbCcdefHhiklmnOoPpQqRrSstWwx]? ");
- #endif
-
- while(ch == ' ' || ch == '\n') ch = readch();
- lineno = 0;
- switch (ch) {
-
- case EOF:
- popfile();
- if (data == stdin) pg("taking commands from stdin now\n");
- break;
-
- case '?':
- sprintf(outstr,"\n%d iterations, s %1d ",totaliter,seed); pg(outstr);
- sprintf(outstr,"k 0 %5.3f, ",unscale(initialkick)); pg(outstr);
- sprintf(outstr,"data file = %s\n",datafilename); pg(outstr);
- sprintf(outstr,"testing file = %s\n",testfile); pg(outstr);
- sprintf(outstr,"training file = %s\n",trainfile); pg(outstr);
- sprintf(outstr,"input file = %s\n",inputfile); pg(outstr);
- sprintf(outstr,"weight file = %s\n",wtfile); pg(outstr);
- sprintf(outstr,"Algorithm: a%c",activation); pg(outstr);
- if (backprop) pg(" b+"); else pg(" b-");
- sprintf(outstr," D%5.2f d%c g %d ",unscale(D),deriv,g); pg(outstr);
- sprintf(outstr,"s%1d t%1d u%c\n",skiprate,testpat,update); pg(outstr);
- sprintf(outstr,"e %7.5f %7.5f",unscale(eta),unscale(eta2)); pg(outstr);
- sprintf(outstr," --- a %7.5f\n",unscale(alpha)); pg(outstr);
- sprintf(outstr,"d d %8.5f e %8.5f ",unscale(decay),unscale(dbdeta));
- pg(outstr);
- sprintf(outstr," k %8.5f m %8.5f ",unscale(kappa),unscale(etamax));
- pg(outstr);
- sprintf(outstr," n %8.5f t %8.5f\n",unscale(noise),unscale(theta1));
- pg(outstr);
- sprintf(outstr,"tolerance = %4.2f\n",unscale(toler)); pg(outstr);
- sprintf(outstr,"f b%c c%c e%c i%c",ringbell,copyflag,echo,informat);
- pg(outstr);
- sprintf(outstr," o%c P %d p%c s%c ",outformat,pagesize,patform,summary);
- pg(outstr);
- sprintf(outstr,"u%c w%c\n",up_to_date_stats,wtformat); pg(outstr);
- pg("format breaks after: ");
- for (i=1;i<=10;i++) {sprintf(outstr,"%4d",format[i]); pg(outstr);};
- pg("\n ");
- for (i=11;i<=maxformat-1;i++)
- {sprintf(outstr,"%4d",format[i]); pg(outstr);};
- sprintf(outstr,"\nlast time weights were saved: %d\n",lastsave);
- pg(outstr);
- sprintf(outstr,"saving weights every %d iterations\n",saverate);
- pg(outstr);
- if (wtlimithit) pg(">>>>> WEIGHT LIMIT HIT <<<<<\n");
- pg("network size: ");
- p = start;
- while (p != NULL)
- {
- sprintf(outstr," %1d",p->unitcount);
- pg(outstr);
- p = p->next;
- };
- if (extraconnect) pg(" with extra connections");
- sprintf(outstr," (total: %1d weights)\n",wttotal); pg(outstr);
- if (toosmall != -1)
- {
- pg("removed non-bias weights with absolute ");
- sprintf(outstr,"value below %4.2f\n",unscale(toosmall)); pg(outstr);
- };
- #ifdef SYMMETRIC
- if (stdthresh != -32768)
- {
- sprintf(outstr,"thresholds frozen at %f\n", unscale(stdthresh));
- pg(outstr);
- };
- #endif
- sprintf(outstr,"%d patterns %5.2f%% right ",npats,pct_right);
- pg(outstr);
- sprintf(outstr,"(%d right, %d wrong) ",right,wrong); pg(outstr);
- sprintf(outstr,"%7.5f error/unit\n",errorperunit); pg(outstr);
- sprintf(outstr,"? = %f\n",unscale(qmark)); pg(outstr);
- sprintf(outstr,"benchmark parameters: g %d ",goal); pg(outstr);
- sprintf(outstr,"k %4.2f ",unscale(kicksize)); pg(outstr);
- sprintf(outstr,"m %d r %d ",maxtries,maxiter); pg(outstr);
- if (printrate != -1) {sprintf(outstr,"%d ",printrate); pg(outstr);};
- if (*testfile != emptystring)
- {sprintf(outstr,"t %s\n",testfile); pg(outstr);}
- else {sprintf(outstr,"t %d\n",testpat); pg(outstr);};
- pg("for help, type h followed by the letter of the command\n\n");
- break;
-
- case '!':
- i = 0;
- ch = readch();
- while (ch != '\n' && i <= 80)
- {
- string[i] = ch;
- ch = readch();
- i = i + 1;
- };
- bufferptr = bufferptr - 1;
- string[i] = '\0';
- system(string);
- break;
-
- case '*': break; /* * on a line is a comment */
-
- case 'A':
- while (ch != '\n' && ch != '*')
- {
- ch = readch();
- if (ch == 'a')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'p' || ch == 'l' || ch == 't') activation = ch;
- #ifndef INTEGER
- else if (ch == 's' || ch == 'T') activation = ch;
- #endif
- else texterror();
- }
- else if (ch == 'b')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == '+') backprop = 1;
- else if (ch == '-') backprop = 0;
- else texterror();
- }
- else if (ch == 'D')
- {
- temp = rdr(GT,0.0,'A');
- if (!readerror) D = temp;
- }
- else if (ch == 'd')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'd' || ch == 'f' || ch == 'o' || ch == 'F') deriv = ch;
- else texterror();
- }
- else if (ch == 'g')
- {
- itemp32 = readint(0,MAXINT,'f');
- if (!readerror) g = itemp32;
- }
- else if (ch == 's')
- {
- itemp = readint(0,32767,'A');
- if (!readerror) skiprate = itemp;
- }
- else if (ch == 't')
- {
- itemp = readint(0,npats,'A');
- if (!readerror) testpat = itemp;
- resetpats();
- for (i=1;i<=npats;i++)
- {
- nextpat();
- if (last->currentpat->bypass < 0) last->currentpat->bypass = 0;
- else if (i == testpat) last->currentpat->bypass = -1;
- };
- }
- else if (ch == 'u')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'j') ch = 'd';
- #ifdef SYMMETRIC
- if (ch == 'c' || ch == 'p') update = ch;
- #else
- if (ch == 'c' || ch == 'p' || ch == 'd') update = ch;
- #endif
- else texterror();
- }
- else if (ch == '*' || ch == '\n' || ch == ' ');
- else texterror();
- }
- bufferptr = bufferptr - 1;
- break;
-
- case 'a':
- temp = rdr(GE,0.0,'a');
- if (!readerror) alpha = temp;
- break;
-
- case 'B':
- dobenchmark = 0;
- while (ch != '\n' && ch != '*')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'g')
- {
- itemp2 = readint(0,MAXINT,'B');
- if (!readerror) goal = itemp2;
- }
- else if (ch == 'k')
- {
- temp = rdr(GT,0.0,'B');
- if (!readerror) kicksize = temp;
- }
- else if (ch == 'm')
- {
- itemp2 = readint(0,MAXINT,'B');
- if (!readerror) maxtries = itemp2;
- }
- else if (ch == 'r')
- {
- if (nonetwork() || nopatterns()) goto endB;
- maxiter = readint(1,MAXINT,'B');
- if (readerror) goto endB;
- do ch = readch(); while (ch == ' ');
- bufferptr = bufferptr - 1;
- if (ch >= '0' && ch <= '9')
- {
- printrate = readint(1,MAXINT,'B');
- if (readerror) goto endB;
- }
- else printrate = -1;
- dobenchmark = 1;
- }
- else if (ch == 't')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'f') testfile = readstr();
- else if (nonetwork() || nopatterns()) goto endB;
- else
- {
- bufferptr = bufferptr - 1;
- itemp = readint(0,npats,'B');
- if (readerror) goto endB;
- testpat = itemp;
- if (testpat == 0) testfile = &emptystring;
- };
- }
- else if (ch == ' ' || ch == '*' || ch == '\n');
- else texterror();
- };
- bufferptr = bufferptr - 1;
- if (dobenchmark)
- {
- if (testpat)
- {
- sprintf(outstr,"testing pattern %d\n",testpat);
- if (pg(outstr)) goto endB;
- };
- benchmark = 1;
- tries = 0;
- sumiter = 0;
- successes = 0;
- totalcpu = 0;
- s = seedstart->next;
- while (successes < goal && tries < maxtries)
- {
- if (s != NULL)
- {
- seed = s->val;
- srand(seed);
- s = s->next;
- };
- clear();
- kick(scale(0.0),kicksize);
- sprintf(outstr," seed = %6d; ",seed);
- pg(outstr);
- if (testpat)
- {
- resetpats();
- for (i=1;i<=testpat;i++) nextpat();
- last->currentpat->bypass = -1;
- };
- prevcputime = clock();
- if (run(maxiter,printrate)) goto endB;
- cputime = clock();
- tries = tries + 1;;
- if (unlearned == 0 || ((unlearned == 1) && testpat))
- {
- successes = successes + 1;
- sumiter = sumiter + totaliter;
- totalcpu = totalcpu + cputime - prevcputime;
- };
- if (testpat)
- {
- for (i=1;i<(testpat-1);i++) setonepat();
- last->currentpat->bypass = 0;
- }
- };
- sprintf(outstr,"%d failures; %d successes;",tries - successes,successes);
- pg(outstr);
- if (successes > 0)
- {
- averageiter = (REAL) sumiter / (REAL) successes;
- averagecpu = (REAL) totalcpu / (REAL) successes;
- sprintf(outstr," average = %f ",averageiter); pg(outstr);
- sprintf(outstr,"%12.6f sec/network",averagecpu / CLOCKS_PER_SEC);
- pg(outstr);
- };
- pg("\n");
- };
-
- endB: benchmark = 0;
- break;
-
- case 'b':
- itemp = 0;
- ch = readch();
- while (ch != '\n' && ch != '*')
- {
- bufferptr = bufferptr - 1;
- itemp2 = readint(format[itemp],last->unitcount,'b');
- if (readerror) goto endb;
- itemp = itemp + 1;
- if (itemp < maxformat) format[itemp] = itemp2;
- else pg("format too long\n");
- ch = readch();
- while (ch == ' ') ch = readch();
- if (ch >= '0' && ch <= '9') bufferptr = bufferptr - 1;
- };
- if (itemp < maxformat-1)
- for (i=itemp+1;i <= maxformat-1; i++) format[i] = format[i-1] + 10;
- bufferptr = bufferptr - 1;
-
- endb: break;
-
- case 'C':
- if (nonetwork()) break;
- clear();
- srand(seed);
- break;
-
- #ifndef SYMMETRIC
- case 'c':
- if (nonetwork()) break;
- layer1 = readint(1,nlayers,'c');
- if (readerror) break;
- node1 = readint(1,MAXINT,'c');
- if (readerror) break;
- layer2 = readint(1,nlayers,'c');
- if (readerror) break;
- node2 = readint(1,MAXINT,'c');
- if (readerror) break;
- if (layer1 >= layer2)
- {
- pg("backward connections in c command not implemented\n");
- break;
- };
- n1 = locateunit(layer1,node1);
- n2 = locateunit(layer2,node2);
- if (n1 != NULL && n2 != NULL)
- {
- connect(n1,n2,0);
- extraconnect = 1;
- }
- else
- {
- sprintf(outstr,"connection not made: %d %d %d %d\n", layer1, node1, layer2, node2);
- pg(outstr);
- };
- break;
- #endif
-
- case 'd':
- case 'j':
- while (ch != '\n' && ch != '*')
- {
- ch = readch();
- if (ch == 'd')
- {
- temp = rdr(GT,0.0,'d');
- if (!readerror) decay = temp;
- }
- else if (ch == 'e')
- {
- temp = rdr(GT,0.0,'d');
- if (!readerror && !nonetwork())
- {
- dbdeta = temp;
- p = start->next;
- while (p != NULL)
- {
- u = (UNIT *) p->units;
- while (u != NULL)
- {
- w = (WTNODE *) u->wtlist;
- while (w != NULL)
- {
- #ifdef SYMMETRIC
- *(w->eta) = dbdeta;
- #else
- w->eta = dbdeta;
- #endif
- w = w->next;
- }
- u = u->next;
- }
- p = p->next;
- }
- }
- }
- else if (ch == 'k')
- {
- temp = rdr(GT,0.0,'d');
- if (!readerror) kappa = temp;
- }
- else if (ch == 'm')
- {
- temp = rdr(GT,0.0,'d');
- if (!readerror) etamax = temp;
- }
- else if (ch == 'n')
- {
- temp = rdr(GE,0.0,'d');
- if (!readerror) noise = temp;
- }
- else if (ch == 't')
- {
- temp = rdr(GE,0.0,'d');
- if (!readerror)
- {
- theta1 = temp;
- theta2 = scale(1.0) - theta1;
- };
- }
- else if (ch == '*' || ch == '\n' || ch == ' ');
- else texterror();
- }
- bufferptr = bufferptr - 1;
- break;
-
- case 'e':
- temp = rdr(GT,0.0,'e');
- if (!readerror) eta = temp;
- do ch = readch(); while (ch == ' ');
- bufferptr = bufferptr - 1;
- if (ch != '\n' && ch != '*')
- {
- temp = rdr(GT,0.0,'r');
- if (!readerror) eta2 = temp;
- }
- else eta2 = eta;
- break;
-
- case 'f':
- while (ch != '\n' && ch != '*')
- {
- ch = readch();
- if (ch == 'b')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == '+' || ch == '-') ringbell = ch; else texterror();
- }
- else if (ch == 'c')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == '+')
- {
- copyflag = '+';
- copy = fopen("copy","w");
- if (copy == NULL)
- {sprintf(outstr,"cannot open file: copy\n"); pg(outstr); };
- }
- else if (ch == '-')
- {
- copyflag = '-';
- if (copy != NULL)
- {
- fflush(copy);
- fclose(copy);
- }
- }
- else texterror();
- }
- else if (ch == 'e')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == '+' || ch == '-') echo = ch;
- }
- else if (ch == 'i')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'c' || ch == 'r') informat = ch; else texterror();
- }
- else if (ch == 'o')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'a' || ch == 'c' || ch == 'r') outformat = ch;
- else texterror();
- }
- else if (ch == 'P')
- {
- itemp = readint(0,MAXINT,'f');
- if (!readerror) pagesize = itemp;
- }
- else if (ch == 'p')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'c' || ch == 'C' || ch == 'g' || ch == 'G') patform = ch;
- else texterror();
- }
- else if (ch == 's')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == '+' || ch == '-') summary = ch; else texterror();
- }
- else if (ch == 'u')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == '+' || ch == '-') up_to_date_stats = ch; else texterror();
- }
- else if (ch == 'w')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'r' || ch == 'R' || ch == 'b' || ch == 'B') wtformat = ch;
- else texterror();
- }
- else if (ch == ' ' || ch == '*' || ch == '\n');
- else texterror();
- }
- bufferptr = bufferptr - 1;
- break;
- #ifndef SYMMETRIC
-
- case 'H':
- if (nonetwork()) break;
- itemp = readint(2,nlayers,'H');
- if (readerror) break;
- temp = rdr(GE,0.0,'H');
- if (!readerror) addhiddenunit(itemp,temp);
- break;
- #endif
-
- case 'h': help(); break;
-
- case 'i':
- do ch = readch(); while (ch == ' ');
- if (ch != '\n')
- {
- bufferptr = bufferptr - 1;
- inputfile = readstr();
- }
- pushfile(inputfile);
- break;
-
- case 'k':
- if (nonetwork()) break;
- temp = rdr(GE,0.0,'k');
- if (readerror) break;
- temp2 = rdr(GT,0.0,'k');
- if (!readerror)
- {
- if (initialkick == -1 && temp == 0) initialkick = temp2;
- kick(temp,temp2);
- }
- break;
-
- case 'l':
- if (nonetwork()) break;
- layerno = readint(1,nlayers,'l');
- if (readerror) break;
- p = start;
- for (i=2;i<=layerno;i++) p = p->next;
- printoutunits(1,p,0);
- break;
-
- case 'm':
- nlayers = 0;
- wttotal = 0;
- ch = readch();
- p = NULL;
- while (ch != '\n' && ch != '*')
- {
- itemp = readint(1,MAXINT,'m');
- if (readerror)
- {
- wttotal = 0;
- goto endm;
- };
- nlayers = nlayers + 1;
- p = mklayer(p,itemp);
- if (nlayers == 1) start = p;
- ch = readch();
- while (ch == ' ') ch = readch();
- if (ch >= '0' && ch <= '9') bufferptr = bufferptr - 1;
- };
- last = p;
- p = start;
- p = p->next;
- hlayer = (UNIT *) p->units;
- p = p->next;
- if (p != NULL)
- {
- ilayer = (UNIT *) p->units;
- p = p->next;
- if (p != NULL)
- {
- jlayer = (UNIT *) p->units;
- p = p->next;
- if (p != NULL) klayer = (UNIT *) p->units;
- }
- };
- bufferptr = bufferptr - 1;
- nullpatterns();
- clear();
- endm: break;
-
- case 'n':
- if (nonetwork()) break;
- do ch = readch(); while (ch == ' ');
- if (ch == 'f')
- {
- trainfile = readstr();
- itemp = MAXINT;
- pushfile(trainfile);
- }
- else
- {
- bufferptr = bufferptr - 1;
- itemp = readint(1,MAXINT,'n');
- if (readerror) break;
- };
- nullpatterns();
- readingpattern = 1;
- npats = readpats(itemp,'n');
- if (itemp != MAXINT && npats < itemp)
- {
- sprintf(outstr,"\n>>>>> only %d patterns read <<<<<\n\n",npats);
- pg(outstr);
- };
- readingpattern = 0;
- wrong = npats;
- break;
-
- case 'O':
- if (nonetwork() || nopatterns()) break;
- itemp = readint(1,npats,'O');
- if (readerror) break;
- resetpats();
- for (i=1;i<=itemp;i++) nextpat();
- setoutputpat();
- u = (UNIT *) last->units;
- itemp2 = 0; /* unit counter */
- i = 1; /* format counter */
- while (u != NULL)
- {
- if (outformat == 'c')
- if (unscale(u->tj) == 1) pg("1"); else pg("0");
- else {sprintf(outstr,"%5.2f",unscale(u->tj)); pg(outstr);};
- itemp2 = itemp2 + 1;
- if (format[i] == itemp2)
- {
- if (outformat == 'r') pg("\n"); else pg(" ");
- if (i < maxformat - 1) i = i + 1;
- };
- u = u->next;
- }
- pg("\n");
- break;
-
- case 'o':
- do ch = readch(); while (ch == ' ' || ch == '\n');
- if (ch == 'r' || ch == 'a' || ch == 'c') outformat = ch;
- else printf("incorrect output format: %c\n",ch);
- break;
-
- case 'P':
- if (nonetwork() || nopatterns()) break;
- do ch = readch(); while (ch == ' ');
- bufferptr = bufferptr - 1;
- if (ch == '\n' || ch == '*') patcheck(1,npats,1,1,1,1,0);
- else
- {
- itemp = readint(0,npats,'P');
- if (readerror) break;
- if (itemp == 0) patcheck(1,npats,0,0,1,1,0);
- else patcheck(itemp,itemp,1,1,0,0,0);
- };
- break;
-
- case 'p':
- if (nonetwork()) break;
- loadpat('p');
- printoutunits(1,last,0);
- break;
-
- case 'Q':
- temp = rdr(GT,(REAL) KCODE,'Q');
- if (!readerror) qmark = temp;
- break;
-
- case 'q': return;
-
- case 'R': if (nonetwork()) break; else restoreweights(); break;
-
- case 'r': /* r for run, rw for restore weights */
- do ch = readch(); while (ch == ' ');
- if (ch == 'w')
- {
- do ch = readch(); while (ch == ' ');
- bufferptr = bufferptr - 1;
- if (ch == '*' || ch == '\n') /* nothing */ ; else wtfile = readstr();
- if (nonetwork()) break; else restoreweights();
- }
- else
- {
- if (nonetwork() || nopatterns()) break;
- bufferptr = bufferptr - 1;
- itemp = readint(1,MAXINT,'r');
- if (!readerror) iter = itemp; else break;
- do ch = readch(); while (ch == ' ');
- bufferptr = bufferptr - 1;
- if (ch != '\n' && ch != '*')
- {
- itemp = readint(1,MAXINT,'r');
- if (readerror != 1) run(iter,itemp);
- }
- else run(iter,-1);
- };
- break;
-
- case 'S':
- do ch = readch(); while (ch == ' ');
- bufferptr = bufferptr - 1;
- if (ch == '\n' || ch == '*') itemp = 0;
- else
- {
- itemp = readint(0,MAXINT,'S');
- if (readerror) break;
- };
- if (itemp == 0) if (nonetwork()) break; else saveweights();
- else saverate = itemp;
- break;
-
- case 's': /* s <int> for seed, sw <filename> for save weights */
- do ch = readch(); while (ch == ' ');
- if (ch == 'w')
- {
- do ch = readch(); while (ch == ' ');
- bufferptr = bufferptr - 1;
- if (ch == '*' || ch == '\n') /* nothing */ ; else wtfile = readstr();
- if (nonetwork()) break; else saveweights();
- }
- else
- {
- bufferptr = bufferptr - 1;
- sprev = seedstart;
- while (ch != '\n' && ch != '*')
- {
- seed = readint(0,MAXINT,'s');
- if (readerror) goto ends;
- s = (SEEDNODE *) malloc(sizeof(SEEDNODE));
- s->val = seed;
- s->next = NULL;
- sprev->next = s;
- sprev = s;
- do ch = readch(); while(ch == ' ');
- if (ch >= '0' && ch <= '9') bufferptr = bufferptr - 1;
- };
- ends: seed = seedstart->next->val;
- srand(seed);
- }
- bufferptr = bufferptr - 1;
- break;
- #ifdef SYMMETRIC
-
- case 'T':
- if (nonetwork()) break;
- stdthresh = rdr(GT,-unscale(32767),'T');
- if (readerror) break;
- u = (UNIT *) last->units;
- while (u != NULL)
- {
- w = (WTNODE *) u->wtlist;
- while (w->next != NULL) w = w->next;
- *(w->weight) = stdthresh;
- u = u->next;
- };
- break;
- #endif
-
- case 't':
- do ch = readch(); while (ch == ' ');
- if (ch == '\n' && (!nonetwork())) testcheck();
- else if (ch == 'f')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == '\n' && (!nonetwork())) testcheck();
- else
- {
- bufferptr = bufferptr - 1;
- testfile = readstr();
- if (!nonetwork()) testcheck();
- };
- }
- else
- {
- bufferptr = bufferptr - 1;
- temp = rdr(GT,0.0,'t');
- if (readerror) break;
- else if (temp < scale(1.0)) toler = temp;
- else printf("tolerance value out of range\n");
- };
- break;
- #ifndef SYMMETRIC
-
- case 'W':
- if (nonetwork()) break;
- temp = rdr(GT,0.0,'W');
- if (!readerror)
- {
- toosmall = temp;
- whittle(temp);
- printf("total weights now: %1d\n",wttotal);
- };
- break;
- #endif
-
- case 'w':
- if (nonetwork()) break;
- layerno = readint(2,nlayers,'w');
- if (readerror) break;
- unitno = readint(1,MAXINT,'w');
- if (readerror) break;
- u = locateunit(layerno,unitno);
- if (u != NULL) printweights(u);
- break;
-
- case 'x':
- if (nonetwork()) break;
- do ch = readch(); while (ch == ' ');
- if (ch == 'f')
- {
- trainfile = readstr();
- itemp = MAXINT;
- pushfile(trainfile);
- }
- else
- {
- bufferptr = bufferptr - 1;
- itemp = readint(1,MAXINT,'n');
- if (readerror) break;
- };
- prevnpats = npats;
- findendofpats(start);
- findendofpats(last);
- readingpattern = 1;
- itemp2 = readpats(itemp,'x');
- if (itemp != MAXINT && npats < itemp2)
- printf("\n>>>>> only %d patterns read <<<<<\n\n",npats);
- readingpattern = 0;
- npats = npats + itemp2;
- wrong = wrong + itemp2;
- break;
-
- /*
- case 'z': tracer();
- break;
- */
-
- default: texterror();
- break;
- };
- do ch = readch(); while (ch != '\n');
- }while (!finished);
- }
-
- void main(argc,argv)
- int argc;
- char *argv[];
- {
- FILE *tempfile;
- setbuf(stdout,NULL); /* set unbuffered output */
- printf("Fast Backpropagation Copyright (c) 1990, 1991, 1992 by Donald R. Tveter\n");
- filestackptr = 0;
- filestack[0] = stdin;
- data = stdin;
- emptystring = '\0';
- if (argc == 1)
- {
- printf("no data file, stdin assumed\n");
- datafilename = &emptystring;
- testfile = &emptystring;
- }
- else
- {
- datafilename = argv[1];
- pushfile(datafilename);
- if (argc == 3)
- {
- tempfile = fopen(argv[2],"r");
- if (tempfile == NULL)
- {
- printf("there is no file: %s\n",argv[2]);
- testfile = &emptystring;
- }
- else
- {
- testfile = argv[2];
- fclose(tempfile);
- }
- }
- else testfile = &emptystring;
- };
- init();
- signal(SIGINT,restartcmdloop); /* restart from interrrupt */
- cmdloop();
- if (copy != NULL)
- {
- fflush(copy);
- fclose(copy);
- }
- }
-