home *** CD-ROM | disk | FTP | other *** search
- /* ************************************************** */
- /* file bp.c: contains the main program and network */
- /* creation routines. */
- /* */
- /* Copyright (c) 1990 by Donald R. Tveter */
- /* */
- /* ************************************************** */
-
- #include <stdio.h>
- #include <malloc.h>
- #include <signal.h>
- #include <setjmp.h>
- #define SIGINT 2
- #define MAXINT 2147483647
-
- #ifdef INTEGER
- #include "ibp.h"
- #else
- #include "rbp.h"
- #endif
-
- extern int rand(); /* built-in C function */
- extern int srand(); /* built-in C function */
-
- extern void forward(); /* from int.c or real.c */
-
- #ifdef INTEGER
- extern int scale(); /* from io.c */
- extern double unscale(); /* from io.c */
- #endif
-
- extern int copyhidden(); /* from misc.c */
- extern void findendofpats(); /* from misc.c */
- extern void help(); /* from io.c */
- extern void kick(); /* from misc.c */
- extern void nullpatterns(); /* from misc.c */
- extern void printoutunits(); /* from misc.c */
- extern void printpats(); /* from misc.c */
- extern void printweights(); /* from io.c */
- extern void run(); /* from misc.c */
- extern WTTYPE rdr(); /* from io.c */
- extern int readch(); /* from io.c */
- extern double readchar(); /* from io.c */
- extern int readint(); /* from io.c */
- extern void restoreweights();/* from io.c */
- extern void saveweights(); /* from io.c */
- extern void texterror(); /* from io.c */
- extern void whittle(); /* from misc.c */
-
- /* 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 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 */
- char cmdfilename[50]; /* name of file to take extra commands from */
- jmp_buf cmdloopstate; /* to save state in case of a SIGINT */
- WTTYPE D; /* sigmoid sharpness */
- FILE *data; /* file for original data */
- char datafilename[50];/* 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 */
- int echo; /* controls echoing of characters during input */
- WTTYPE eta; /* basic learning rate */
- WTTYPE eta2; /* DSZ learning rate for inner layers */
- WTTYPE etamax; /* the maximum eta for the DBD method */
- int extraconnect; /* flags the use of connections between */
- /* non-adjacent layers */
- int format[maxformat];/* each value in format indicates where to put */
- /* a blank for compressed output mode or a */
- /* carriage return for real output */
- 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 */
- 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 */
- LAYER *last; /* has address of the output layer */
- int lastprint; /* last iteration pattern responses printed */
- int lastsave; /* last time weights were saved */
- short nlayers; /* number of layers in network */
- int npats; /* number of patterns currently in use */
- char outformat; /* controls format to print output */
- int prevnpats; /* previous number of patterns, initially 0 */
- WTTYPE qmark; /* value for ? in compressed input */
- int readerror; /* flags an error in reading a value */
- int readingpattern; /* flags reading pattern state */
- int saverate; /* rate at which to save weights */
- unsigned seed; /* seed for generating random weights */
- short skiprate; /* number of times to bypass a learned pattern */
- LAYER *start; /* has address of the input layer */
- char summary; /* flags summary output mode */
- 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
- int totaldiff; /* totals errors to find average error per unit */
- #else
- double totaldiff;
- #endif
- int totaliter; /* counts total iterations for the program */
- int unlearnedpats; /* number unlearned in last learning cycle */
- char update; /* flags type of update rule to use */
- char wtformat; /* controls format to save and restore weights */
- WTTYPE wtlimit; /* adjustable limit on 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
-
- UNIT *locateunit(layerno,unitno) /* given a layer number and unit */
- int layerno, unitno; /* number this routine returns the */
- {int i; /* address of the unit */
- UNIT *u;
- LAYER *layer;
-
- if (layerno >= 1 && layerno <= nlayers)
- {
- 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);
- }
- else
- {
- printf("there is no layer %3d\n",layerno);
- return(NULL);
- };
- return(u);
- }
-
- #ifdef SYMMETRIC
-
- int wtaddress(i,j,biasunit,type,size) /* Returns the address of a */
- int i,j; /* weight (1), olddw (2), */
- int biasunit; /* eta (3) or total (4). */
- int type; /* One is created if it */
- int size; /* doesn't already exist. */
-
- { int k, addr;
- UNIT *u;
- WTNODE *w;
-
- if (biasunit == 1) addr = (int) malloc(size);
- else if (j >= i) addr = (int) 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 = (int) w->weight;
- else if (type == 2) addr = (int) w->olddw;
- else if (type == 3) addr = (int) w->eta;
- else addr = (int) w->total;
- };
- return(addr);
- }
-
- void setweight(w,i,j,biasunit) /* set initial values in w */
- WTNODE *w;
- int 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 = (int *) wtaddress(i,j,biasunit,4,sizeof(int));
- #else
- w->total = (double *) wtaddress(i,j,biasunit,4,WTSIZE);
- #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->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;
- (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->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) /* reads the patterns for layer */
- LAYER *layer;
- int command;
-
- {PATNODE *p, *prevp;
- PATLIST *pl;
- int i;
-
- 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;
-
- prevp = NULL; /* read in each number */
- for (i=1;i<=layer->unitcount;i++)
- {
- p = (PATNODE *) malloc(sizeof(PATNODE));
- if (informat == 'r') p->val = rdr(GE,(double) HCODE,command);
- else p->val = scale(readchar());
- if (readerror == 1)
- {
- printf("pattern not read\n");
- return;
- };
- p->next = NULL;
- if (prevp == NULL) pl->pats = p; else prevp->next = p;
- prevp = p;
- };
- }
-
- void readpats(new,command) /* reads the input and output patterns */
- int new;
- int command;
- { int i;
- PATLIST *pl;
-
- for (i=prevnpats + 1;i<=npats;i++)
- {
- readpatson(start,command);
- if (readerror == 1) goto failure;
- readpatson(last,command);
- if (readerror == 1) goto failure;
- };
- return;
- failure:
- if (data != stdin)
- {
- printf("error while reading pattern %d\n",i);
- exit(5);
- };
- if (new == 0)
- {
- resetpats();
- for (i=1;i<prevnpats;i++) setonepat();
- pl = (PATLIST *) start->currentpat;
- pl->next = NULL;
- pl = (PATLIST *) last->currentpat;
- pl->next = NULL;
- };
- printf("no patterns added\n");
- printf("%d patterns in use\n",prevnpats);
- npats = prevnpats;
- }
-
- void init() /* initializes almost everything */
- {int i;
-
- activation = 'p'; /* piece-wise activation function */
- alpha = scale(0.5);
- backprop = 1; /* always back-propagate errors */
- bufferend = 0;
- bufferptr = buffsize + 1;
- ch = ' ';
- D = scale(1.0);
- dbdeta = scale(0.5);
- decay = scale(0.5);
- deriv = 'f'; /* use Fahlman's derivative */
- eta = scale(0.5);
- eta2 = scale(0.05);
- etamax = scale(30.0);
- extraconnect = 0;
- format[0] = 0; /* set default places for breaks in output patterns */
- for(i=1;i<=maxformat-1;i++) format[i] = format[i-1] + 10;
- informat = 'c'; /* input format is compressed */
- initialkick = -1; /* weights have not been kicked yet */
- kappa = scale(0.5);
- lastprint = 0;
- lastsave = 0;
- outformat = 'r'; /* output format is real */
- skiprate = 0;
- prevnpats = 0;
- qmark = scale(0.5);
- saverate = 100000; /* effectively, never save weights */
- seed = 0;
- #ifdef SYMMETRIC
- stdthresh = -32768; /* indicates no threshold set */
- #endif
- summary = '-'; /* don't summarize learning */
- theta1 = scale(0.5);
- theta2 = scale(1.0) - theta1;
- toler = scale(0.1);
- toosmall = -1; /* indicates no weights whittled away */
- totaliter = 0;
- update = 'o'; /* update formulas are the original */
- wtformat = 'r'; /* save weights in real format */
- wtlimit = scale(0.0); /* no limit on weights */
- wtlimithit = 0; /* weight limit not yet hit */
- wttotal = 0;
- }
-
- void restartcmdloop() /* for a SIGINT, restart in cmdloop */
- {
- if (data != stdin) ch = EOF;
- 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;
- WTTYPE temp, temp2;
- UNIT *u, *n1, *n2, *hunit, *iunit, *junit, *kunit;
- LAYER *p;
- char string[81];
- WTNODE *w;
-
- setjmp(cmdloopstate); /* position to recover from SIGINT */
- finished = 0; /* loop until finished == 1 */
- do{
- restart:
- #ifdef SYMMETRIC
- if (data == stdin) printf("[?!*AabCEefHhijklmnoPpQqRrSsTtWwx]? ");
- #else
- if (data == stdin) printf("[?!*AabCcEefHhijklmnoPpQqRrSstWwx]? ");
- #endif
- while(ch == ' ' || ch == '\n') ch = readch();
- switch (ch) {
- case EOF: if (data == stdin) exit(6); else data = stdin;
- printf("taking commands from stdin now\n");
- bufferend = 0; /* force a read from stdin */
- bufferptr = buffsize + 1; /* when readch is called */
- ch = ' ';
- goto restart;
- case '?': printf("\n%d iterations, s %1d ",totaliter,seed);
- printf("k 0 %5.3lf, ",unscale(initialkick));
- printf("file = %s\n",datafilename);
- printf("Algorithm: a%c",activation);
- if (backprop) printf(" b+"); else printf(" b-");
- printf(" D%5.2lf d%c ",unscale(D),deriv);
- printf("l%6.2lf s%1d u%c\n",unscale(wtlimit),skiprate,update);
- printf("e %7.5lf %7.5lf",unscale(eta),unscale(eta2));
- printf(" --- a %7.5lf\n",unscale(alpha));
- printf("j d %8.5lf e %8.5lf",unscale(decay),unscale(dbdeta));
- printf(" k %8.5lf m %8.5lf",unscale(kappa),unscale(etamax));
- printf(" t %8.5lf\n",unscale(theta1));
- printf("tolerance = %4.2lf\n",unscale(toler));
- printf("f i%c o%c",informat,outformat);
- printf(" s%c w%c\n",summary,wtformat);
- printf("format breaks after: ");
- for (i=1;i<=10;i++) printf("%4d",format[i]);
- printf("\n ");
- for (i=11;i<=maxformat-1;i++) printf("%4d",format[i]);
- printf("\nlast time weights were saved: %d\n",lastsave);
- printf("saving weights every %d iterations\n",saverate);
- if (wtlimithit) printf(">>>>> WEIGHT LIMIT HIT <<<<<\n");
- printf("network size: ");
- p = start;
- while (p != NULL)
- {
- printf(" %1d",p->unitcount);
- p = p->next;
- };
- if (extraconnect == 1) printf(" with extra connections");
- printf(" (total: %1d weights)\n",wttotal);
- if (toosmall != -1)
- {
- printf("removed non-bias weights with absolute ");
- printf("value below %4.2lf\n",unscale(toosmall));
- };
- #ifdef SYMMETRIC
- if (stdthresh != -32768)
- printf("thresholds frozen at %lf\n", unscale(stdthresh));
- #endif
- printf("%d patterns ",npats);
- printf("%d learned ",npats-unlearnedpats);
- printf("%d unlearned on last pass\n",unlearnedpats);
- printf("? = %lf\n",unscale(qmark));
- printf("for help, type h followed by");
- printf(" 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; /* ungetc(ch,data); */
- 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') activation = 'p';
- #ifndef INTEGER
- else if (ch == 's') activation = 's';
- #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 == 0) D = temp;
- }
- else if (ch == 'd')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'd' || ch == 'f' || ch == 'o') deriv = ch;
- else texterror();
- }
- else if (ch == 'l')
- {
- temp = rdr(GE,0.0,'A');
- if (readerror == 0)
- {
- wtlimit = temp;
- if (wtlimit == 0) wtlimithit = 0;
- };
- }
- else if (ch == 's')
- {
- itemp = readint(0,32767,'s');
- if (readerror == 0) skiprate = itemp;
- }
- else if (ch == 'u')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == 'c' || ch == 'C' || ch == 'd' ||
- ch == 'j' || ch == 'o') update = ch;
- else texterror();
- }
- else if (ch == '*' || ch == '\n' || ch == ' ');
- else texterror();
- }
- bufferptr = bufferptr - 1;
- break;
- case 'a': temp = rdr(GE,0.0,'a');
- if (readerror == 0) alpha = temp;
- break;
- case 'b': itemp = 0;
- ch = readch();
- while (ch != '\n' && ch != '*')
- {
- bufferptr = bufferptr - 1;
- itemp2 = readint(format[itemp],MAXINT,'b');
- if (readerror == 1) goto endb;
- itemp = itemp + 1;
- if (itemp < maxformat) format[itemp] = itemp2;
- else printf("format too long\n");
- ch = readch();
- while (ch == ' ') ch = readch();
- /* if its the start of a number, back up */
- if (ch != '\n') 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 (toosmall != -1)
- {
- printf("cannot restart with the weights removed\n");
- break;
- };
- wtlimithit = 0;
- totaliter = 0;
- lastsave = 0;
- initialkick = -1;
- lastprint = 0;
- seed = 0;
- p = start->next;
- while (p != NULL)
- {
- u = (UNIT *) p->units;
- while (u != NULL)
- {
- w = (WTNODE *) u->wtlist;
- while (w != NULL)
- {
- #ifdef SYMMETRIC
- if (w->next != NULL)
- { /* skip threshold weight */
- *(w->weight) = 0;
- *(w->olddw) = 0;
- *(w->eta) = dbdeta;
- };
- #else
- w->weight = 0;
- w->olddw = 0;
- w->eta = dbdeta;
- #endif
- w = w->next;
- };
- u = u->next;
- };
- p = p->next;
- };
- break;
- #ifndef SYMMETRIC
- case 'c': layer1 = readint(1,nlayers,'c');
- if (readerror == 1) break;
- node1 = readint(1,MAXINT,'c');
- if (readerror == 1) break;
- layer2 = readint(1,nlayers,'c');
- if (readerror == 1) break;
- node2 = readint(1,MAXINT,'c');
- if (readerror == 1) break;
- if (layer1 >= layer2)
- {
- printf("backward connections in c command not");
- printf(" implemented\n");
- break;
- };
- n1 = locateunit(layer1,node1);
- n2 = locateunit(layer2,node2);
- if (n1 != NULL && n2 != NULL)
- {
- connect(n1,n2,0);
- extraconnect = 1;
- }
- else printf("connection not made: %d %d %d %d\n",
- layer1, node1, layer2, node2);
- break;
- #endif
-
- case 'E': itemp = readint(0,1,'E');
- if (readerror == 1) break;
- else echo = itemp;
- break;
- case 'e': temp = rdr(GT,0.0,'e');
- if (readerror == 0) eta = temp;
- while (ch == ' ') ch = readch();
- if (ch != '\n' && ch != '*')
- {
- bufferptr = bufferptr - 1;
- temp = rdr(GT,0.0,'r');
- if (readerror != 1) eta2 = temp;
- }
- else eta2 = eta / 10;
- bufferptr = bufferptr - 1;
- break;
- case 'f': while (ch != '\n' && ch != '*')
- {
- ch = readch();
- 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 == 's')
- {
- do ch = readch(); while (ch == ' ');
- if (ch == '+' || summary == '-') summary = 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': itemp = readint(2,nlayers,'H');
- if (readerror == 1) break;
- temp = rdr(GE,0.0,'H');
- if (readerror == 0) addhiddenunit(itemp,temp);
- break;
- #endif
- case 'h': help();
- break;
- case 'i': ch = readch();
- while(ch == ' ') ch = readch();
- itemp = 0;
- while(ch != ' ' && ch != '\n' && itemp < 49)
- {
- cmdfilename[itemp] = ch;
- itemp = itemp + 1;
- ch = readch();
- };
- cmdfilename[itemp] = '\0';
- if ((data = fopen(cmdfilename,"r")) == (FILE *) NULL)
- {
- printf("cannot open: %s\n",cmdfilename);
- data = stdin;
- printf("taking commands from stdin now\n");
- }
- bufferend = 0;
- bufferptr = buffsize + 1;
- ch = ' ';
- goto restart;
- case 'j': while (ch != '\n' && ch != '*')
- {
- ch = readch();
- if (ch == 'd')
- {
- temp = rdr(GT,0.0,'j');
- if (readerror == 0) decay = temp;
- }
- else if (ch == 'e')
- {
- temp = rdr(GT,0.0,'d');
- if (readerror == 0)
- {
- 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,'j');
- if (readerror == 0) kappa = temp;
- }
- else if (ch == 'm')
- {
- temp = rdr(GT,0.0,'j');
- if (readerror == 0) etamax = temp;
- }
- else if (ch == 't')
- {
- temp = rdr(GE,0.0,'j');
- if (readerror == 0)
- {
- theta1 = temp;
- theta2 = scale(1.0) - theta1;
- };
- }
- else if (ch == '*' || ch == '\n' || ch == ' ');
- else texterror();
- }
- bufferptr = bufferptr - 1;
- break;
- case 'k': temp = rdr(GE,0.0,'k');
- if (readerror == 1) break;
- temp2 = rdr(GT,0.0,'k');
- if (readerror == 0)
- {
- if (initialkick == -1 && temp == 0) initialkick = temp2;
- kick(temp,temp2);
- }
- break;
- case 'l': layerno = readint(1,nlayers,'l');
- if (readerror == 1) break;
- p = start;
- for (i=2;i<=layerno;i++) p = p->next;
- printoutunits(p,0);
- break;
- case 'm': nlayers = 0;
- ch = readch();
- p = NULL;
- while (ch != '\n' && ch != '*')
- {
- itemp = readint(1,MAXINT,'m');
- if (readerror == 1) goto endm;
- nlayers = nlayers + 1;
- p = mklayer(p,itemp);
- if (nlayers == 1) start = p;
- ch = readch();
- while (ch == ' ') ch = readch();
- /* if its the start of a number, back up */
- if (ch != '\n') 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();
- endm: break;
- case 'n': if (start == NULL)
- {
- printf("the network must be defined first\n");
- break;
- };
- itemp = readint(1,MAXINT,'n');
- if (readerror == 1) break;
- nullpatterns();
- npats = itemp;
- readingpattern = 1;
- readpats(1,'n');
- readingpattern = 0;
- unlearnedpats = npats;
- 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': do ch = readch(); while (ch == ' ');
- bufferptr = bufferptr - 1;
- if (ch == '\n' || ch == '*') itemp = 0;
- else
- {
- itemp = readint(0,npats,'P');
- if (readerror == 1) break;
- };
- if (itemp == 0) printpats(1,npats,0,1,0);
- else printpats(itemp,itemp,0,1,0);
- break;
- case 'p': u = (UNIT *) start->units;
- readingpattern = 1;
- hunit = hlayer;
- iunit = ilayer;
- junit = jlayer;
- kunit = klayer;
- while (u != NULL)
- {
- if (informat == 'r') u->oj = rdr(GE,(double) HCODE,'p');
- else u->oj = scale(readchar());
- if (readerror == 1) goto endp;
- if (u->oj <= KCODE) /* do hidden unit codes */
- {
- if (u->oj == HCODE)
- {if (copyhidden(u,&hunit,2) == 1) goto endp;}
- else if (u->oj == ICODE)
- {if (copyhidden(u,&iunit,3) == 1) goto endp;}
- else if (u->oj == JCODE)
- {if (copyhidden(u,&junit,4) == 1) goto endp;}
- else if (copyhidden(u,&kunit,5) == 1) goto endp;
- };
- u = u->next;
- };
- forward();
- printoutunits(last,0);
- endp: readingpattern = 0;
- break;
- case 'Q': temp = rdr(GT,(double) KCODE,'Q');
- if (readerror == 0) qmark = temp;
- break;
- case 'q': finished = 1;
- break;
- case 'R': restoreweights();
- break;
- case 'r': if (start == NULL)
- {
- printf("the network must be defined first\n");
- break;
- };
- iter = readint(1,MAXINT,'r');
- if (readerror == 1) break;
- while (ch == ' ') ch = readch();
- if (ch != '\n' && ch != '*')
- {
- bufferptr = bufferptr - 1;
- itemp = readint(1,MAXINT,'r');
- if (readerror != 1) run(iter,itemp);
- }
- else run(iter,-1);
- bufferptr = bufferptr - 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 == 1) break;
- };
- if (itemp == 0) saveweights();
- else saverate = itemp;
- break;
- case 's': seed = readint(0,MAXINT,'s');
- srand(seed);
- break;
- #ifdef SYMMETRIC
- case 'T': stdthresh = rdr(GT,-unscale(32767),'T');
- if (readerror == 1) 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': temp = rdr(GT,0.0,'t');
- if (readerror == 1) break;
- else if (temp < scale(1.0)) toler = temp;
- else printf("tolerance value out of range\n");
- break;
- #ifndef SYMMETRIC
- case 'W': temp = rdr(GT,0.0,'W');
- if (readerror == 0)
- {
- toosmall = temp;
- whittle(temp);
- printf("total weights now: %1d\n",wttotal);
- };
- break;
- #endif
- case 'w': layerno = readint(2,nlayers,'w');
- if (readerror == 1) break;
- unitno = readint(1,MAXINT,'w');
- if (readerror == 1) break;
- u = locateunit(layerno,unitno);
- if (u != NULL) printweights(u);
- break;
- case 'x': if (start == NULL)
- {
- printf("the network must be defined first\n");
- break;
- };
- itemp = readint(1,MAXINT,'x');
- if (readerror == 1) break;
- prevnpats = npats;
- npats = npats + itemp;
- findendofpats(start);
- findendofpats(last);
- readingpattern = 1;
- readpats(0,'x');
- readingpattern = 0;
- unlearnedpats = npats;
- break;
- default : texterror();
- break;
- };
- ch = readch();
- while(ch != '\n') ch = readch();
- }while (finished == 0);
- }
-
- void main(argc,argv)
- int argc;
- char *argv[];
- {
- char *fnamestr, *i;
-
- printf("Fast Backpropagation Copyright (c) 1990 by Donald R. Tveter\n");
-
- setbuf(stdout,NULL); /* set unbuffered output */
- if (argc == 1) /* check for file argument, if any */
- {
- printf("missing data file name, stdin assumed\n");
- data = stdin;
- *datafilename = '\0';
- }
- else
- if ((data = fopen(argv[1],"r")) == (FILE *) NULL)
- {
- printf("cannot open: %s\n",argv[1]);
- exit(1);
- }
- else /* make a copy of the file name in a global variable */
- {
- fnamestr = argv[1];
- i = datafilename;
- while(*fnamestr != '\0') *i++ = *fnamestr++;
- };
- init();
- signal(SIGINT,restartcmdloop); /* restart from interrrupt */
- cmdloop();
- }
-