www.pudn.com > BPËã·¨Ô´Âë.zip > io.c
/* ************************************************** */
/* file io.c: contains most input/output functions */
/* */
/* Copyright (c) 1990-96 by Donald R. Tveter */
/* */
/* ************************************************** */
#ifdef INTEGER
#include "ibp.h"
#else
#include "rbp.h"
#endif
#if defined(UNIX) && defined(HOTKEYS)
#ifdef BSD
struct termios raw; /* characteristics for hotkeys */
struct termios noraw; /* original characteristics */
#elif defined NEXT
struct sgttyb raw; /* characteristics for hotkeys */
struct sgttyb noraw; /* original characteristics */
#else /* the System V solution */
struct termio raw; /* characteristics for hotkeys */
struct termio noraw; /* original characteristics */
#endif
char onechar[1]; /* the buffer for the hotkey character */
#endif
extern UNIT *locateunit();
extern WTTYPE userscaleup();
extern char buffer[], outstr[], *inputfile, sysstr[];
extern char copyflag,deriv,*datafile,echo,informat;
extern char outformat, probtype, update, *wtfile, wtformat, zeroderiv;
extern char offby1, ringbell, up_to_date_stats, summary, biasset;
extern char wtlimithit, runningflag, seednote;
extern char saveonminimum, wtfilename[], trfiles[];
extern char recurinit;
extern int bufferend, bufferptr, filestackptr, format[];
extern int filetimes[], wtfilecount, timestoread, maxiter;
extern FILE *data, *filestack[];
extern LAYER *last, *start;
extern int extraconnect,ioconnects,lastsave,pagesize,pccnet,prevnpats;
extern int readerror, readingpattern, totaliter;
extern int printrate, saverate;
extern int lineno, stmsize;
extern long iotime;
extern short nlayers;
extern WTTYPE unknown, toler, toosmall, stdthresh;
extern WTTYPE initrange, kickrange, kicksize;
extern WTTYPE alpha, eta, eta2;
extern WTTYPE decay, dbdeta, kappa, etamax, theta1;
extern WTTYPE qpeta, qpnoise, mu;
extern WTTYPE classoff, classon;
extern WTTYPE hbiasact, obiasact;
extern char qpslope;
extern FILE *copy;
extern REAL qpdecayh, qpdecayo;
extern REAL toloverall, minimumsofar;
extern DATA s[2][2];
extern WTTYPE Dh, Do;
extern char ah, ao;
extern int wtsinuse, wttotal;
extern char incrementseed;
extern unsigned seed;
extern SEEDNODE *seedstart;
#if defined(UNIX) && defined(HOTKEYS)
#ifdef BSD
void initraw()
{
int i;
tcgetattr(0,&noraw);
raw.c_iflag = noraw.c_iflag;
raw.c_oflag = noraw.c_oflag;
raw.c_cflag = noraw.c_cflag;
raw.c_lflag = noraw.c_lflag & ~ ECHO;
raw.c_lflag = raw.c_lflag & ~ ICANON;
for (i=0;i 31.999 || x < -32.0)
{
sprintf(outstr,"magnitude of %f is too large for the integer",x);
pg(stdout,outstr);
pg(stdout," representation\n");
readerror = 1;
if (x > 31.999) return(MAXSHORT); else return(MINSHORT);
};
if (x > 0.0) s = x * 1024 + 0.5;
else s = x * 1024 - 0.5;
if (x != 0.0 && s == 0)
{
sprintf(outstr,"warning: magnitude of %f is too small for",x);
pg(stdout,outstr);
pg(stdout," the integer representation\n");
return(0);
};
return(s);
}
REAL unscale(x) /* returns the REAL value of short x */
short x;
{return((REAL) x / 1024.0);}
REAL unscaleint(x) /* returns the REAL value of INT32 x */
INT32 x;
{ return((REAL) x / 1024.0); }
#endif
int pushfile(filename,timestoread)
char *filename;
int timestoread;
{
FILE *file;
bufferptr = 0;
bufferend = 0;
buffer[0] = '\n';
file = fopen(filename,"r");
if (file == NULL)
{
sprintf(outstr,"cannot open: %s\n",filename); pg(stdout,outstr);
return(0);
};
filestackptr = filestackptr + 1;
if (filestackptr > MAXFILES)
{
pg(stdout,"can't stack up any more files\n");
filestackptr = filestackptr - 1;
fclose(file);
return(0);
};
filestack[filestackptr] = file;
filetimes[filestackptr] = timestoread;
data = file;
return(1);
}
void popfile()
{
bufferptr = 0;
bufferend = 0;
buffer[0] = '\n';
if (s[TOL][TRAIN].wrong == 0) /* break the "loop" */
filetimes[filestackptr] = 1;
filetimes[filestackptr] = filetimes[filestackptr] - 1;
if (filetimes[filestackptr] > 0) rewind(data);
else if (filestackptr > 0)
{
fclose(data);
filestackptr = filestackptr - 1;
}
else pg(stdout,"\nunexpected EOF: to quit the program, type q\n");
data = filestack[filestackptr];
}
int readch() /* returns the next character in the input buffer */
{
int i, ch2;
if (bufferptr > bufferend) /* then read next line into buffer */
{
#ifdef HOTKEYS
if (data == stdin)
{
ch2 = getch();
if (ch2 <= 26 || (ch2 >= 63 && ch2 <= 90)) /* HOTKEY characters */
{
if (ch2 == 2) buffer[0] = 'b';
else if (ch2 == 9) buffer[0] = 'i';
else if (ch2 == 18) buffer[0] = 'r';
else buffer[0] = ch2;
buffer[1] = '\n';
buffer[2] = '\0';
i = 1;
printf("%s",buffer);
goto entryfromhotkeys;
}
else /* all other characters */
{
putchar(ch2);
i = 0;
buffer[i] = ch2;
#ifdef UNIX
while (ch2 != '\n' && i < (BUFFSIZE-1))
#else
while (ch2 != 13 && i < (BUFFSIZE-1))
#endif
{
ch2 = getch();
if (ch2 == 8 && i >= 0)
{
i = i - 1;
putchar(8);
}
else if (ch2 == 8) {/* do nothing */}
#ifdef UNIX
else if (ch2 != '\n')
#else
else if (ch2 != 13)
#endif
{
putchar(ch2);
i = i + 1;
buffer[i] = ch2;
};
};
putchar('\n');
i = i + 1;
goto entryfromhotkeys;
};
}
else
#endif
ch2 = getc(data);
if (ch2 == EOF) return(ch2);
i = 0;
while(ch2 != '\n' && i < (BUFFSIZE-1))
{
#ifdef UNIX
if (ch2 == 13) ch2 = ' '; /* turn a ctrl-M into a blank */
#endif
if (ch2 == '\t') ch2 = ' ';
buffer[i] = ch2;
i = i + 1;
ch2 = getc(data);
};
entryfromhotkeys:
if (i == (BUFFSIZE-1)) pg(stdout,"line too long\n");
buffer[i] = '\n';
buffer[i+1] = '\0';
bufferend = i;
bufferptr = 0;
if (echo == '+') for(i = 0; i <= bufferend; i++) putchar(buffer[i]);
if (copy && ((data == stdin) || (echo == '+')))
for (i=0;i<=bufferend;i++) putc(buffer[i],copy);
}
ch2 = buffer[bufferptr];
bufferptr = bufferptr + 1;
return(ch2);
}
void texterror()
{
pg(stdout,"unexpected text: ");
pg(stdout,&buffer[bufferptr-1]);
bufferptr = bufferend;
}
char *readstr()
{
short i,start,end;
char *addr, *addr2;
i = bufferptr;
while (buffer[i] == ' ') i = i + 1;
start = i;
while (buffer[i] != ' ' && buffer[i] != '\n') i = i + 1;
end = i-1;
addr = (char *) malloc((int) end-start+2);
addr2 = addr;
for (i=start;i<=end;i++) *addr++ = buffer[i];
bufferptr = end + 1;
*addr = '\0';
return(addr2);
}
int scanfordigit()
{
int sign, ch2;
sign = 1;
restart:
do ch2 = readch(); while (ch2 == ' ' || ch2 == '\n');
if ((ch2 >= '0' && ch2 <= '9') || ch2 == '.')
{
bufferptr = bufferptr - 1;
return(sign);
};
switch (ch2) {
case '}': readerror = 3;
return(0);
case EOF: readerror = 2;
return(0);
case '*': while (ch2 != '\n') ch2 = readch();
goto restart;
case '-': sign = -sign;
goto restart;
case 'h':
case 'x':
case 'X':
case 'H':
case 'd':
case 's': bufferptr = bufferptr - 1;
return(0);
default: readerror = 1;
return(0);
};
}
int readint(min,max,command)
int min, max;
char command;
{
int sign, number, ch2;
readerror = 0;
sign = scanfordigit();
if (readerror)
{
if (readerror == 1) texterror();
return(0);
};
number = 0;
do ch2 = readch(); while (ch2 == ' ');
while (ch2 >= '0' && ch2 <= '9')
{
number = number * 10 + (ch2 - '0');
ch2 = readch();
};
bufferptr = bufferptr - 1;
number = sign * number;
if (number < min || number > max)
{
sprintf(outstr,"out of range value: %d",number); pg(stdout,outstr);
if (data == stdin) pg(stdout,"\n");
else {sprintf(outstr," in %c command\n",command); pg(stdout,outstr);};
readerror = 1;
};
return(number);
}
REAL readreal(op,min,command)
int op;
REAL min;
int command;
{
REAL fractpart, divisor, intpart, sign;
double number;
int ch2, numread, i;
readerror = 0;
sign = (REAL) scanfordigit();
if (readerror || (sign == 0 && !readingpattern))
{
if (readerror == 1) texterror();
return(0);
};
ch2 = readch();
if (ch2 == 'H' && readingpattern) return(unscale(CAPHCODE));
else if (ch2 == 'X' && readingpattern) return(unscale(CAPXCODE));
else if (ch2 == 'h' && readingpattern) return(unscale(HCODE));
else if (ch2 == 'i' && readingpattern) return(unscale(ICODE));
else if (ch2 == 'o' && readingpattern) return(unscale(OCODE));
else if (ch2 == 'd' && readingpattern) return(unscale(DIFFCODE));
else if (ch2 == 's' && readingpattern) return(unscale(SKIPCODE));
else if (ch2 == 'x' && readingpattern) return(unscale(unknown));
i = 0;
while ((ch2 >= '0' && ch2 <='9') || ch2 == '+' || ch2 == '-' ||
ch2 == 'e' || ch2 == 'E' || ch2 == '.')
{
outstr[i] = ch2;
i = i+1;
ch2 = readch();
};
outstr[i] = 0;
bufferptr = bufferptr - 1;
numread = sscanf(outstr,"%lf",&number);
if (numread == 0)
{
pg(stdout,"bad real value\n");
readerror = 1;
return(0.0);
};
number = sign * number;
if (op == GT && number > min) return(number);
else if (op == GE && number >= min) return(number);
else
{
sprintf(outstr,"erroneous value: %f",number); pg(stdout,outstr);
if (data == stdin) pg(stdout,"\n");
else {sprintf(outstr," in %c command\n",command); pg(stdout,outstr);};
readerror = 1;
return(0.0);
};
}
WTTYPE rdr(op,min,command) /* reads REAL real numbers and converts */
int op; /* them to 16-bit integers if necessary */
REAL min;
int command;
{
REAL x;
WTTYPE ix;
x = readreal(op,min,command);
if (readerror) return(0);
ix = scale(x);
if (readerror) return(0);
return(ix);
}
REAL readchar() /* reads data in compressed format */
{
int ch2;
readerror = 0;
ch2 = readch();
do {
switch (ch2) {
case '\n':
case ' ': ch2 = readch();
break;
case '1': return(1.0);
case '0': return(0.0);
case 'X': return(unscale(CAPXCODE));
case 'x': return(unscale(unknown));
case '*': do ch2 = readch(); while(ch2 != '\n');
break;
case 'H': return(unscale(CAPHCODE));
case 'h': return(unscale(HCODE));
case 's': return(unscale(SKIPCODE));
case 'd': return(unscale(DIFFCODE));
case EOF: readerror = 2;
return(0.0);
case '}': readerror = 3;
return(0.0);
default: texterror();
readerror = 1;
return(0.0);};
} while (0 == 0);
}
void readapat(pn,relation,minimum,command,informat)
PATNODE *pn;
int relation;
REAL minimum;
int command;
char informat;
{
REAL val;
int unitnumber;
UNIT *u;
if (informat == 'r') val = rdr(relation,minimum,command);
else val = scale(readchar());
if (val == ICODE)
{
recurinit = '+';
pn->layer = 1;
pn->val = ICODE;
unitnumber = readint(1,start->unitcount,'r');
if (readerror != 0) return;
pn->unitno = unitnumber;
u = locateunit(1,unitnumber);
pn->addr = &(u->oj);
}
else if (val == HCODE)
{
recurinit = '+';
pn->addr = (WTTYPE *) -1;
pn->layer = 2;
pn->val = HCODE;
pn->unitno = HCODE;
}
else if (val == CAPXCODE)
{
pn->addr = (WTTYPE *) -1;
pn->layer = 2;
pn->val = CAPXCODE;
pn->unitno = CAPXCODE;
}
else if (val == CAPHCODE)
{
recurinit = '+';
pn->addr = (WTTYPE *) -1;
pn->layer = 2;
pn->val = CAPHCODE;
pn->unitno = CAPHCODE;
}
else if (val == OCODE)
{
recurinit = '+';
pn->layer = nlayers;
pn->val = OCODE;
unitnumber = readint(1,last->unitcount,'r');
if (readerror != 0) return;
pn->unitno = unitnumber;
u = locateunit((int) pn->layer,unitnumber);
pn->addr = &(u->oj);
}
else if (val == SKIPCODE)
{
pn->addr = (WTTYPE *) -1;
pn->layer = 0;
pn->val = SKIPCODE;
pn->unitno = SKIPCODE;
}
else if (val == DIFFCODE)
{
pn->addr = (WTTYPE *) -1;
pn->layer = nlayers;
pn->val = DIFFCODE;
pn->unitno = DIFFCODE;
}
else
{
pn->addr = NULL;
pn->val = val;
pn->layer = 0; /* unused */
pn->unitno = 0; /* unused */
};
}
void readpatson(layer,list,command)
LAYER *layer;
int list;
int command;
{PATLIST *pl, *prev;
PATNODE *pn;
int i, answer, veclength;
pl = (PATLIST *) malloc(sizeof(PATLIST));
pl->next = NULL;
pl->pats = NULL; /* no patterns read yet */
if (layer->patstart[list] == NULL)
{
prev = NULL;
layer->patstart[list] = pl;
}
else
{
prev = layer->currentpat[list];
prev->next = pl;
};
layer->currentpat[list] = pl;
veclength = layer->unitcount;
pn = (PATNODE *) malloc(veclength * sizeof(PATNODE));
pl->pats = pn;
if (layer == last && probtype == 'c')
{
answer = readint(1,veclength,command);
if (readerror != 0) return;
for (i=1;i<=veclength;i++)
{
if (i == answer) pn->val = classon; else pn->val = classoff;
pn->addr = NULL;
pn->layer = nlayers;
pn->unitno = i;
pn++;
};
return;
};
for (i=1;i<=veclength;i++)
{
readapat(pn,GE,(REAL) HCODE,command,informat);
if ((readerror == 3 || readerror == 2) && i == 1 && layer == start)
{
if (prev != NULL) prev->next = NULL;
free(pn);
free(pl);
readerror = readerror + 2;
return;
}
else if (readerror != 0) return;
if (pn->unitno == CAPHCODE || pn->unitno == CAPXCODE) return; else pn++;
};
return;
}
int readpats(list,command)
int list, command;
{ int i, j;
PATLIST *pl;
/* look for scaling parameters, if any, in a TRAINing set */
if (list == TRAIN)
{
REAL temp;
WTTYPE trans, sca;
int ch1, ch2, k, col, nfactors;
UNIT *u;
ch1 = readch();
if (ch1 == '\n') ch1 = readch();
ch2 = readch();
if (ch1 != '*' || ch2 != '$') bufferptr = bufferptr - 2;
else /* there are scaling parameters */
{
nfactors = readint(0,MAXINT,'r');
do ch1 = readch(); while (ch1 != '\n');
u = start->units;
for (k=1;k<=nfactors;k++)
{
if (u == NULL)
{
pg(stdout,"not enough input units for these patterns\n");
exit(99);
};
ch1 = readch();
ch2 = readch();
if (ch1 != '*' || ch2 != '$')
{
pg(stdout,"error in input scaling list\n");
goto readthepatterns;
}
else
{
col = readint(k,k,'r');
if (readerror == 1)
{
pg(stdout,"error in scaling list\n");
goto readthepatterns;
};
trans = rdr(GE,(REAL) -MAXINT,'r');
if (readerror == 1)
{
pg(stdout,"error in scaling list\n");
goto readthepatterns;
}
else u->translate = trans;
sca = rdr(GE,(REAL) -MAXINT,'r');
if (readerror == 1)
{
pg(stdout,"error in scaling list\n");
goto readthepatterns;
}
else u->userscale = sca;
u = u->next;
do ch1 = readch(); while (ch1 != '\n');
};
};
/* do the output unit scaling factors if its not a classification problem */
if (probtype != 'c')
{
u = last->units;
for (k=1;k<=last->unitcount;k++)
{
ch1 = readch();
ch2 = readch();
if (ch1 != '*' || ch2 != '$')
{
pg(stdout,"error in output scaling list\n");
goto readthepatterns;
}
else
{
col = readint(k,k,'r');
if (readerror == 1)
{
pg(stdout,"error in scaling list\n");
goto readthepatterns;
};
trans = rdr(GE,(REAL) -MAXINT,'r');
if (readerror == 1)
{
pg(stdout,"error in scaling list\n");
goto readthepatterns;
}
else u->translate = trans;
sca = rdr(GE,(REAL) -MAXINT,'r');
if (readerror == 1)
{
pg(stdout,"error in scaling list\n");
goto readthepatterns;
}
else u->userscale = sca;
u = u->next;
do ch1 = readch(); while (ch1 != '\n');
}; /* end else */
}; /* end for */
}; /* ends prob type */
}; /* else there are scaling parameters */
}; /* if its a training set file */
readthepatterns:
i = 0;
readerror = 0;
while (readerror == 0)
{
readpatson(start,list,command);
if (readerror) break;
readpatson(last,list,command);
if (readerror) break;
i = i + 1;
};
if (readerror == 5) return(i);
else if (readerror == 4)
{
popfile();
return(i);
};
/* failure for some reason */
sprintf(outstr,"error while reading pattern %d",i+1); pg(stdout,outstr);
if (readerror == 1) pg(stdout,"\n");
else if (readerror == 2) pg(stdout,": unexpected end of file\n");
else if (readerror == 3) pg(stdout,": unexpected }\n");
if (readerror == 2) popfile();
if (i > 0)
{
pl = (PATLIST *) start->patstart[list];
for (j=1;j<=prevnpats + i - 1;j++) pl = pl->next;
pl->next = NULL;
pl = (PATLIST *) last->patstart[list];
for (j=1;j<=prevnpats + i - 1;j++) pl = pl->next;
pl->next = NULL;
};
return(i);
}
int pg(f,str) /* paging and making a copy function */
FILE *f;
char *str;
{
char *ch3,action,cr;
int i;
long clockbefore, clockafter;
int nbackspaces = 5;
if (f != stdout) {fprintf(f,"%s",str); return(0);};
clockbefore = clock();
action = 0;
ch3 = str;
while (*ch3 != '\0')
{
if (*ch3 == '\n')
{
putchar('\n');
if (copyflag == '+') putc('\n',copy);
lineno = lineno + 1;
if (pagesize > 0 && lineno > 0 && lineno % pagesize == 0)
{
printf("More?");
#ifdef HOTKEYS
action = getch();
#else
action = getchar();
if (action != '\n') cr = getchar();
#endif
for(i=1;i<=nbackspaces;i++) putchar(8);
for(i=1;i<=nbackspaces;i++) putchar(' ');
for(i=1;i<=nbackspaces;i++) putchar(8);
if (action == 'q') goto stoppaging;
else if (action == 'c') lineno = -MAXINT;
#ifdef UNIX
else if (action == '\n') lineno = lineno - 1;
#else
else if (action == 13) lineno = lineno - 1;
#endif
else if (action == 4) lineno = pagesize / 2;
else lineno = 0;
}
}
else {putchar(*ch3); if (copyflag == '+') putc(*ch3,copy); };
ch3++;
};
stoppaging:
clockafter = clock();
iotime = iotime + clockafter - clockbefore;
if (action == 'q') return(1); else return(0);
}
void printnetsize(f) /* the size of the network */
FILE *f;
{LAYER *p;
pg(f,"m ");
p = start;
if (stmsize > 0)
{
sprintf(outstr," %1d+%1d",p->unitcount-stmsize,stmsize);
pg(f,outstr);
p = p->next;
};
while (p != NULL)
{
sprintf(outstr," %1d",p->unitcount);
pg(f,outstr);
p = p->next;
};
if (ioconnects) pg(f," x");
if (pccnet) pg(f," p");
}
void listseeds(f)
FILE *f;
{
SEEDNODE *s;
s = seedstart->next;
pg(f,"s");
while (s != NULL)
{
sprintf(outstr," %1d",s->val); pg(f,outstr);
s = s->next;
};
}
int printoutunits(patnum,layer,list,error,tok,mok)
int patnum;
LAYER *layer;
int list;
REAL error;
char tok,mok;
{
short unitno, fmtbreaknum;
UNIT *u;
WTTYPE upper, middle, diff;
int i;
WTTYPE *target;
PATLIST *pl;
#ifdef INTEGER
float tempreal;
#endif
upper = scale(1.0) - toler;
middle = scale(0.5);
unitno = 0;
fmtbreaknum = 1;
/*
if (layer == last && patnum > 0)
{
pl = last->currentpat[list];
target = pl->pats;
u = (UNIT *) layer->units;
for (i=1;i<=last->unitcount;i++)
{
u->tj = *target++;
u = u->next;
};
};
*/
if (patnum) {sprintf(outstr,"%5d ",patnum); pg(stdout,outstr);}
else pg(stdout," ");
u = (UNIT *) layer->units;
while (u != NULL)
{
diff = u->tj - u->oj;
unitno = unitno + 1;
if (outformat == 'r' || outformat == 's')
{
sprintf(outstr,"%6.3f ",unscale(u->oj)); pg(stdout,outstr);
if (format[fmtbreaknum] == unitno)
{
if (pg(stdout,"\n ")) return(1);
if (fmtbreaknum < MAXFORMAT - 1) fmtbreaknum = fmtbreaknum + 1;
}
}
else if (outformat == 'e')
{
sprintf(outstr,"%12.4e ",unscale(u->oj)); pg(stdout,outstr);
if (format[fmtbreaknum] == unitno)
{
if (pg(stdout,"\n ")) return(1);
if (fmtbreaknum < MAXFORMAT - 1) fmtbreaknum = fmtbreaknum + 1;
}
}
else if (outformat == 'a')
{
if (diff < toler) pg(stdout,"c");
else if (u->oj > upper) pg(stdout,"1");
else if (u->oj < toler) pg(stdout,"0");
else if (u->oj > u->tj) pg(stdout,"^");
else pg(stdout,"v");
if (format[fmtbreaknum] == unitno)
{
pg(stdout," ");
if (fmtbreaknum < MAXFORMAT - 1) fmtbreaknum = fmtbreaknum + 1;
}
}
else
{
if (u->oj > upper) pg(stdout,"1");
else if (u->oj > middle) pg(stdout,"^");
else if (u->oj < toler) pg(stdout,"0");
else pg(stdout,"v");
if (format[fmtbreaknum] == unitno)
{
pg(stdout," ");
if (fmtbreaknum < MAXFORMAT - 1) fmtbreaknum = fmtbreaknum + 1;
}
}
u = u->next;
};
if (patnum > 0)
{
sprintf(outstr," e %5.3f",error); pg(stdout,outstr);
if (tok) pg(stdout," ok"); else pg(stdout," ");
if (mok) pg(stdout," ok");
if (pg(stdout,"\n")) return(1); else return(0);
};
if (pg(stdout,"\n")) return(1);
if (pg(stdout,"\n")) return(1); else return(0);
}
void saveweights() /* saves weights on the file weights */
{
UNIT *u, *bu;
LAYER *layer;
WTNODE *w;
WTTYPE wvalue, evalue, dvalue, svalue;
int wtsize, unitno, layerno, i;
short wtinuse;
FILE *wtfileptr;
wtsize = WTSIZE;
sprintf(wtfilename,"%s",wtfile);
wtfileptr = fopen(wtfilename,"wb");
if (wtfileptr == NULL)
{
sprintf(outstr,"cannot open: %s\n",wtfilename); pg(stdout,outstr);
return;
};
fprintf(wtfileptr,"%d%c",totaliter,wtformat);
layer = start;
fprintf(wtfileptr," m %1d",layer->unitcount);
layer = layer->next;
while (layer != NULL)
{
fprintf(wtfileptr," %1d",layer->unitcount);
layer = layer->next;
};
if (ioconnects) fprintf(wtfileptr," x");
fprintf(wtfileptr," aah%c",start->next->activation);
fprintf(wtfileptr," ao%c",last->activation);
fprintf(wtfileptr," bh %f",unscale(start->next->biasact));
fprintf(wtfileptr," bo %f",unscale(last->biasact));
fprintf(wtfileptr," Dh %f",unscale(start->next->D));
fprintf(wtfileptr," Do %f",unscale(last->D));
fprintf(wtfileptr," file = %s",datafile);
#ifdef DOSMOD /* I don't remember this */
fputc('\r',wtfileptr);
#endif
fputc('\n',wtfileptr);
layer = start->next;
while (layer != NULL)
{
u = (UNIT *) layer->units;
while (u != NULL)
{
w = (WTNODE *) u->wtlist;
while (w != NULL)
{
#ifdef SYMMETRIC
wvalue = *(w->weight);
evalue = *(w->eta);
dvalue = *(w->olddw);
svalue = *(w->slope);
wtinuse = w->inuse;
#else
wvalue = w->weight;
evalue = w->eta;
dvalue = w->olddw;
svalue = w->slope;
wtinuse = w->inuse;
#endif
if (wtformat == 'r' || wtformat == 'R')
{
fprintf(wtfileptr,"%14.6e",unscale(wvalue));
fprintf(wtfileptr,"%3d",w->inuse);
if (wtformat == 'R')
{
fprintf(wtfileptr," %14.6e",unscale(evalue));
fprintf(wtfileptr," %14.6e",unscale(dvalue));
fprintf(wtfileptr," %14.6e",unscale(svalue));
};
bu = w->backunit;
fprintf(wtfileptr," %1d ",bu->layernumber);
if (bu->unitnumber == 32767) fprintf(wtfileptr,"b to ");
else fprintf(wtfileptr,"%1d to ",bu->unitnumber);
fprintf(wtfileptr,"%1d %1d",u->layernumber,u->unitnumber);
#ifdef DOSMOD
fputc('\r',wtfileptr);
#endif
fputc('\n',wtfileptr);
}
w = w->next;
};
u = u->next;
};
layer = layer->next;
};
fflush(wtfileptr);
fclose(wtfileptr);
lastsave = totaliter;
}
void restoreweights() /* restore weights */
{
FILE *wtfileptr;
UNIT *u;
LAYER *layer;
WTNODE *w;
int ch2, fileformat, wtsize, numread, i, layerno, unitno;
WTTYPE wvalue, evalue, dvalue, svalue;
int wtinuse;
double temp;
unsigned char *cptr;
/*
if (numwtfiles == '+') sprintf(wtfilename,"%s.%1d",wtfile,wtfilecount);
else sprintf(wtfilename,"%s",wtfile);
*/
wtfileptr = fopen(wtfilename,"rb");
if (wtfileptr == NULL)
{
sprintf(outstr,"cannot open: %s\n",wtfilename);
pg(stdout,outstr);
return;
};
numread = fscanf(wtfileptr,"%d",&totaliter);
if (numread == EOF) goto unexpectedeof;
if (numread == 0) goto badread;
fileformat = fgetc(wtfileptr);
if (fileformat == EOF) goto unexpectedeof;
if (fileformat != wtformat) pg(stdout,"note: weight format mismatch\n");
wtsize = WTSIZE;
do ch2 = fgetc(wtfileptr); while (ch2 != '\n');
layer = start->next;
while (layer != NULL)
{
u = (UNIT *) layer->units;
while (u != NULL)
{
u->inuse = 1;
w = (WTNODE *) u->wtlist;
while (w != NULL)
{
if (fileformat == 'r' || fileformat == 'R')
{
numread = fscanf(wtfileptr,"%lf",&temp);
if (numread == EOF) goto unexpectedeof;
if (numread == 0) goto badread;
wvalue = scale((REAL) temp);
#ifdef ALTCODE
{
do ch2 = fgetc(wtfileptr); while (ch2 == ' ');
wtinuse = 1;
if (ch2 == '-')
{
wtinuse = -1;
ch2 = fgetc(wtfileptr);
};
if (ch2 == 0) wtinuse = 0;
else if (ch2 == '1') wtinuse = wtinuse;
else if (ch2 == '2') wtinuse = wtinuse * 2;
else pg(stdout,"bad weight in use flag\n");
}
#else
numread = fscanf(wtfileptr,"%d",&wtinuse);
if (numread == EOF) goto unexpectedeof;
if (numread == 0) goto badread;
#endif
if (fileformat == 'R')
{
numread = fscanf(wtfileptr,"%lf",&temp);
if (numread == EOF) goto unexpectedeof;
if (numread == 0) goto badread;
evalue = scale((REAL) temp);
numread = fscanf(wtfileptr,"%lf",&temp);
if (numread == EOF) goto unexpectedeof;
if (numread == 0) goto badread;
dvalue = scale((REAL) temp);
numread = fscanf(wtfileptr,"%lf",&temp);
if (numread == EOF) goto unexpectedeof;
if (numread == 0) goto badread;
svalue = scale((REAL) temp);
};
do ch2 = fgetc(wtfileptr); while (ch2 != '\n');
if (ch2 == '\n')
{
ch2 = fgetc(wtfileptr);
if (ch2 != '\r') ungetc(ch2,wtfileptr);
};
}
#ifdef SYMMETRIC
*(w->weight) = wvalue;
if (fileformat == 'R')
{
*(w->olddw) = dvalue;
*(w->eta) = evalue;
}
else *(w->olddw) = 0;
#else
w->weight = wvalue;
w->inuse = wtinuse;
if (fileformat == 'R')
{
w->olddw = dvalue;
w->eta = evalue;
w->slope = svalue;
}
else w->olddw = 0;
#endif
w = w->next;
};
u = u->next;
};
layer = layer->next;
};
fclose(wtfileptr);
lastsave = totaliter;
return;
badread: pg(stdout,"\n>>>>> scanf read error <<<<<\n\n");
fclose(wtfileptr);
return;
unexpectedeof: pg(stdout,"\n>>>>> ran out of weights <<<<<\n\n");
fclose(wtfileptr);
}
void printweights(u,layerno) /* print the weights leading into unit u */
UNIT *u;
int layerno;
{
WTNODE *w;
UNIT *bunit;
WTTYPE value;
LAYER *layer;
int i;
short wtinuse, unitinuse;
#ifdef INTEGER
INT32 sum, input;
#else
REAL sum, input;
#endif
w = (WTNODE *) u->wtlist;
sum = 0;
pg(stdout,"layer unit inuse unit value weight inuse input from unit\n");
while (w != NULL)
{
bunit = (UNIT *) w->backunit;
unitinuse = w->backunit->inuse;
#ifdef SYMMETRIC
value = *(w->weight);
wtinuse = 1;
#else
value = w->weight;
wtinuse = w->inuse;
#endif
#ifdef INTEGER
if (wtinuse && unitinuse)
{
input = (INT32) value * bunit->oj;
input = input / 1024;
}
else input = 0;
#else
if (wtinuse && unitinuse) input = value * bunit->oj; else input = 0;
#endif
sum = sum + input;
sprintf(outstr,"%3d ",bunit->layernumber); pg(stdout,outstr);
if (bunit->unitnumber == 32767) pg(stdout," b ");
else {sprintf(outstr,"%3d ",bunit->unitnumber); pg(stdout,outstr);};
sprintf(outstr,"%4d ",unitinuse); pg(stdout,outstr);
sprintf(outstr,"%10.5f %10.5f ",unscale(bunit->oj),unscale(value));
pg(stdout,outstr);
sprintf(outstr," %3d ",wtinuse); pg(stdout,outstr);
sprintf(outstr,"%14.5f\n",unscaleint(input));
if (pg(stdout,outstr)) return;
w = w->next;
};
pg(stdout," ");
sprintf(outstr,"sum = %9.5f\n",unscaleint(sum));
if (pg(stdout,outstr)) return;
layer = start;
for (i=2;i<=layerno;i++) layer = layer->next;
if (layer->D != scale(1.0))
{
#ifdef INTEGER
sum = sum * layer->D / 1024;
#else
sum = sum * layer->D;
#endif
pg(stdout," ");
sprintf(outstr,"sum = %9.5f with D = %7.3f\n",unscaleint(sum),unscale(layer->D));
if (pg(stdout,outstr)) return;
};
pg(stdout,"\n");
}
void parameters(f)
FILE *f;
{int i;
printnetsize(f);
sprintf(outstr," * %1d weights; ",wttotal); pg(f,outstr);
sprintf(outstr,"data file = %s",datafile); pg(f,outstr);
if (zeroderiv) pg(f,"*>>>>> 0 deriv <<<<<*\n"); else pg(f,"\n");
if (toosmall != 0)
{
sprintf(outstr,"pw %4.2f",unscale(toosmall)); pg(f,outstr);
sprintf(outstr," * weights in use: %1d\n",wtsinuse); pg(f,outstr);
};
sprintf(outstr,"sb %f\n", unscale(stdthresh)); pg(f,outstr);
#ifdef INTEGER
if (wtlimithit) pg(f,"*>>>>> WEIGHT LIMIT HIT <<<<<*\n");
#endif
listseeds(f); pg(f,"\n");
sprintf(outstr,"r %1d %1d ",maxiter,printrate); pg(f,outstr);
if (f != stdout) pg(f,"\"\n"); else pg(f,"\n");
sprintf(outstr,"f b%c c%c e%c i%c",ringbell,copyflag,echo,informat);
pg(f,outstr);
if (offby1 == '+') pg(f," O+"); else pg(f," O-");
sprintf(outstr," o%c P %d p%c ",outformat,pagesize,probtype);
pg(f,outstr);
sprintf(outstr,"R%c ",runningflag); pg(f,outstr);
sprintf(outstr," s%c ",summary); pg(f,outstr);
sprintf(outstr,"u%c ",up_to_date_stats); pg(f,outstr);
sprintf(outstr,"x% f\n",unscale(unknown)); pg(f,outstr);
pg(f,"f B ");
for (i=1;i<=MAXFORMAT-1;i++)
{sprintf(outstr," %1d",format[i]); pg(f,outstr);};
pg(f,"\n");
sprintf(outstr,"! %s ",sysstr); pg(f,outstr);
if (f != stdout) pg(f,"\"\n"); else pg(f,"\n");
pg(f,"a ");
if (nlayers > 2)
{sprintf(outstr,"ah %c ",ah); pg(f,outstr);};
sprintf(outstr,"ao %c ",ao); pg(f,outstr);
sprintf(outstr,"d%c ",deriv); pg(f,outstr);
sprintf(outstr,"u%c\n",update); pg(f,outstr);
sprintf(outstr,"e %7.5f %7.5f\n",unscale(eta),unscale(eta2));pg(f,outstr);
sprintf(outstr,"a %7.5f\n",unscale(alpha)); pg(f,outstr);
#ifndef SYMMETRIC
sprintf(outstr,"d d %8.5f e %8.5f ",unscale(decay),unscale(dbdeta));
pg(f,outstr);
sprintf(outstr,"k %8.5f m %8.5f ",unscale(kappa),unscale(etamax));
pg(f,outstr);
sprintf(outstr,"t %8.5f\n",unscale(theta1));
pg(f,outstr);
sprintf(outstr,"qp dh %8.6f do %8.6f e %8.5f ",qpdecayh,qpdecayo,unscale(qpeta));
pg(f,outstr);
sprintf(outstr,"m %8.5f n %8.5f s%c\n",unscale(mu),unscale(qpnoise),qpslope);
pg(f,outstr);
#endif
sprintf(outstr,"* last save at: %d\n",lastsave); pg(f,outstr);
sprintf(outstr,"rw %s\n",wtfilename); pg(f,outstr);
sprintf(outstr,"t %4.2f\n",unscale(toler)); pg(f,outstr);
printstats(f,TRAIN,1,s);
if (s[TOL][TEST].npats > 0) printstats(f,TEST,1,s);
if (f != stdout)
{
sprintf(outstr,"z %e",minimumsofar); pg(f,outstr);
};
pg(f,"\n");
}
void menus(ch)
char ch;
{
switch (ch) {
case '?': parameters(stdout); return;
case 'A':
pg(stdout,"\nAlgorithm Parameters\n\n");
pg(stdout,"a a sets all act. functions to ; {ls} h aa\n");
if (nlayers > 2)
{
sprintf(outstr,"a ah %c ",ah); pg(stdout,outstr);
pg(stdout,"hidden layer(s) act. function; {ls} h aa\n");
};
sprintf(outstr,"a ao %c ",ao); pg(stdout,outstr);
pg(stdout,"output layer act. function; {ls} h aa\n");
sprintf(outstr,"a d %c ",deriv); pg(stdout,outstr);
pg(stdout,"the output layer derivative term; {cdf} h ad\n");
sprintf(outstr,"a u %c ",update); pg(stdout,outstr);
pg(stdout,"the weight update algorithm; {Ccdpq} h au\n");
sprintf(outstr,"t %4.3f ",unscale(toler)); pg(stdout,outstr);
pg(stdout,"tolerance/unit for successful learning; (0..1)\n");
sprintf(outstr,"\nf O %c ",offby1); pg(stdout,outstr);
pg(stdout,"allows out-of-date statistics to print; {+-}\n");
sprintf(outstr,"f u %c ",up_to_date_stats); pg(stdout,outstr);
pg(stdout,"compute up-to-date statistics; {+-}\n");
pg(stdout,"\n");
return;
case 'C':
pg(stdout,"\nScreen Includes Information and Parameters on:\n\n");
pg(stdout," A algorithm parameters and tolerance\n");
pg(stdout," C this listing of major command groups\n");
#ifndef SYMMETRIC
pg(stdout," D delta-bar-delta parameters\n");
#endif
pg(stdout," F formats: patterns, output, paging, copying screen i/o\n");
pg(stdout," G gradient descent (plain backpropagation)\n");
pg(stdout," M miscellaneous commands: shell escape, seed values, clear,\n");
pg(stdout," clear and initialize, quit, save almost everything\n");
pg(stdout," N making a network, listing network unit values\n");
pg(stdout," P pattern commands: reading patterns, testing patterns,\n");
#ifndef SYMMETRIC
pg(stdout," Q quickprop parameters\n");
#endif
pg(stdout," T a short tutorial\n");
pg(stdout," W weight commands: listing, saving, restoring, set bias unit weights\n");
pg(stdout," ? a compact listing of everything\n");
pg(stdout,"\n");
return;
#ifndef SYMMETRIC
case 'D':
pg(stdout,"\nThe Delta-Bar-Delta Paramters (d)\n\n");
sprintf(outstr,"d d %4.2f ",unscale(decay)); pg(stdout,outstr);
pg(stdout,"decay rate for each eta; (0..1)\n");
sprintf(outstr,"d e %5.3f ",unscale(dbdeta)); pg(stdout,outstr);
pg(stdout,"initial eta for each weight; (0..inf)\n");
sprintf(outstr,"d k %6.4f ",unscale(kappa)); pg(stdout,outstr);
pg(stdout,"kappa, the eta increment; (0..inf)\n");
sprintf(outstr,"d m %6.3f ",unscale(etamax)); pg(stdout,outstr);
pg(stdout,"maximum value for eta; (0..inf)\n");
sprintf(outstr,"d t %3.1f ",unscale(theta1)); pg(stdout,outstr);
pg(stdout,"the theta parameter; (0..1)\n");
pg(stdout,"\na u d use this to get the delta-bar-delta update method\n");
pg(stdout,"\n");
return;
#endif
case 'F':
pg(stdout,"\nThe Format Command (f)\n\n");
sprintf(outstr,"f b %c ",ringbell); pg(stdout,outstr);
pg(stdout,"ring the bell when training is finished; {+-}\n");
sprintf(outstr,"f c %c ",copyflag); pg(stdout,outstr);
pg(stdout,"make a copy of screen i/o on the file copy; {+-}\n");
sprintf(outstr,"f e %c ",echo); pg(stdout,outstr);
pg(stdout,"echo input; {+-}\n");
sprintf(outstr,"f i %c ",informat); pg(stdout,outstr);
pg(stdout,"format for reading input and output patterns; {cr} h fi\n");
sprintf(outstr,"f O %c ",offby1); pg(stdout,outstr);
pg(stdout,"give off by 1 statistics for training set; {+-}\n");
sprintf(outstr,"f o %c ",outformat); pg(stdout,outstr);
pg(stdout,"format for outputing network's unit values; {acer} h fo\n");
sprintf(outstr,"f P %2d ",pagesize); pg(stdout,outstr);
pg(stdout,"lines per page; 0 = no paging; [0..inf]\n");
sprintf(outstr,"f p %c ",probtype); pg(stdout,outstr);
pg(stdout,"problem type; {cg} h fp\n");
sprintf(outstr,"f R %c ",runningflag); pg(stdout,outstr);
pg(stdout,"print the \"running . . .\" message; {+-}\n");
sprintf(outstr,"f s %c ",summary); pg(stdout,outstr);
pg(stdout,"summarize learning status while running; {+-}\n");
sprintf(outstr,"f u %c ",up_to_date_stats); pg(stdout,outstr);
pg(stdout,"get up-to-date status of training patterns; {+-}\n");
sprintf(outstr,"f x %5.2f ",unknown); pg(stdout,outstr);
pg(stdout,"the value of x in patterns\n");
pg(stdout,"f B ");
{int i;
for (i=1;i<=MAXFORMAT-1;i++)
{sprintf(outstr," %1d",format[i]); pg(stdout,outstr);};};
pg(stdout,"\n ");
pg(stdout," h fB\n");
pg(stdout,"\n");
return;
case 'G':
pg(stdout,"\nGradient Descent (Plain Backpropagation)\n\n");
sprintf(outstr,"e %8.5f %8.5f ",unscale(eta),unscale(eta2));pg(stdout,outstr);
pg(stdout,"eta for weights into the output layer is");
sprintf(outstr,"%8.5f\n",unscale(eta)); pg(stdout,outstr);
pg(stdout," eta for weights into the hidden layer(s) is");
sprintf(outstr,"%8.5f\n",unscale(eta2)); pg(stdout,outstr);
pg(stdout,"e sets both etas to \n\n");
sprintf(outstr,"a %4.2f ",unscale(alpha)); pg(stdout,outstr);
pg(stdout,"the momentum parameter, alpha, for all layers; [0..1)\n\n");
pg(stdout,"a u C use this for the right continuous update method\n");
pg(stdout,"a u c use this for the wrong continuous update method\n");
pg(stdout,"a u p use this for the periodic update method\n");
pg(stdout,"\n");
return;
case 'M':
pg(stdout,"\nMiscellaneous Commands\n\n");
if (sysstr[0] != '\0')
{pg(stdout,"! "); pg(stdout,sysstr); pg(stdout,"\n");};
pg(stdout,"! pass to the operating system\n\n");
pg(stdout,"q q by itself quits the program\n\n");
pg(stdout,"c clear the network weights\n");
pg(stdout,"ci same as c except the weights are initialized to\n");
sprintf(outstr," between -%4.2f ",unscale(initrange));
pg(stdout,outstr);
sprintf(outstr,"and %4.2f\n",unscale(initrange)); pg(stdout,outstr);
pg(stdout,"ci same as ci except the weights are initialized to\n");
pg(stdout," between - and + \n\n");
sprintf(outstr,"r run %d iterations",maxiter); pg(stdout,outstr);
pg(stdout," and print a summary every\n");
sprintf(outstr," %d iterations\n",printrate); pg(stdout,outstr);
pg(stdout,"^R same as r\n");
pg(stdout,"r run iterations and print a summary every\n");
pg(stdout," iterations\n");
sprintf(outstr,"s %5d",seed); pg(stdout,outstr);
sprintf(outstr," random number seed: %1d\n",seed); pg(stdout,outstr);
pg(stdout,"\nse save everything to \n");
pg(stdout,"\n");
return;
case 'N':
pg(stdout,"\nNetwork Information\n\n");
printnetsize(stdout);
pg(stdout,"\n");
sprintf(outstr," total weights: %1d\n",wttotal);
pg(stdout,outstr);
pg(stdout,"l print the unit values in layer \n\n");
return;
case 'P':
pg(stdout,"\nPattern Related Commands\n\n");
pg(stdout,"f p g the problem type; {gc} h fp\n");
pg(stdout,"f i r format to input patterns; {cr} h fi\n");
pg(stdout,"f o r format to output network values; {acer} h fo\n\n");
pg(stdout,"rt {patterns} reads the patterns between { and }\n");
pg(stdout,"rt read training patterns from \n");
pg(stdout,"rx read more training patterns from \n");
pg(stdout,"tf test file is \n\n");
pg(stdout,"p list all training set pattern values\n");
pg(stdout,"pa same as p\n");
pg(stdout,"p evaluate the training pattern\n");
pg(stdout,"p0 summarize training pattern learning\n\n");
pg(stdout,"t list all test set pattern values\n");
pg(stdout,"ta same as t\n");
pg(stdout,"tr test recurrent patterns h tr\n");
pg(stdout,"trp test recurrent patterns and print results h trp\n");
pg(stdout,"t evaluate the test pattern\n");
pg(stdout,"t0 summarize test pattern learning\n\n");
pg(stdout,"o prints the target for training pattern \n\n");
printstats(stdout,TRAIN,1,s);
if (s[TOL][TEST].npats > 0) printstats(stdout,TEST,1,s);
pg(stdout,"\n");
return;
case 'Q':
pg(stdout,"\nThe Quickprop Parameters (qp)\n\n");
pg(stdout,"qp d sets quickprop weight decay to in all layers\n");
sprintf(outstr,"qp dh %8.6f ",unscale(qpdecayh)); pg(stdout,outstr);
pg(stdout,"quickprop decay for the hidden layer weights; [0..1)\n");
sprintf(outstr,"qp do %8.6f ",unscale(qpdecayo)); pg(stdout,outstr);
pg(stdout,"quickprop decay for the output layer weights; [0..1)\n");
sprintf(outstr,"qp e %6.4f ",unscale(qpeta)); pg(stdout,outstr);
pg(stdout,"quickprop eta; (0..inf)\n");
sprintf(outstr,"qp m %4.2f ",unscale(mu)); pg(stdout,outstr);
pg(stdout,"quickprop acceleration (mu); (1..inf)\n");
sprintf(outstr,"qp n %5.3f ",unscale(qpnoise)); pg(stdout,outstr);
pg(stdout,"quickprop noise (ibp only); [0..inf)\n");
sprintf(outstr,"qp s %c ",qpslope); pg(stdout,outstr);
pg(stdout,"include or exclude extra slope term; {+-}\n");
pg(stdout,"\na u q use this to set the quickprop update method\n");
pg(stdout,"\n");
return;
case 'T':
pg(stdout,"\nA Tutorial\n\n");
pg(stdout,"The following topics are designed to be read in the order listed.\n\n");
pg(stdout,"To get help on a topic type the code on the right at the prompt.\n\n");
pg(stdout,"Understanding the Menus h1\n");
pg(stdout,"Formatting Data for a Classification Problem h2\n");
pg(stdout,"Formatting Data for Function Approximation h3\n");
pg(stdout,"Formatting Data for a Recurrent Problem h4\n");
pg(stdout,"Making a Network for Classification or Function Approximation h5\n");
pg(stdout,"Making a Recurrent Network h6\n");
pg(stdout,"Reading the Data h7\n");
pg(stdout,"Setting Algorithms and Parameters h8\n");
pg(stdout,"Running the Program h9\n");
pg(stdout,"Saving Almost Everything h10\n");
pg(stdout,"To Quit the Program h11\n\n");
return;
case 'W':
pg(stdout,"\nWeights Related Commands\n\n");
pg(stdout,"rw reads weights from the file "); pg(stdout,wtfilename);
pg(stdout,"\n");
pg(stdout,"sw saves weights to the file "); pg(stdout,wtfilename);
pg(stdout,"\n");
pg(stdout,"rw reads weights from \n");
pg(stdout,"sw save weights to \n");
sprintf(outstr," last save at: %1d\n\n",lastsave);
pg(stdout,outstr);
pg(stdout,"w list weights leading into this unit\n\n");
if (biasset == 1)
{
sprintf(outstr,"sb %5.2f ",unscale(stdthresh)); pg(stdout,outstr);
pg(stdout,"bias units set to this value\n\n");
}
else pg(stdout,"sb set bias weights to \n\n");
printnetsize(stdout);
pg(stdout,"\n");
sprintf(outstr," total weights: %1d\n",wttotal);
pg(stdout,outstr);
#ifdef INTEGER
if (wtlimithit == 1)
pg(stdout,"\n >>>>> WEIGHT LIMIT HIT <<<<<\n");
#endif
pg(stdout,"\n");
return;
default: pg(stdout,"not a screen item\n");
return;
}; /* end switch */
}
void help()
{
int ch2;
pg(stdout,"\n");
do ch2 = readch(); while (ch2 == ' ' && ch2 != '\n');
switch(ch2) {
default: menus('C'); return;
case '1':
ch2 = readch();
switch(ch2) {
case '0':
pg(stdout,"\n");
pg(stdout,"It is possible to use the program by typing in all the commands at the\n");
pg(stdout,"keyboard yet it is more convenient to have the basic set up commands for\n");
pg(stdout,"a particular problem in a file, have the program read the file and then\n");
pg(stdout,"have it take commands from the keyboard. So if you have a file named\n");
pg(stdout,"xor set up you can start the program with:\n");
pg(stdout,"\n");
pg(stdout,"bp xor\n");
pg(stdout,"\n");
pg(stdout,"After working with the problem you may reset many parameters. To save\n");
pg(stdout,"the current set of parameters and weights (but not the patterns which\n");
pg(stdout,"are normally in files of their own) use the save everything command,\n");
pg(stdout,"`se'. So to save the current state of the program to a file called,\n");
pg(stdout,"say, new, do:\n");
pg(stdout,"\n");
pg(stdout,"se new\n");
pg(stdout,"\n");
pg(stdout,"The file new will be virtually identical to the listing you get with\n");
pg(stdout,"the `?' command. Later on you can restart the problem with:\n");
pg(stdout,"\n");
pg(stdout,"bp new\n");
pg(stdout,"\n");
return;
case '1':
pg(stdout,"In DOS and UNIX type `q' at the command line prompt.\n\n");
pg(stdout,"In DOS you can hit the escape key to stop a training run.\n\n");
pg(stdout,"In DOS and UNIX you can hit ctrl-C to stop anything and get to the\n");
pg(stdout,"command prompt. When used in a DOS window under Windows this may\n");
pg(stdout,"produce an error message as well as stopping the program.\n\n");
return;
case '\n':
bufferptr = bufferptr - 1;
pg(stdout,"Understanding the Menus\n\n");
pg(stdout,"First, this program includes a paging algorithm similar to more. When\n");
pg(stdout,"you get the string:\n");
pg(stdout,"\n");
pg(stdout,"More?\n");
pg(stdout,"\n");
pg(stdout,"at the bottom of the screen you can get one more page by hitting the\n");
pg(stdout,"space bar, one more line by hitting the carriage return, half a page\n");
pg(stdout,"with ctrl-D, a c will continue without paging and in most cases typing\n");
pg(stdout,"a q will stop the paging. There is no scrolling backwards.\n\n");
pg(stdout,"While the program does not use a mouse or windows it does have menus to\n");
pg(stdout,"make it easy to see what the commands are. One typical menu is the F\n");
pg(stdout,"for format menu, so if you type F at the command prompt you get:\n\n");
pg(stdout,"The Format Command (f)\n\n");
pg(stdout,"f b - ring the bell when training is finished; {+-}\n");
pg(stdout,"f c + make a copy of screen i/o on the file copy; {+-}\n");
pg(stdout,"f e - echo input; {+-}\n");
pg(stdout,"f i r format for reading input and output patterns; {cr} h fi\n\n");
pg(stdout,"plus there is more that has been deleted but these four lines show enough.\n");
pg(stdout,"The first column gives the command and the current value of the parameter.\n");
pg(stdout,"In the `f b -' string, the `f' is the general format command that\n");
pg(stdout,"includes many sub-commands. The `b' sub-command controls the ringing\n");
pg(stdout,"of the bell when the program finishes learning. With the `-' it is off.\n");
pg(stdout,"The middle portion of the screen gives the function involved with the\n");
pg(stdout,"command. Characters at the end within { and } list the possible options.\n");
pg(stdout,"For ringing the bell it is on or off, `+' or `-'. In the `f i r' the\n");
pg(stdout,"explanation for c and r within the { and } can be found by typing `h f i'\n");
pg(stdout,"at the normal command prompt. To change the settings you only have to\n");
pg(stdout,"type the command string in the left column but with the new parameter\n");
pg(stdout,"setting.\n\n");
pg(stdout,"In many cases the command parameters are numbers. The range of values\n");
pg(stdout,"that the parameter can take on are given using [, ], (, and ). If the\n");
pg(stdout,"range listed is: [0..1) the [ next to 0 means that the lowest possible\n");
pg(stdout,"value allowed is exactly 0 while the ) indicates that you can get very\n");
pg(stdout,"close to 1 but never exactly 1.\n\n");
pg(stdout,"In some cases the leftmost column will code a possible command parameter\n");
pg(stdout,"using some name within < and >. For instance there are these two\n");
pg(stdout,"examples:\n\n");
pg(stdout,"qp d sets quickprop weight decay to in all layers\n\n");
pg(stdout,"sw save weights to \n");
pg(stdout,"\n");
pg(stdout,"In the first case it means that to set the quickprop decay in all layers\n");
pg(stdout,"to some value you type `qp d' and some real number as in:\n\n");
pg(stdout,"qp d 0.0001\n\n");
pg(stdout,"In the second example the command means save the weight to some filename\n");
pg(stdout,"so type the name in place of `'.\n\n");
return;
default: pg(stdout,"not a help item\n\n");
return;
}; /* end the inner switch */
case '2':
pg(stdout,"The normal way to operate this program is to have the training data\n");
pg(stdout,"in one file and if there is test set data it should be in another file.\n\n");
pg(stdout,"For a plain classification program, with say four inputs and 3 possible\n");
pg(stdout,"classes the data file will look like:\n\n");
pg(stdout,"0.4 0.3 0.33 0.21 1 * this is a class 1 pattern\n");
pg(stdout,"0.55 0.32 -0.09 0.20 2 * this is a class 2 pattern\n");
pg(stdout,"0.11 0.23 -0.97 0.45 3 * this is a class 3 pattern\n\n");
pg(stdout,"where the first four numbers are the input and the last number is the\n");
pg(stdout,"class number. If there are a large number of inputs you can use more\n");
pg(stdout,"than one line for each pattern but you should start every new pattern\n");
pg(stdout,"on a new line. The asterisk at the end of the line begins a comment.\n\n");
pg(stdout,"It is also possible to type the data in as commands but this is\n");
pg(stdout,"generally not a good idea unless you have a very small data set\n");
pg(stdout,"because you will probably make many mistakes when typing the data\n");
pg(stdout,"in.\n\n");
return;
case '3':
pg(stdout,"The normal way to operate this program is to have the training data\n");
pg(stdout,"in one file and if there is test set data it should be in another file.\n\n");
pg(stdout,"For a function approximation program with say five inputs and 1 output\n");
pg(stdout,"the data should look like:\n\n");
pg(stdout," -1.588 -1.650 0.365 0.188 0.962 -1.543\n");
pg(stdout," -1.182 -0.926 0.992 0.188 1.140 -1.372\n");
pg(stdout," -2.650 -1.650 3.501 0.188 -0.566 -1.201\n\n");
pg(stdout,"where the first five numbers are the input and the last number is the\n");
pg(stdout,"answer. If there are a large number of inputs you can use more\n");
pg(stdout,"than one line for each pattern but you should start every new pattern\n");
pg(stdout,"on a new line.\n\n");
pg(stdout,"It is also possible to type the data in as commands but this is\n");
pg(stdout,"generally not a good idea unless you have a very small data set because\n");
pg(stdout,"you will probably make many mistakes when typing the data in.\n\n");
return;
case '4':
pg(stdout,"The normal way to operate this program is to have the training data\n");
pg(stdout,"in one file and if there is test set data it should be in another file.\n\n");
pg(stdout,"For a recurrent network problem, with say four inputs and 4 possible\n");
pg(stdout,"outputs the data file will look like:\n\n");
pg(stdout,"1 0 0 0 H 0 0 1 0\n");
pg(stdout,"0 0 1 0 H 0 1 0 0\n");
pg(stdout,"0 1 0 0 H 0 0 1 0\n");
pg(stdout,"0 0 1 0 H 0 0 0 1\n\n");
pg(stdout,"where the first four numbers are the input, the H stands for the values\n");
pg(stdout,"of the hidden layer units that are copied down to the input and the last\n");
pg(stdout,"four numbers are the output. If there are a large number of inputs you\n");
pg(stdout,"can use more than one line for each pattern but you should start every\n");
pg(stdout,"new pattern on a new line.\n\n");
pg(stdout,"It is also possible to type the data in as commands but this is\n");
pg(stdout,"generally not a good idea unless you have a very small data set\n");
pg(stdout,"because you will probably make many mistakes when typing the data in.\n\n");
return;
case '5':
pg(stdout,"The command to type in to make a network with four inputs, three\n");
pg(stdout,"hidden layer units and two output units is:\n\n");
pg(stdout,"m 4 3 2\n\n");
pg(stdout,"In many cases adding extra connections from the input units to the\n");
pg(stdout,"output units will produce faster training. If you wanted to use the\n");
pg(stdout,"extra connections type in:\n\n");
pg(stdout,"m 4 3 2 x\n\n");
pg(stdout,"NOTE: there is no way to know ahead of time how many hidden units will\n");
pg(stdout,"be needed or if hidden units will be needed at all.\n\n");
pg(stdout,"NOTE: when patterns are read in they are attached to the network\n");
pg(stdout,"structure so if you make a different size network, such as a 4-5-2\n");
pg(stdout,"network after the patterns are read in the patterns will be lost and\n");
pg(stdout,"you will have to read them in again.\n\n");
return;
case '6':
pg(stdout,"The command to type in to make a recurrent network with four normal\n");
pg(stdout,"input units and three more input units that have values copied from\n");
pg(stdout,"the three hidden layer units and with two output units is:\n\n");
pg(stdout,"m 4+3 3 2\n\n");
pg(stdout,"The 3 in the `4+3' portion must be the same value as the 3 following it.\n\n");
return;
case '7':
pg(stdout,"If you're doing a classification type problem it is important to first\n");
pg(stdout,"let the program know that using the `f' (format) command so the last\n");
pg(stdout,"number can be interpreted as the class number, use:\n\n");
pg(stdout,"f p c * the problem type is classification\n\n");
pg(stdout,"If you're doing a function approximation type of problem, do nothing\n");
pg(stdout,"since the default setting (g, for general) will work.\n\n");
pg(stdout,"To read in the training set data from some file called, say train is:\n\n");
pg(stdout,"rt train * rt is for read training\n\n\n");
pg(stdout,"To read in any test set data from some file called, say, test is:\n\n");
pg(stdout,"tf test * tf is for test file\n\n\n");
pg(stdout,"For other ways to read in data see the manual.\n\n");
return;
case '8':
pg(stdout,"There are many algorithms that can be tried and there are many\n");
pg(stdout,"parameters for each algorithm that can be varied, some algorithms and\n");
pg(stdout,"values produce faster training while others may produce better\n");
pg(stdout,"generalization. So far there is no way to know ahead of time which\n");
pg(stdout,"algorithms and values are best. The fastest training algorithm in this\n");
pg(stdout,"program is quickprop. To get fairly good results set the quickprop eta\n");
pg(stdout,"parameter to about 1 / n where n is the number of patterns in the\n");
pg(stdout,"training set. So if n = 100 type in:\n\n");
pg(stdout,"qp e 0.01 * sets the quickprop eta to 0.01\n\n");
pg(stdout,"and set the algorithm to use to quickprop with the algorithm command:\n\n");
pg(stdout,"a uq * sets the update algorithm to quickprop.\n\n");
pg(stdout,"This will probably work well (NO GUARANTEE) with the other default\n");
pg(stdout,"parameters in the program.\n\n");
pg(stdout,"If you need outputs beyond the range of 0 to 1 use the algorithm\n");
pg(stdout,"command to make the output layer linear:\n\n");
pg(stdout,"a aol * activation function for the output layer is linear\n\n");
return;
case '9':
pg(stdout,"\n");
pg(stdout,"Normally you want to initialize the weights in the network with small random\n");
pg(stdout,"values. This is done with the clear and initialize command, type in:\n");
pg(stdout,"\n");
pg(stdout,"ci * ci for clear and initialize\n");
pg(stdout,"\n");
pg(stdout,"Having done that you can run the training program by typing `r' and a\n");
pg(stdout,"carriage return or by typing ctrl-R. Doing this applies the training\n");
pg(stdout,"algorithm for up to 100 passes through the training set data and lists\n");
pg(stdout,"the status of the training set and the test set if it exists. For the\n");
pg(stdout,"sonar data included in the sample data the listing will look like:\n");
pg(stdout,"\n");
pg(stdout," 10 49.04 % 49.04 % 0.47063 62.50 % 62.50 % 0.38221 \n");
pg(stdout," 20 70.19 % 73.08 % 0.38548 77.88 % 77.88 % 0.38063 \n");
pg(stdout," 30 76.92 % 76.92 % 0.34943 77.88 % 80.77 % 0.33282 \n");
pg(stdout,"\n");
pg(stdout,"The first column is the iteration number, the second column gives the\n");
pg(stdout,"percentage of training set patterns right based on the tolerance the\n");
pg(stdout,"third column gives the percentage right based on the maximum value, the\n");
pg(stdout,"fourth column gives the abs (not RMS!) error. The fifth column is the\n");
pg(stdout,"percentage of test set patterns right based on the tolerance, the sixth\n");
pg(stdout,"column gives the percentage right based on maximum value and the last\n");
pg(stdout,"column gives the abs error.\n");
pg(stdout,"\n");
return;
case 'a':
do ch2 = readch(); while (ch2 == ' ');
if (ch2 == 'd')
{
pg(stdout,"a d c uses the original (correct) derivative.\n\n");
pg(stdout,"a d d uses the differential step derivative in the output layer.\n");
pg(stdout,"a d f uses Fahlman's derivative in the output layer.\n");
pg(stdout,"a d o uses the original (correct) derivative.\n\n");
}
else if (ch2 == 'a')
{
pg(stdout,"a a sets every activation function to .\n");
pg(stdout,"a ah sets the hidden layer activation function to .\n");
pg(stdout,"a ao sets the output layer activation function to ,\n");
pg(stdout," can be any of the following:\n\n");
pg(stdout," Function Range\n\n");
pg(stdout," l linear function, x (-inf..+inf)\n");
pg(stdout," s standard sigmoid, 1 / (1 + exp(-x)) (0..+1)\n");
}
else if (ch2 == 'u')
{
pg(stdout,"a u C gives the \"right\" continuous update method.\n");
pg(stdout,"a u c gives the \"wrong\" continuous update method.\n");
#ifndef SYMMETRIC
pg(stdout,"a u d gives the delta-bar-delta update method.\n");
#endif
pg(stdout,"a u p gives the periodic update method.\n");
#ifndef SYMMETRIC
pg(stdout,"a u q gives the quickprop update method.\n");
#endif
}
else texterror(); /* end of the 'a' case */
break;
case 'f':
do ch2 = readch(); while (ch2 == ' ');
if (ch2 == 'B')
{
pg(stdout,"B ... ... puts a carriage return\n");
pg(stdout," after each values when the output format is real\n");
pg(stdout," and inserts a blank after each value if the\n");
pg(stdout," format is condensed.\n\n");
}
else if (ch2 == 'i')
{
pg(stdout,"i c will read pattern values using compressed format.\n");
pg(stdout,"i r will read pattern values as reals.\n\n");
}
else if (ch2 == 'o')
{
pg(stdout,"o a will write node values as analog compressed.\n");
pg(stdout,"o c will write node values as compressed.\n");
pg(stdout,"o e will write node values with e notation.\n");
pg(stdout,"o r will write node values as real.\n\n");
}
else if (ch2 == 'p')
{
pg(stdout,"p c will read patterns in the classification format.\n");
pg(stdout,"p g will accept general patterns.\n\n");
}
else texterror();
break;
case 't':
do ch2 = readch(); while (ch2 == ' ');
if (ch2 == 'r')
{
pg(stdout,"tr in a recurrent network takes each training set pattern\n");
pg(stdout," and its - 1 following patterns and predicts the\n");
pg(stdout," + 1st pattern\n");
pg(stdout,"trp does the same and prints the predicted patterns\n");
}
else texterror();
break;
}; /* end switch */
pg(stdout,"\n");
}