v14i085: Fast Backpropagation Part 2 of 4
Donald Tveter
drt at chinet.chi.il.us
Sun Sep 16 10:58:09 AEST 1990
Posting-number: Volume 14, Issue 85
Submitted-by: Donald Tveter <drt at chinet.chi.il.us>
Archive-name: back-prop/part02
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 2 (of 4)."
# Contents: bp.c
# Wrapped by drt at chinet on Fri Aug 31 08:17:40 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'bp.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'bp.c'\"
else
echo shar: Extracting \"'bp.c'\" \(36100 characters\)
sed "s/^X//" >'bp.c' <<'END_OF_FILE'
X/* ************************************************** */
X/* file bp.c: contains the main program and network */
X/* creation routines. */
X/* */
X/* Copyright (c) 1990 by Donald R. Tveter */
X/* */
X/* ************************************************** */
X
X#include <stdio.h>
X#include <malloc.h>
X#include <signal.h>
X#include <setjmp.h>
X#define SIGINT 2
X#define MAXINT 2147483647
X
X#ifdef INTEGER
X#include "ibp.h"
X#else
X#include "rbp.h"
X#endif
X
Xextern int rand(); /* built-in C function */
Xextern int srand(); /* built-in C function */
X
Xextern void forward(); /* from int.c or real.c */
X
X#ifdef INTEGER
Xextern int scale(); /* from io.c */
Xextern double unscale(); /* from io.c */
X#endif
X
Xextern int copyhidden(); /* from misc.c */
Xextern void findendofpats(); /* from misc.c */
Xextern void help(); /* from io.c */
Xextern void kick(); /* from misc.c */
Xextern void nullpatterns(); /* from misc.c */
Xextern void printoutunits(); /* from misc.c */
Xextern void printpats(); /* from misc.c */
Xextern void printweights(); /* from io.c */
Xextern void run(); /* from misc.c */
Xextern WTTYPE rdr(); /* from io.c */
Xextern int readch(); /* from io.c */
Xextern double readchar(); /* from io.c */
Xextern int readint(); /* from io.c */
Xextern void restoreweights();/* from io.c */
Xextern void saveweights(); /* from io.c */
Xextern void texterror(); /* from io.c */
Xextern void whittle(); /* from misc.c */
X
X/* global variables used in all versions */
X
Xchar activation; /* activation function, p or s */
XWTTYPE alpha; /* momentum term */
Xchar backprop; /* flags whether to back propagate error for */
X /* units close to their targets */
Xint bufferend; /* index of last character in input line */
Xint bufferptr; /* position of next character in buffer */
Xchar buffer[buffsize];/* holds contents of one input line */
Xint ch; /* general purpose character variable */
Xchar cmdfilename[50]; /* name of file to take extra commands from */
Xjmp_buf cmdloopstate; /* to save state in case of a SIGINT */
XWTTYPE D; /* sigmoid sharpness */
XFILE *data; /* file for original data */
Xchar datafilename[50];/* copy of the data file name saved here */
XWTTYPE dbdeta; /* the initial eta value for the DBD method */
XWTTYPE decay; /* the decay parameter for the DBD method */
Xchar deriv; /* flags type of derivative to use */
Xint echo; /* controls echoing of characters during input */
XWTTYPE eta; /* basic learning rate */
XWTTYPE eta2; /* DSZ learning rate for inner layers */
XWTTYPE etamax; /* the maximum eta for the DBD method */
Xint extraconnect; /* flags the use of connections between */
X /* non-adjacent layers */
Xint format[maxformat];/* each value in format indicates where to put */
X /* a blank for compressed output mode or a */
X /* carriage return for real output */
XUNIT *hlayer; /* pointer to list of units in second layer */
XUNIT *ilayer; /* pointer to list of units in third layer */
Xchar informat; /* controls format to read numbers */
XWTTYPE initialkick; /* the range weights are initialized to */
Xint iter; /* for counting iterations in one run */
XUNIT *jlayer; /* pointer to list of units in fourth layer */
XWTTYPE kappa; /* the DBD learning parameter */
XUNIT *klayer; /* pointer to list of units in fifth layer */
XLAYER *last; /* has address of the output layer */
Xint lastprint; /* last iteration pattern responses printed */
Xint lastsave; /* last time weights were saved */
Xshort nlayers; /* number of layers in network */
Xint npats; /* number of patterns currently in use */
Xchar outformat; /* controls format to print output */
Xint prevnpats; /* previous number of patterns, initially 0 */
XWTTYPE qmark; /* value for ? in compressed input */
Xint readerror; /* flags an error in reading a value */
Xint readingpattern; /* flags reading pattern state */
Xint saverate; /* rate at which to save weights */
Xunsigned seed; /* seed for generating random weights */
Xshort skiprate; /* number of times to bypass a learned pattern */
XLAYER *start; /* has address of the input layer */
Xchar summary; /* flags summary output mode */
XWTTYPE theta1; /* the DBD parameter */
XWTTYPE theta2; /* 1 - theta1 */
XWTTYPE toler; /* value used in testing for completion */
XWTTYPE toosmall; /* weights smaller than toosmall were removed */
X#ifdef INTEGER
Xint totaldiff; /* totals errors to find average error per unit */
X#else
Xdouble totaldiff;
X#endif
Xint totaliter; /* counts total iterations for the program */
Xint unlearnedpats; /* number unlearned in last learning cycle */
Xchar update; /* flags type of update rule to use */
Xchar wtformat; /* controls format to save and restore weights */
XWTTYPE wtlimit; /* adjustable limit on weights */
Xchar wtlimithit; /* flags whether the limit has been hit */
Xint wttotal; /* total number of weights in use */
X
X/* global variable for the symmetric integer version */
X
X#ifdef SYMMETRIC
XWTTYPE stdthresh; /* the standard threshold weight value */
X#endif
X
XUNIT *locateunit(layerno,unitno) /* given a layer number and unit */
Xint layerno, unitno; /* number this routine returns the */
X{int i; /* address of the unit */
X UNIT *u;
X LAYER *layer;
X
X if (layerno >= 1 && layerno <= nlayers)
X {
X layer = start;
X for(i=1;i<=(layerno-1);i++) layer = layer->next;
X u = (UNIT *) layer->units;
X while (u != NULL && u->unitnumber != unitno) u = u->next;
X if (u == NULL)
X printf("there is no unit %3d in layer %3d\n",unitno,layerno);
X }
X else
X {
X printf("there is no layer %3d\n",layerno);
X return(NULL);
X };
X return(u);
X}
X
X#ifdef SYMMETRIC
X
Xint wtaddress(i,j,biasunit,type,size) /* Returns the address of a */
Xint i,j; /* weight (1), olddw (2), */
Xint biasunit; /* eta (3) or total (4). */
Xint type; /* One is created if it */
Xint size; /* doesn't already exist. */
X
X{ int k, addr;
X UNIT *u;
X WTNODE *w;
X
X if (biasunit == 1) addr = (int) malloc(size);
X else if (j >= i) addr = (int) malloc(size);
X else /* the item already exists, so find its address */
X {
X u = locateunit(2,j);
X w = (WTNODE *) u->wtlist;
X k = 1;
X while (k < i)
X {
X w = w->next;
X k = k + 1;
X };
X if (type == 1) addr = (int) w->weight;
X else if (type == 2) addr = (int) w->olddw;
X else if (type == 3) addr = (int) w->eta;
X else addr = (int) w->total;
X };
X return(addr);
X}
X
Xvoid setweight(w,i,j,biasunit) /* set initial values in w */
XWTNODE *w;
Xint i, j;
Xint biasunit;
X{WTTYPE *s;
X
X s = (WTTYPE *) wtaddress(i,j,biasunit,1,WTSIZE);
X *s = 0;
X w->weight = s;
X s = (WTTYPE *) wtaddress(i,j,biasunit,2,WTSIZE);
X *s = 0;
X w->olddw = s;
X s = (WTTYPE *) wtaddress(i,j,biasunit,3,WTSIZE);
X *s = eta;
X w->eta = s;
X#ifdef INTEGER
X w->total = (int *) wtaddress(i,j,biasunit,4,sizeof(int));
X#else
X w->total = (double *) wtaddress(i,j,biasunit,4,WTSIZE);
X#endif
X}
X
X#else
X
Xvoid setweight(w,i,j,biasunit) /* set initial values in w */
XWTNODE *w;
Xshort i,j;
Xint biasunit;
X{
X w->weight = 0;
X w->olddw = 0;
X w->eta = dbdeta;
X}
X
X#endif
X
XLAYER *mklayer(prevlayer,n) /* creates a layer of n units, pointers */
XLAYER *prevlayer; /* and weights back to the units in the */
Xint n; /* previous layer and links this new */
X /* layer into the list of layers */
X{UNIT *front, *p, *q, *bias, *prev, *ptr;
X WTNODE *wfront, *wprev, *w;
X LAYER *lptr;
X int i, j, count;
X
X/* make a list of nodes in this layer */
X
X count = 1;
X front = (UNIT *) malloc(sizeof(UNIT));
X front->unitnumber = count;
X front->layernumber = nlayers;
X prev = front;
X for(i=1;i<n;i++)
X {
X count = count + 1;
X ptr = (UNIT *) malloc(sizeof(UNIT));
X prev->next = ptr;
X ptr->unitnumber = count;
X ptr->layernumber = nlayers;
X prev = ptr;
X };
X prev->next = NULL;
X
X/* make a LAYER node to point to this list of units */
X
X lptr = (LAYER *) malloc(sizeof(LAYER));
X lptr->unitcount = n;
X lptr->patstart = NULL;
X lptr->currentpat = NULL;
X lptr->backlayer = prevlayer;
X lptr->next = NULL;
X (UNIT *) lptr->units = front; /* connect the list of units */
X
X/* return if this is the input layer */
X
X if (prevlayer == NULL) return(lptr);
X prevlayer->next = lptr;
X
X/* If we are working on a deeper layer, for every node in this layer, */
X/* create a linked list back to units in the previous layer. */
X
X i = 1;
X q = front;
X while (q != NULL) /* do a unit */
X {
X j = 1; /* handle first connection */
X p = (UNIT *) prevlayer->units;
X wfront = (WTNODE *) malloc(sizeof(WTNODE));
X wttotal = wttotal + 1;
X (WTNODE *) q->wtlist = wfront;
X wprev = wfront;
X (UNIT *) wfront->backunit = p;
X setweight(wfront,i,j,0);
X p = p->next;
X while (p != NULL) /* handle rest of connections */
X {
X j = j + 1;
X w = (WTNODE *) malloc(sizeof(WTNODE));
X wttotal = wttotal + 1;
X wprev->next = w;
X (UNIT *) w->backunit = p;
X setweight(w,i,j,0);
X wprev = w;
X p = p->next;
X };
X j = j + 1;
X bias = (UNIT *) malloc(sizeof(UNIT)); /* create a bias unit */
X bias->oj = scale(1.0);
X bias->layernumber = nlayers;
X bias->unitnumber = 32767; /* bias unit is unit 32767 */
X w = (WTNODE *) malloc(sizeof(WTNODE)); /* connect to end of list */
X wttotal = wttotal + 1;
X wprev->next = w;
X (UNIT *) w->backunit = bias;
X setweight(w,n+2,i,1);
X w->next = NULL;
X q = q->next;
X i = i + 1;
X };
X return(lptr);
X}
X
X#ifndef SYMMETRIC
X
Xvoid connect(a,b,range) /* add a connection from unit a to unit b */
XUNIT *a, *b; /* connections go in increasing order */
XWTTYPE range;
X
X{WTNODE *wnew, *w, *wprev;
X UNIT *wunit;
X int farenough;
X
X wnew = (WTNODE *) malloc(sizeof(WTNODE));
X wttotal = wttotal + 1;
X wnew->eta = dbdeta;
X wnew->weight = range * rand() / 32768;
X if (rand() > 16383) wnew->weight = -wnew->weight;
X wnew->olddw = 0;
X (UNIT *) wnew->backunit = a;
X w = (WTNODE *) b->wtlist;
X wprev = NULL;
X wunit = (UNIT *) w->backunit;
X farenough = 0; /* insert the weight in order */
X while (w != NULL && !farenough)
X if (wunit->layernumber > a->layernumber) farenough = 1;
X else if (wunit->layernumber == a->layernumber)
X {
X while (w != NULL && !farenough)
X {
X if (wunit->unitnumber < a->unitnumber &&
X wunit->layernumber == a->layernumber)
X {
X wprev = w;
X w = w->next;
X wunit = (UNIT *) w->backunit;
X }
X else farenough = 1;
X };
X }
X else
X {
X wprev = w;
X w = w->next;
X wunit = (UNIT *) w->backunit;
X }
X if (wprev == NULL)
X {
X wnew->next = w;
X (WTNODE *) b->wtlist = wnew;
X }
X else
X {
X wnew->next = w;
X wprev->next = wnew;
X };
X}
X
Xvoid addhiddenunit(layerno,range)
Xint layerno; /* add hidden unit to end of the layer */
XWTTYPE range;
X{
X LAYER *lptr, *prevlayer, *nextlayer;
X UNIT *u, *prevu, *p, *bias;
X WTNODE *wnode;
X int i, unitno;
X
X lptr = start;
X for (i=1;i <= (layerno - 1); i++) lptr = lptr->next;
X unitno = lptr->unitcount;
X lptr->unitcount = unitno + 1;
X prevu = locateunit(layerno,unitno);
X if (prevu == NULL) return;
X u = (UNIT *) malloc(sizeof(UNIT));
X prevu->next = u;
X u->next = NULL;
X u->unitnumber = unitno + 1;
X u->layernumber = layerno;
X bias = (UNIT *) malloc(sizeof(UNIT));
X bias->oj = scale(1.0);
X bias->layernumber = layerno;
X bias->unitnumber = 32767; /* bias unit is unit 32767 */
X wnode = (WTNODE *) malloc(sizeof(WTNODE));
X wttotal = wttotal + 1;
X wnode->weight = range * rand() / 32768;
X if (rand() > 16383) wnode->weight = -wnode->weight;
X wnode->olddw = 0;
X wnode->eta = dbdeta;
X wnode->next = NULL;
X (UNIT *) wnode->backunit = bias;
X (WTNODE *) u->wtlist = wnode;
X prevlayer = lptr->backlayer;
X p = (UNIT *) prevlayer->units;
X while (p != NULL)
X {
X connect(p,u,range);
X p = p->next;
X };
X nextlayer = lptr->next;
X p = (UNIT *) nextlayer->units;
X while (p != NULL)
X {
X connect(u,p,range);
X p = p->next;
X };
X}
X
X#endif
X
Xvoid readpatson(layer,command) /* reads the patterns for layer */
XLAYER *layer;
Xint command;
X
X{PATNODE *p, *prevp;
X PATLIST *pl;
X int i;
X
X pl = (PATLIST *) malloc(sizeof(PATLIST));
X pl->next = NULL;
X pl->bypass = 0; /* number of times to bypass this pattern */
X pl->pats = NULL; /* no patterns read yet */
X if (layer->patstart == NULL) (PATLIST *) layer->patstart = pl;
X else layer->currentpat->next = pl;
X layer->currentpat = pl;
X
X prevp = NULL; /* read in each number */
X for (i=1;i<=layer->unitcount;i++)
X {
X p = (PATNODE *) malloc(sizeof(PATNODE));
X if (informat == 'r') p->val = rdr(GE,(double) HCODE,command);
X else p->val = scale(readchar());
X if (readerror == 1)
X {
X printf("pattern not read\n");
X return;
X };
X p->next = NULL;
X if (prevp == NULL) pl->pats = p; else prevp->next = p;
X prevp = p;
X };
X}
X
Xvoid readpats(new,command) /* reads the input and output patterns */
Xint new;
Xint command;
X{ int i;
X PATLIST *pl;
X
X for (i=prevnpats + 1;i<=npats;i++)
X {
X readpatson(start,command);
X if (readerror == 1) goto failure;
X readpatson(last,command);
X if (readerror == 1) goto failure;
X };
X return;
Xfailure:
X if (data != stdin)
X {
X printf("error while reading pattern %d\n",i);
X exit(5);
X };
X if (new == 0)
X {
X resetpats();
X for (i=1;i<prevnpats;i++) setonepat();
X pl = (PATLIST *) start->currentpat;
X pl->next = NULL;
X pl = (PATLIST *) last->currentpat;
X pl->next = NULL;
X };
X printf("no patterns added\n");
X printf("%d patterns in use\n",prevnpats);
X npats = prevnpats;
X}
X
Xvoid init() /* initializes almost everything */
X{int i;
X
X activation = 'p'; /* piece-wise activation function */
X alpha = scale(0.5);
X backprop = 1; /* always back-propagate errors */
X bufferend = 0;
X bufferptr = buffsize + 1;
X ch = ' ';
X D = scale(1.0);
X dbdeta = scale(0.5);
X decay = scale(0.5);
X deriv = 'f'; /* use Fahlman's derivative */
X eta = scale(0.5);
X eta2 = scale(0.05);
X etamax = scale(30.0);
X extraconnect = 0;
X format[0] = 0; /* set default places for breaks in output patterns */
X for(i=1;i<=maxformat-1;i++) format[i] = format[i-1] + 10;
X informat = 'c'; /* input format is compressed */
X initialkick = -1; /* weights have not been kicked yet */
X kappa = scale(0.5);
X lastprint = 0;
X lastsave = 0;
X outformat = 'r'; /* output format is real */
X skiprate = 0;
X prevnpats = 0;
X qmark = scale(0.5);
X saverate = 100000; /* effectively, never save weights */
X seed = 0;
X#ifdef SYMMETRIC
X stdthresh = -32768; /* indicates no threshold set */
X#endif
X summary = '-'; /* don't summarize learning */
X theta1 = scale(0.5);
X theta2 = scale(1.0) - theta1;
X toler = scale(0.1);
X toosmall = -1; /* indicates no weights whittled away */
X totaliter = 0;
X update = 'o'; /* update formulas are the original */
X wtformat = 'r'; /* save weights in real format */
X wtlimit = scale(0.0); /* no limit on weights */
X wtlimithit = 0; /* weight limit not yet hit */
X wttotal = 0;
X}
X
Xvoid restartcmdloop() /* for a SIGINT, restart in cmdloop */
X{
X if (data != stdin) ch = EOF;
X signal(SIGINT,restartcmdloop);
X longjmp(cmdloopstate,1);
X}
X
Xvoid cmdloop() /* read commands and process them */
X{
X int finished, layerno, unitno, layer1, layer2, node1, node2;
X int i, itemp, itemp2;
X WTTYPE temp, temp2;
X UNIT *u, *n1, *n2, *hunit, *iunit, *junit, *kunit;
X LAYER *p;
X char string[81];
X WTNODE *w;
X
X setjmp(cmdloopstate); /* position to recover from SIGINT */
X finished = 0; /* loop until finished == 1 */
X do{
Xrestart:
X#ifdef SYMMETRIC
X if (data == stdin) printf("[?!*AabCEefHhijklmnoPpQqRrSsTtWwx]? ");
X#else
X if (data == stdin) printf("[?!*AabCcEefHhijklmnoPpQqRrSstWwx]? ");
X#endif
X while(ch == ' ' || ch == '\n') ch = readch();
X switch (ch) {
Xcase EOF: if (data == stdin) exit(6); else data = stdin;
X printf("taking commands from stdin now\n");
X bufferend = 0; /* force a read from stdin */
X bufferptr = buffsize + 1; /* when readch is called */
X ch = ' ';
X goto restart;
Xcase '?': printf("\n%d iterations, s %1d ",totaliter,seed);
X printf("k 0 %5.3lf, ",unscale(initialkick));
X printf("file = %s\n",datafilename);
X printf("Algorithm: a%c",activation);
X if (backprop) printf(" b+"); else printf(" b-");
X printf(" D%5.2lf d%c ",unscale(D),deriv);
X printf("l%6.2lf s%1d u%c\n",unscale(wtlimit),skiprate,update);
X printf("e %7.5lf %7.5lf",unscale(eta),unscale(eta2));
X printf(" --- a %7.5lf\n",unscale(alpha));
X printf("j d %8.5lf e %8.5lf",unscale(decay),unscale(dbdeta));
X printf(" k %8.5lf m %8.5lf",unscale(kappa),unscale(etamax));
X printf(" t %8.5lf\n",unscale(theta1));
X printf("tolerance = %4.2lf\n",unscale(toler));
X printf("f i%c o%c",informat,outformat);
X printf(" s%c w%c\n",summary,wtformat);
X printf("format breaks after: ");
X for (i=1;i<=10;i++) printf("%4d",format[i]);
X printf("\n ");
X for (i=11;i<=maxformat-1;i++) printf("%4d",format[i]);
X printf("\nlast time weights were saved: %d\n",lastsave);
X printf("saving weights every %d iterations\n",saverate);
X if (wtlimithit) printf(">>>>> WEIGHT LIMIT HIT <<<<<\n");
X printf("network size: ");
X p = start;
X while (p != NULL)
X {
X printf(" %1d",p->unitcount);
X p = p->next;
X };
X if (extraconnect == 1) printf(" with extra connections");
X printf(" (total: %1d weights)\n",wttotal);
X if (toosmall != -1)
X {
X printf("removed non-bias weights with absolute ");
X printf("value below %4.2lf\n",unscale(toosmall));
X };
X#ifdef SYMMETRIC
X if (stdthresh != -32768)
X printf("thresholds frozen at %lf\n", unscale(stdthresh));
X#endif
X printf("%d patterns ",npats);
X printf("%d learned ",npats-unlearnedpats);
X printf("%d unlearned on last pass\n",unlearnedpats);
X printf("? = %lf\n",unscale(qmark));
X printf("for help, type h followed by");
X printf(" the letter of the command\n\n");
X break;
Xcase '!': i = 0;
X ch = readch();
X while (ch != '\n' && i <= 80)
X {
X string[i] = ch;
X ch = readch();
X i = i + 1;
X };
X bufferptr = bufferptr - 1; /* ungetc(ch,data); */
X string[i] = '\0';
X system(string);
X break;
Xcase '*': break; /* * on a line is a comment */
Xcase 'A': while (ch != '\n' && ch != '*')
X {
X ch = readch();
X if (ch == 'a')
X {
X do ch = readch(); while (ch == ' ');
X if (ch == 'p') activation = 'p';
X#ifndef INTEGER
X else if (ch == 's') activation = 's';
X#endif
X else texterror();
X }
X else if (ch == 'b')
X {
X do ch = readch(); while (ch == ' ');
X if (ch == '+') backprop = 1;
X else if (ch == '-') backprop = 0;
X else texterror();
X }
X else if (ch == 'D')
X {
X temp = rdr(GT,0.0,'A');
X if (readerror == 0) D = temp;
X }
X else if (ch == 'd')
X {
X do ch = readch(); while (ch == ' ');
X if (ch == 'd' || ch == 'f' || ch == 'o') deriv = ch;
X else texterror();
X }
X else if (ch == 'l')
X {
X temp = rdr(GE,0.0,'A');
X if (readerror == 0)
X {
X wtlimit = temp;
X if (wtlimit == 0) wtlimithit = 0;
X };
X }
X else if (ch == 's')
X {
X itemp = readint(0,32767,'s');
X if (readerror == 0) skiprate = itemp;
X }
X else if (ch == 'u')
X {
X do ch = readch(); while (ch == ' ');
X if (ch == 'c' || ch == 'C' || ch == 'd' ||
X ch == 'j' || ch == 'o') update = ch;
X else texterror();
X }
X else if (ch == '*' || ch == '\n' || ch == ' ');
X else texterror();
X }
X bufferptr = bufferptr - 1;
X break;
Xcase 'a': temp = rdr(GE,0.0,'a');
X if (readerror == 0) alpha = temp;
X break;
Xcase 'b': itemp = 0;
X ch = readch();
X while (ch != '\n' && ch != '*')
X {
X bufferptr = bufferptr - 1;
X itemp2 = readint(format[itemp],MAXINT,'b');
X if (readerror == 1) goto endb;
X itemp = itemp + 1;
X if (itemp < maxformat) format[itemp] = itemp2;
X else printf("format too long\n");
X ch = readch();
X while (ch == ' ') ch = readch();
X /* if its the start of a number, back up */
X if (ch != '\n') bufferptr = bufferptr - 1;
X };
X if (itemp < maxformat-1)
X for (i=itemp+1;i <= maxformat-1; i++)
X format[i] = format[i-1] + 10;
X bufferptr = bufferptr - 1;
X endb: break;
Xcase 'C': if (toosmall != -1)
X {
X printf("cannot restart with the weights removed\n");
X break;
X };
X wtlimithit = 0;
X totaliter = 0;
X lastsave = 0;
X initialkick = -1;
X lastprint = 0;
X seed = 0;
X p = start->next;
X while (p != NULL)
X {
X u = (UNIT *) p->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X#ifdef SYMMETRIC
X if (w->next != NULL)
X { /* skip threshold weight */
X *(w->weight) = 0;
X *(w->olddw) = 0;
X *(w->eta) = dbdeta;
X };
X#else
X w->weight = 0;
X w->olddw = 0;
X w->eta = dbdeta;
X#endif
X w = w->next;
X };
X u = u->next;
X };
X p = p->next;
X };
X break;
X#ifndef SYMMETRIC
Xcase 'c': layer1 = readint(1,nlayers,'c');
X if (readerror == 1) break;
X node1 = readint(1,MAXINT,'c');
X if (readerror == 1) break;
X layer2 = readint(1,nlayers,'c');
X if (readerror == 1) break;
X node2 = readint(1,MAXINT,'c');
X if (readerror == 1) break;
X if (layer1 >= layer2)
X {
X printf("backward connections in c command not");
X printf(" implemented\n");
X break;
X };
X n1 = locateunit(layer1,node1);
X n2 = locateunit(layer2,node2);
X if (n1 != NULL && n2 != NULL)
X {
X connect(n1,n2,0);
X extraconnect = 1;
X }
X else printf("connection not made: %d %d %d %d\n",
X layer1, node1, layer2, node2);
X break;
X#endif
X
Xcase 'E': itemp = readint(0,1,'E');
X if (readerror == 1) break;
X else echo = itemp;
X break;
Xcase 'e': temp = rdr(GT,0.0,'e');
X if (readerror == 0) eta = temp;
X while (ch == ' ') ch = readch();
X if (ch != '\n' && ch != '*')
X {
X bufferptr = bufferptr - 1;
X temp = rdr(GT,0.0,'r');
X if (readerror != 1) eta2 = temp;
X }
X else eta2 = eta / 10;
X bufferptr = bufferptr - 1;
X break;
Xcase 'f': while (ch != '\n' && ch != '*')
X {
X ch = readch();
X if (ch == 'i')
X {
X do ch = readch(); while (ch == ' ');
X if (ch == 'c' || ch == 'r') informat = ch;
X else texterror();
X }
X else if (ch == 'o')
X {
X do ch = readch(); while (ch == ' ');
X if (ch == 'a' || ch == 'c' || ch == 'r') outformat = ch;
X else texterror();
X }
X else if (ch == 's')
X {
X do ch = readch(); while (ch == ' ');
X if (ch == '+' || summary == '-') summary = ch;
X else texterror();
X }
X else if (ch == 'w')
X {
X do ch = readch(); while (ch == ' ');
X if (ch == 'r' || ch == 'R' || ch == 'b' || ch == 'B')
X wtformat = ch;
X else texterror();
X }
X else if (ch == ' ' || ch == '*' || ch == '\n');
X else texterror();
X }
X bufferptr = bufferptr - 1;
X break;
X#ifndef SYMMETRIC
Xcase 'H': itemp = readint(2,nlayers,'H');
X if (readerror == 1) break;
X temp = rdr(GE,0.0,'H');
X if (readerror == 0) addhiddenunit(itemp,temp);
X break;
X#endif
Xcase 'h': help();
X break;
Xcase 'i': ch = readch();
X while(ch == ' ') ch = readch();
X itemp = 0;
X while(ch != ' ' && ch != '\n' && itemp < 49)
X {
X cmdfilename[itemp] = ch;
X itemp = itemp + 1;
X ch = readch();
X };
X cmdfilename[itemp] = '\0';
X if ((data = fopen(cmdfilename,"r")) == (FILE *) NULL)
X {
X printf("cannot open: %s\n",cmdfilename);
X data = stdin;
X printf("taking commands from stdin now\n");
X }
X bufferend = 0;
X bufferptr = buffsize + 1;
X ch = ' ';
X goto restart;
Xcase 'j': while (ch != '\n' && ch != '*')
X {
X ch = readch();
X if (ch == 'd')
X {
X temp = rdr(GT,0.0,'j');
X if (readerror == 0) decay = temp;
X }
X else if (ch == 'e')
X {
X temp = rdr(GT,0.0,'d');
X if (readerror == 0)
X {
X dbdeta = temp;
X p = start->next;
X while (p != NULL)
X {
X u = (UNIT *) p->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X#ifdef SYMMETRIC
X *(w->eta) = dbdeta;
X#else
X w->eta = dbdeta;
X#endif
X w = w->next;
X }
X u = u->next;
X }
X p = p->next;
X }
X }
X }
X else if (ch == 'k')
X {
X temp = rdr(GT,0.0,'j');
X if (readerror == 0) kappa = temp;
X }
X else if (ch == 'm')
X {
X temp = rdr(GT,0.0,'j');
X if (readerror == 0) etamax = temp;
X }
X else if (ch == 't')
X {
X temp = rdr(GE,0.0,'j');
X if (readerror == 0)
X {
X theta1 = temp;
X theta2 = scale(1.0) - theta1;
X };
X }
X else if (ch == '*' || ch == '\n' || ch == ' ');
X else texterror();
X }
X bufferptr = bufferptr - 1;
X break;
Xcase 'k': temp = rdr(GE,0.0,'k');
X if (readerror == 1) break;
X temp2 = rdr(GT,0.0,'k');
X if (readerror == 0)
X {
X if (initialkick == -1 && temp == 0) initialkick = temp2;
X kick(temp,temp2);
X }
X break;
Xcase 'l': layerno = readint(1,nlayers,'l');
X if (readerror == 1) break;
X p = start;
X for (i=2;i<=layerno;i++) p = p->next;
X printoutunits(p,0);
X break;
Xcase 'm': nlayers = 0;
X ch = readch();
X p = NULL;
X while (ch != '\n' && ch != '*')
X {
X itemp = readint(1,MAXINT,'m');
X if (readerror == 1) goto endm;
X nlayers = nlayers + 1;
X p = mklayer(p,itemp);
X if (nlayers == 1) start = p;
X ch = readch();
X while (ch == ' ') ch = readch();
X /* if its the start of a number, back up */
X if (ch != '\n') bufferptr = bufferptr - 1;
X };
X last = p;
X p = start;
X p = p->next;
X hlayer = (UNIT *) p->units;
X p = p->next;
X if (p != NULL)
X {
X ilayer = (UNIT *) p->units;
X p = p->next;
X if (p != NULL)
X {
X jlayer = (UNIT *) p->units;
X p = p->next;
X if (p != NULL) klayer = (UNIT *) p->units;
X }
X };
X bufferptr = bufferptr - 1;
X nullpatterns();
X endm: break;
Xcase 'n': if (start == NULL)
X {
X printf("the network must be defined first\n");
X break;
X };
X itemp = readint(1,MAXINT,'n');
X if (readerror == 1) break;
X nullpatterns();
X npats = itemp;
X readingpattern = 1;
X readpats(1,'n');
X readingpattern = 0;
X unlearnedpats = npats;
X break;
Xcase 'o': do ch = readch(); while (ch == ' ' || ch == '\n');
X if (ch == 'r' || ch == 'a' || ch == 'c') outformat = ch;
X else printf("incorrect output format: %c\n",ch);
X break;
Xcase 'P': do ch = readch(); while (ch == ' ');
X bufferptr = bufferptr - 1;
X if (ch == '\n' || ch == '*') itemp = 0;
X else
X {
X itemp = readint(0,npats,'P');
X if (readerror == 1) break;
X };
X if (itemp == 0) printpats(1,npats,0,1,0);
X else printpats(itemp,itemp,0,1,0);
X break;
Xcase 'p': u = (UNIT *) start->units;
X readingpattern = 1;
X hunit = hlayer;
X iunit = ilayer;
X junit = jlayer;
X kunit = klayer;
X while (u != NULL)
X {
X if (informat == 'r') u->oj = rdr(GE,(double) HCODE,'p');
X else u->oj = scale(readchar());
X if (readerror == 1) goto endp;
X if (u->oj <= KCODE) /* do hidden unit codes */
X {
X if (u->oj == HCODE)
X {if (copyhidden(u,&hunit,2) == 1) goto endp;}
X else if (u->oj == ICODE)
X {if (copyhidden(u,&iunit,3) == 1) goto endp;}
X else if (u->oj == JCODE)
X {if (copyhidden(u,&junit,4) == 1) goto endp;}
X else if (copyhidden(u,&kunit,5) == 1) goto endp;
X };
X u = u->next;
X };
X forward();
X printoutunits(last,0);
X endp: readingpattern = 0;
X break;
Xcase 'Q': temp = rdr(GT,(double) KCODE,'Q');
X if (readerror == 0) qmark = temp;
X break;
Xcase 'q': finished = 1;
X break;
Xcase 'R': restoreweights();
X break;
Xcase 'r': if (start == NULL)
X {
X printf("the network must be defined first\n");
X break;
X };
X iter = readint(1,MAXINT,'r');
X if (readerror == 1) break;
X while (ch == ' ') ch = readch();
X if (ch != '\n' && ch != '*')
X {
X bufferptr = bufferptr - 1;
X itemp = readint(1,MAXINT,'r');
X if (readerror != 1) run(iter,itemp);
X }
X else run(iter,-1);
X bufferptr = bufferptr - 1;
X break;
Xcase 'S': do ch = readch(); while (ch == ' ');
X bufferptr = bufferptr - 1;
X if (ch == '\n' || ch == '*') itemp = 0;
X else
X {
X itemp = readint(0,MAXINT,'S');
X if (readerror == 1) break;
X };
X if (itemp == 0) saveweights();
X else saverate = itemp;
X break;
Xcase 's': seed = readint(0,MAXINT,'s');
X srand(seed);
X break;
X#ifdef SYMMETRIC
Xcase 'T': stdthresh = rdr(GT,-unscale(32767),'T');
X if (readerror == 1) break;
X u = (UNIT *) last->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X while (w->next != NULL) w = w->next;
X *(w->weight) = stdthresh;
X u = u->next;
X };
X break;
X#endif
Xcase 't': temp = rdr(GT,0.0,'t');
X if (readerror == 1) break;
X else if (temp < scale(1.0)) toler = temp;
X else printf("tolerance value out of range\n");
X break;
X#ifndef SYMMETRIC
Xcase 'W': temp = rdr(GT,0.0,'W');
X if (readerror == 0)
X {
X toosmall = temp;
X whittle(temp);
X printf("total weights now: %1d\n",wttotal);
X };
X break;
X#endif
Xcase 'w': layerno = readint(2,nlayers,'w');
X if (readerror == 1) break;
X unitno = readint(1,MAXINT,'w');
X if (readerror == 1) break;
X u = locateunit(layerno,unitno);
X if (u != NULL) printweights(u);
X break;
Xcase 'x': if (start == NULL)
X {
X printf("the network must be defined first\n");
X break;
X };
X itemp = readint(1,MAXINT,'x');
X if (readerror == 1) break;
X prevnpats = npats;
X npats = npats + itemp;
X findendofpats(start);
X findendofpats(last);
X readingpattern = 1;
X readpats(0,'x');
X readingpattern = 0;
X unlearnedpats = npats;
X break;
Xdefault : texterror();
X break;
X };
X ch = readch();
X while(ch != '\n') ch = readch();
X }while (finished == 0);
X}
X
Xvoid main(argc,argv)
Xint argc;
Xchar *argv[];
X{
X char *fnamestr, *i;
X
Xprintf("Fast Backpropagation Copyright (c) 1990 by Donald R. Tveter\n");
X
X setbuf(stdout,NULL); /* set unbuffered output */
X if (argc == 1) /* check for file argument, if any */
X {
X printf("missing data file name, stdin assumed\n");
X data = stdin;
X *datafilename = '\0';
X }
X else
X if ((data = fopen(argv[1],"r")) == (FILE *) NULL)
X {
X printf("cannot open: %s\n",argv[1]);
X exit(1);
X }
X else /* make a copy of the file name in a global variable */
X {
X fnamestr = argv[1];
X i = datafilename;
X while(*fnamestr != '\0') *i++ = *fnamestr++;
X };
X init();
X signal(SIGINT,restartcmdloop); /* restart from interrrupt */
X cmdloop();
X}
END_OF_FILE
if test 36100 -ne `wc -c <'bp.c'`; then
echo shar: \"'bp.c'\" unpacked with wrong size!
fi
# end of 'bp.c'
fi
echo shar: End of archive 2 \(of 4\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 4 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
More information about the Comp.sources.misc
mailing list