v14i087: Fast Backpropagation Part 4 of 4
Donald Tveter
drt at chinet.chi.il.us
Sun Sep 16 10:58:46 AEST 1990
Posting-number: Volume 14, Issue 87
Submitted-by: Donald Tveter <drt at chinet.chi.il.us>
Archive-name: back-prop/part04
#! /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 4 (of 4)."
# Contents: int.c real.c misc.c
# Wrapped by drt at chinet on Fri Aug 31 08:18:36 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'int.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'int.c'\"
else
echo shar: Extracting \"'int.c'\" \(14277 characters\)
sed "s/^X//" >'int.c' <<'END_OF_FILE'
X/* *********************************************************** */
X/* file int.c: Contains the network evaluation and weight */
X/* adjustment procedures for the integer versions */
X/* bp and sbp. */
X/* */
X/* Copyright (c) 1990 by Donald R. Tveter */
X/* */
X/* The code here has been optimized for use with the Motorola */
X/* MC 68010 processor and version 3.5 of the UNIX (tm) PC */
X/* C compiler where UNIX is a trademark of Bell Laboratories. */
X/* *********************************************************** */
X
X#include "ibp.h"
X#include <stdio.h>
X
Xextern WTTYPE alpha;
Xextern char backprop;
Xextern WTTYPE D;
Xextern WTTYPE decay;
Xextern char deriv;
Xextern WTTYPE eta;
Xextern WTTYPE eta2;
Xextern WTTYPE etamax;
Xextern WTTYPE kappa;
Xextern LAYER *last;
Xextern LAYER *start;
Xextern WTTYPE theta1;
Xextern WTTYPE theta2;
Xextern WTTYPE toler;
Xextern int totaldiff;
Xextern char update;
X
Xvoid forward() /* computes unit activations */
X{
X register WTNODE *w;
X register UNIT *u;
X register UNIT *predu;
X LAYER *layer;
X register int sum;
X register int x;
X register short fract;
X register short val;
X register int intpart;
X
X layer = start->next;
X while (layer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X sum = 0;
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X predu = (UNIT *) w->backunit;
X#ifdef SMART
X# ifdef SYMMETRIC
X sum = sum + (*(w->weight) * predu->oj) / 1024;
X# else
X sum = sum + (w->weight * predu->oj) / 1024;
X# endif
X#else
X# ifdef SYMMETRIC
X x = (*(w->weight) * predu->oj);
X# else
X x = w->weight * predu->oj;
X# endif
X if (x >= 0) sum = sum + (x >> 10);
X else sum = sum - ( (-x) >> 10);
X#endif
X w = w->next;
X };
X sum = (D * sum) / 1024;
X if (sum > 0) x = sum; else x = -sum;
X intpart = x >> 10;
X fract = x - (intpart << 10);
X switch (intpart)
X {
X case 0: val = 512 + ((237 * fract) >> 10); /* 0 <= x < 1 */
X break;
X case 1: val = 748 + ((153 * fract) >> 10); /* 1 <= x < 2 */
X break;
X case 2: val = 901 + ((73 * fract) >> 10); /* 2 <= x < 3 */
X break;
X case 3:
X case 4: val = 976 + (((x - 3072) * 20) >> 10); /* 3 <= x < 5 */
X break;
X default: val = 1024; /* x >= 5 */
X };
X if (sum < 0) u->oj = 1024 - val; else u->oj = val;
X u = u->next;
X };
X layer = layer->next;
X };
X};
X
Xshort backoutput() /* computes weight changes from the output layer */
X{
X register short deltaj;
X register int temp;
X register short temp2;
X register short temp3;
X register short adiff;
X register UNIT *bunit;
X register WTNODE *w;
X register UNIT *u;
X register PATNODE *t;
X register short notclose;
X
X notclose = last->unitcount;
X u = (UNIT *) last->units;
X t = (PATNODE *) last->currentpat->pats;
X while (u != NULL)
X {
X temp3 = u->oj;
X temp2 = t->val - temp3;
X if (temp2 > 0) adiff = temp2; else adiff = -temp2;
X if (adiff < toler) notclose = notclose - 1;
X totaldiff = totaldiff + adiff;
X if (adiff >= toler || backprop) /* then compute errors */
X {
X if (deriv == 'd') /* diff. step size method */
X deltaj = temp2;
X else if (deriv == 'f') /* Fahlman's derivative */
X {
X temp = temp2 * (104448 + temp3 * ((short)(1024 - temp3)));
X if (temp > 0) deltaj = (temp + 524288) >> 20;
X else deltaj = -((524288 - temp) >> 20);
X }
X else /* the derivative in the original formula */
X {
X temp = temp2 * (temp3 * ((short)(1024 - temp3)));
X if (temp > 0) deltaj = (temp + 524288) >> 20;
X else deltaj = -((524288 - temp) >> 20);
X }
X w = (WTNODE *) u->wtlist;
X#ifdef SYMMETRIC
X while (w->next != NULL) /* skips threshold unit at end */
X#else
X while (w != NULL)
X#endif
X {
X bunit = (UNIT *) w->backunit;
X#ifdef SYMMETRIC
X *(w->total) = *(w->total) + deltaj * bunit->oj;
X#else
X w->total = w->total + deltaj * bunit->oj;
X if (bunit->layernumber > 1)
X bunit->error = bunit->error + deltaj * w->weight;
X#endif
X w = w->next;
X }
X };
X u = u->next;
X t = t->next;
X };
X return(notclose);
X}
X
X#ifndef SYMMETRIC
X
Xvoid backinner() /* Computes slopes and passes back */
X{ /* errors from hidden layers. */
X register short deltaj;
X register int temp;
X register short temp3;
X register UNIT *bunit;
X register WTNODE *w;
X register UNIT *u;
X LAYER *layer;
X
X layer = last->backlayer;
X while (layer->backlayer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X temp3 = u->oj;
X if (deriv == 'f') /* Fahlman's derivative */
X temp = (((short)((temp3*((short)(1024-temp3))+512) >> 10))
X + 102) * u->error;
X else /* either for the original or diff. step size */
X temp = ((short)((temp3*((short)(1024-temp3))+512) >> 10))
X * u->error;
X if (temp > 0) deltaj = (temp + 524288) >> 20;
X else deltaj = -((524288 - temp) >> 20);
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X bunit = (UNIT *) w->backunit;
X w->total = w->total + deltaj * bunit->oj;
X if (bunit->layernumber > 1)
X bunit->error = bunit->error + deltaj * w->weight;
X w = w->next;
X };
X u = u->next;
X };
X layer = layer->backlayer;
X };
X}
X
X#endif
X
Xvoid updatej() /* Jacob's delta-bar-delta method for weight updates */
X{
X register short rkappa;
X register short temp2;
X register short dbarm1;
X register short rdecay;
X register int temp;
X register UNIT *u;
X register WTNODE *w;
X LAYER *layer;
X
X/* w->olddw is used for delta-bar minus 1 */
X
X rkappa = kappa;
X rdecay = decay;
X layer = last;
X while (layer->backlayer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X#ifdef SYMMETRIC
X if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
X {
X if (*(w->total) > 0) temp2 = (*(w->total) + 512) >> 10;
X else temp2 = -((512 - *(w->total)) >> 10);
X dbarm1 = *(w->olddw);
X temp = theta2 * temp2 + theta1 * dbarm1;
X if (temp > 0) *(w->olddw) = (temp + 512) >> 10;
X else *(w->olddw) = -((512 - temp) >> 10);
X if ((temp2 > 0) && (dbarm1 > 0))
X *(w->eta) = *(w->eta) + rkappa;
X else if ((temp2 < 0) && (dbarm1 < 0))
X *(w->eta) = *(w->eta) + rkappa;
X else if ((temp2 > 0) && (dbarm1 < 0))
X *(w->eta) = (*(w->eta) * rdecay) >> 10;
X else if ((temp2 < 0) && (dbarm1 > 0))
X *(w->eta) = (*(w->eta) * rdecay) >> 10;
X if (*(w->eta) > etamax) *(w->eta) = etamax;
X temp = temp2 * *(w->eta);
X if (temp > 0) temp2 = (temp + 512) >> 10;
X else temp2 = -((512 - temp) >> 10);
X *(w->weight) = *(w->weight) + temp2;
X };
X#else
X if (w->total > 0) temp2 = (w->total + 512) >> 10;
X else temp2 = -((512 - w->total) >> 10);
X dbarm1 = w->olddw;
X temp = theta2 * temp2 + theta1 * dbarm1;
X if (temp > 0) w->olddw = (temp + 512) >> 10;
X else w->olddw = -((512 - temp) >> 10);
X if (temp2 > 0 && dbarm1 > 0) w->eta = w->eta + rkappa;
X else if (temp2 < 0 && dbarm1 < 0) w->eta = w->eta + rkappa;
X else if (temp2 > 0 && dbarm1 < 0)
X w->eta = (w->eta * rdecay) >> 10;
X else if (temp2 < 0 && dbarm1 > 0)
X w->eta = (w->eta * rdecay) >> 10;
X if (w->eta > etamax) w->eta = etamax;
X temp = temp2 * w->eta;
X if (temp > 0) temp2 = (temp + 512) >> 10;
X else temp2 = -((512 - temp) >> 10);
X w->weight = w->weight + temp2;
X#endif
X w = w->next;
X };
X u = u->next;
X };
X layer = layer->backlayer;
X };
X}
X
Xvoid updateo() /* update weights for the original method */
X{ /* and the differential step size algorithm */
X register short reta;
X register short ralpha;
X register int temp;
X register UNIT *u;
X register WTNODE *w;
X LAYER *layer;
X
X ralpha = alpha;
X reta = eta;
X layer = last;
X while (layer->backlayer != NULL)
X {
X if (layer != last && update == 'd') reta = eta2;
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X#ifdef SYMMETRIC
X if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
X {
X if (*(w->total) > 0)
X temp = ((*(w->total) + 512) >> 10) * reta
X + ralpha * *(w->olddw);
X else temp = -((512 - *(w->total)) >> 10) * reta
X + ralpha * *(w->olddw);
X if (temp > 0) *(w->olddw) = (temp + 512) >> 10;
X else *(w->olddw) = -((512 - temp) >> 10);
X *(w->weight) = *(w->weight) + *(w->olddw);
X };
X#else
X if (w->total > 0)
X temp = ((w->total + 512) >> 10) * reta + ralpha * w->olddw;
X else
X temp = -((512 - w->total) >> 10) * reta + ralpha * w->olddw;
X if (temp > 0) w->olddw = (temp + 512) >> 10;
X else w->olddw = -((512 - temp) >> 10);
X w->weight = w->weight + w->olddw;
X#endif
X w = w->next;
X };
X u = u->next;
X };
X layer = layer->backlayer;
X };
X}
X
Xshort cbackoutput() /* The continuous update version */
X{ /* of back-propagation */
X register short deltaj;
X register int etadeltaj;
X register int temp;
X register int temp2;
X register short temp3;
X register short adiff;
X register UNIT *bunit;
X register WTNODE *w;
X register UNIT *u;
X register PATNODE *t;
X register short ralpha;
X register short notclose;
X
X ralpha = alpha;
X notclose = last->unitcount;
X u = (UNIT *) last->units;
X t = (PATNODE *) last->currentpat->pats;
X while (u != NULL)
X {
X temp3 = u->oj;
X temp2 = t->val - temp3;
X if (temp2 > 0) adiff = temp2; else adiff = -temp2;
X if (adiff < toler) notclose = notclose - 1;
X totaldiff = totaldiff + adiff;
X if (adiff >= toler || backprop)
X {
X if (deriv == 'd') /* the differential step size method */
X deltaj = temp2;
X else if (deriv == 'f') /* Fahlman's derivative */
X { /* deltaj = (t->val - u->oj) * [0.1 + u->oj*(1.0 - u->oj)] */
X temp = temp2 * (104448 + temp3 * ((short)(1024 - temp3)));
X if(temp > 0) deltaj = (temp + 524288) >> 20;
X else deltaj = -((524288 - temp) >> 20);
X }
X else /* the original derivative */
X { /* deltaj = (t->val - u->oj) * u->oj * (1.0 - u->oj) */
X temp = temp2 * (temp3 * ((short)(1024 - temp3)));
X if(temp > 0) deltaj = (temp + 524288) >> 20;
X else deltaj = -((524288 - temp) >> 20);
X };
X etadeltaj = deltaj * eta;
X w = (WTNODE *) u->wtlist;
X#ifdef SYMMETRIC
X while (w->next != NULL)
X#else
X while (w != NULL)
X#endif
X { /* get a slope for each weight */
X bunit = (UNIT *) w->backunit;
X temp = etadeltaj * bunit->oj;
X if(temp > 0) temp = (temp + 524288) >> 20;
X else temp = -((524288 - temp) >> 20);
X#ifdef SYMMETRIC
X temp2 = ralpha * *(w->olddw);
X#else
X temp2 = ralpha * w->olddw;
X#endif
X if (temp2 > 0) temp3 = temp + ((temp2 + 512) >> 10);
X else temp3 = temp - ((512 - temp2) >> 10);
X#ifdef SYMMETRIC
X *(w->olddw) = temp3;
X#else
X w->olddw = temp3;
X#endif
X /* w->weight = w->weight + w->olddw */
X#ifdef SYMMETRIC
X temp3 = *(w->weight) + temp3;
X *(w->weight) = temp3;
X#else
X temp3 = w->weight + temp3;
X w->weight = temp3;
X if (bunit->layernumber > 1)
X bunit->error = bunit->error + deltaj * temp3;
X#endif
X w = w->next;
X }
X }
X u = u->next;
X t = t->next;
X }
X return(notclose);
X}
X
X#ifndef SYMMETRIC
X
Xvoid cbackinner() /* Same as cbackoutput, except errors are */
X{ /* calculated differently */
X register short deltaj;
X register int etadeltaj;
X register int temp;
X register int temp2;
X register short temp3;
X register short reta;
X register short ralpha;
X register UNIT *bunit;
X register WTNODE *w;
X register UNIT *u;
X LAYER *layer;
X
X if (update == 'C') reta = eta2; else reta = eta;
X ralpha = alpha;
X layer = last->backlayer;
X while (layer->backlayer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X temp3 = u->oj;
X if (deriv == 'f') /* Fahlman's derivative */
X temp = (((temp3 * ((short)(1024 - temp3)) + 512) >> 10) + 102)
X * u->error;
X else /* diff. step size and original derivative */
X temp = ((temp3 * ((short)(1024 - temp3)) + 512) >> 10)
X * u->error;
X if (temp > 0) deltaj = (temp + 524288) >> 20;
X else deltaj = -((524288 - temp) >> 20);
X etadeltaj = reta * deltaj;
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X bunit = (UNIT *) w->backunit;
X temp = etadeltaj * bunit->oj;
X if (temp > 0) temp = (temp + 524288) >> 20;
X else temp = -((524288 - temp) >> 20);
X temp2 = ralpha * w->olddw;
X if (temp2 > 0) temp3 = temp + ((temp2 + 512) >> 10);
X else temp3 = temp - ((512 - temp2) >> 10);
X w->olddw = temp3;
X temp3 = w->weight + temp3;
X w->weight = temp3;
X if (bunit->layernumber > 1)
X bunit->error = bunit->error + deltaj * temp3;
X w = w->next;
X };
X u = u->next;
X };
X layer = layer->backlayer;
X };
X}
X
X#endif
END_OF_FILE
if test 14277 -ne `wc -c <'int.c'`; then
echo shar: \"'int.c'\" unpacked with wrong size!
fi
# end of 'int.c'
fi
if test -f 'real.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'real.c'\"
else
echo shar: Extracting \"'real.c'\" \(10454 characters\)
sed "s/^X//" >'real.c' <<'END_OF_FILE'
X/* *********************************************************** */
X/* file real.c: contains the network evaluation and weight */
X/* adjustment procedures for the 64-bit floating point program */
X/* */
X/* Copyright (c) 1990 by Donald R. Tveter */
X/* */
X/* *********************************************************** */
X
X#include "rbp.h"
X#include <stdio.h>
X
Xextern char activation;
Xextern double alpha;
Xextern char backprop;
Xextern double D;
Xextern double decay;
Xextern char deriv;
Xextern double eta;
Xextern double eta2;
Xextern double etamax;
Xextern double kappa;
Xextern LAYER *last;
Xextern LAYER *start;
Xextern double theta1;
Xextern double theta2;
Xextern double toler;
Xextern double totaldiff;
Xextern char update;
X
Xextern double exp(); /* a built-in function */
X
Xvoid forward() /* computes unit activations */
X{
X UNIT *u, *predu;
X LAYER *layer;
X WTNODE *b;
X double fract, x, val;
X double sum;
X int intpart;
X
X layer = start->next;
X while (layer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X sum = 0.0;
X b = (WTNODE *) u->wtlist;
X while (b != NULL)
X {
X predu = (UNIT *) b->backunit;
X#ifdef SYMMETRIC
X sum = sum + *(b->weight) * predu->oj;
X#else
X sum = sum + b->weight * predu->oj;
X#endif
X b = b->next;
X };
X sum = sum * D;
X if (activation == 's') u->oj = 1.0 / (1.0 + exp(-sum));
X else
X { /* piecewise linear, the fast way */
X if (sum >= 0.0) x = sum; else x = - sum;
X intpart = x;
X fract = x - intpart;
X switch (intpart)
X {
X case 0: val = 0.5 + 0.231 * fract; /* 0 <= x < 1 */
X break;
X case 1: val = 0.731059 + 0.149738 * fract; /* 1 <= x < 2 */
X break;
X case 2: val = 0.880797 + 0.071777 * fract; /* 2 <= x < 3 */
X break;
X case 3:
X case 4: val = 0.9525741 + (x - 3.0) * 0.02; /* 3 <= x < 5 */
X break;
X default: val = 1.0; /* x >= 5 */
X };
X if (sum < 0.0) u->oj = 1.0 - val; else u->oj = val;
X } /* end of the fast way */
X u = u->next;
X };
X layer = layer->next;
X };
X}
X
Xshort backoutput() /* back propagate errors from the output units */
X{ /* send down errors for any previous layers */
X double deltaj, diff, adiff;
X register UNIT *u, *bunit;
X register WTNODE *w;
X register PATNODE *t;
X register short notclose;
X
X notclose = last->unitcount;
X u = (UNIT *) last->units;
X t = (PATNODE *) last->currentpat->pats;
X while (u != NULL)
X {
X diff = t->val - u->oj;
X if (diff > 0) adiff = diff; else adiff = -diff;
X if (adiff < toler) notclose = notclose - 1;
X totaldiff = totaldiff + adiff;
X if (adiff >= toler || backprop)
X {
X if (deriv == 'd') /* differential step size */
X deltaj = diff;
X else if (deriv == 'f') /* Fahlman's derivative */
X deltaj = diff * (0.1 + u->oj * (1.0 - u->oj));
X else /* the original derivative */
X deltaj = diff * u->oj * (1.0 - u->oj);
X w = (WTNODE *) u->wtlist;
X#ifdef SYMMETRIC
X while (w->next != NULL)
X#else
X while (w != NULL)
X#endif
X {
X bunit = (UNIT *) w->backunit;
X#ifdef SYMMETRIC
X *(w->total) = *(w->total) + deltaj * bunit->oj;
X#else
X w->total = w->total + deltaj * bunit->oj;
X if (bunit->layernumber > 1) /* pass back the error */
X bunit->error = bunit->error + deltaj * w->weight;
X#endif
X w = w->next;
X };
X }
X u = u->next;
X t = t->next;
X }
X return(notclose);
X}
X
X#ifndef SYMMETRIC
X
Xvoid backinner() /* compute weight changes for hidden layers */
X{ /* send down errors for any previous layers */
X LAYER *layer;
X double deltaj;
X register UNIT *bunit;
X register WTNODE *w;
X register UNIT *u;
X
X layer = last->backlayer;
X while (layer->backlayer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X if (deriv == 'f') /* Fahlman's derivative */
X deltaj = (0.1 + u->oj * (1.0 - u->oj)) * u->error;
X else /* original and diff. step size derivative */
X deltaj = (u->oj * (1.0 - u->oj)) * u->error;
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X bunit = (UNIT *) w->backunit;
X w->total = w->total + deltaj * bunit->oj;
X if (bunit->layernumber > 1)
X bunit->error = bunit->error + deltaj * w->weight;
X w = w->next;
X };
X u = u->next;
X };
X layer = layer->backlayer;
X };
X}
X
X#endif
X
Xvoid updatej() /* Jacob's delta-bar-delta method for changing weights */
X{
X register short stotal;
X register short sdbarm1;
X register UNIT *u;
X register WTNODE *w;
X LAYER *layer;
X
X /* w->olddw is used for delta-bar minus 1 */
X
X layer = last;
X while (layer->backlayer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X#ifdef SYMMETRIC
X if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
X {
X if (*(w->total) > 0) stotal = 1;
X else if (*(w->total) < 0) stotal = -1;
X else stotal = 0;
X if (*(w->olddw) > 0) sdbarm1 = 1;
X else if (*(w->olddw) < 0) sdbarm1 = -1;
X else sdbarm1 = 0;
X *(w->olddw) = theta2 * *(w->total) + theta1 * *(w->olddw);
X if ((stotal > 0) && (sdbarm1 > 0))
X *(w->eta) = *(w->eta) + kappa;
X else if ((stotal < 0) && (sdbarm1 < 0))
X *(w->eta) = *(w->eta) + kappa;
X else if ((stotal > 0) && (sdbarm1 < 0))
X *(w->eta) = *(w->eta) * decay;
X else if ((stotal < 0) && (sdbarm1 > 0))
X *(w->eta) = *(w->eta) * decay;
X if (*(w->eta) > etamax) *(w->eta) = etamax;
X *(w->weight) = *(w->weight) + *(w->total) * *(w->eta);
X };
X#else
X if (w->total > 0) stotal = 1;
X else if (w->total < 0) stotal = -1;
X else stotal = 0;
X if (w->olddw > 0) sdbarm1 = 1;
X else if (w->olddw < 0) sdbarm1 = -1;
X else sdbarm1 = 0;
X w->olddw = theta2 * w->total + theta1 * w->olddw;
X if ((stotal > 0) && (sdbarm1 > 0)) w->eta = w->eta + kappa;
X else if ((stotal < 0) && (sdbarm1 < 0)) w->eta = w->eta + kappa;
X else if ((stotal > 0) && (sdbarm1 < 0)) w->eta = w->eta * decay;
X else if ((stotal < 0) && (sdbarm1 > 0)) w->eta = w->eta * decay;
X if (w->eta > etamax) w->eta = etamax;
X w->weight = w->weight + w->total * w->eta;
X#endif
X w = w->next;
X };
X u = u->next;
X };
X layer = layer->backlayer;
X };
X}
X
Xvoid updateo() /* update weights for the original and the */
X{ /* differential step size methods */
X double reta;
X register UNIT *u;
X register WTNODE *w;
X LAYER *layer;
X
X reta = eta;
X layer = last;
X while (layer->backlayer != NULL)
X {
X if (layer != last && update == 'd') reta = eta2;
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X#ifdef SYMMETRIC
X if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
X {
X *(w->olddw) = *(w->total) * reta + alpha * *(w->olddw);
X *(w->weight) = *(w->weight) + *(w->olddw);
X };
X#else
X w->olddw = w->total * reta + alpha * w->olddw;
X w->weight = w->weight + w->olddw;
X#endif
X w = w->next;
X };
X u = u->next;
X };
X layer = layer->backlayer;
X };
X}
X
Xshort cbackoutput() /* backoutput for continuous updates */
X{
X double deltaj, etadeltaj, diff, adiff;
X register UNIT *u, *bunit;
X register WTNODE *b;
X register PATNODE *t;
X register short notclose;
X
X notclose = last->unitcount;
X u = (UNIT *) last->units;
X t = (PATNODE *) last->currentpat->pats;
X while (u != NULL)
X {
X diff = t->val - u->oj;
X if (diff > 0) adiff = diff; else adiff = -diff;
X if (adiff < toler) notclose = notclose - 1;
X totaldiff = totaldiff + adiff;
X if (adiff >= toler || backprop)
X {
X if (deriv == 'd') /* differential step size derivative */
X deltaj = diff;
X else if (deriv == 'f') /* Fahlman's derivative */
X deltaj = diff * (0.1 + u->oj * (1.0 - u->oj));
X else /* the original derivative */
X deltaj = diff * u->oj * (1.0 - u->oj);
X etadeltaj = deltaj * eta;
X b = (WTNODE *) u->wtlist;
X#ifdef SYMMETRIC
X while (b->next != NULL)
X#else
X while (b != NULL)
X#endif
X {
X bunit = (UNIT *) b->backunit;
X#ifdef SYMMETRIC
X *(b->olddw) = etadeltaj * bunit->oj + alpha * *(b->olddw);
X *(b->weight) = *(b->weight) + *(b->olddw);
X#else
X b->olddw = etadeltaj * bunit->oj + alpha * b->olddw;
X b->weight = b->weight + b->olddw;
X if (bunit->layernumber > 1)
X bunit->error = bunit->error + deltaj * b->weight;
X#endif
X b = b->next;
X };
X };
X u = u->next;
X t = t->next;
X }
X return(notclose);
X}
X
X#ifndef SYMMETRIC
X
Xvoid cbackinner() /* backinner for continuous updates */
X{
X LAYER *layer;
X double deltaj, etadeltaj, reta;
X register UNIT *bunit, *u;
X register WTNODE *b;
X
X if (update == 'D') reta = eta2; else reta = eta;
X layer = last->backlayer;
X while (layer->backlayer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X if (deriv == 'f') /* Fahlman's derivative */
X deltaj = (0.1 + u->oj * (1.0 - u->oj)) * u->error;
X else /* the diff. step size and original derivative */
X deltaj = (u->oj * (1.0 - u->oj)) * u->error;
X etadeltaj = reta * deltaj;
X b = (WTNODE *) u->wtlist;
X while (b != NULL)
X {
X bunit = (UNIT *) b->backunit;
X b->olddw = etadeltaj * bunit->oj + alpha * b->olddw;
X b->weight = b->weight + b->olddw;
X if (bunit->layernumber > 1)
X bunit->error = bunit->error + deltaj * b->weight;
X b = b->next;
X };
X u = u->next;
X };
X layer = layer->backlayer;
X };
X}
X#endif
END_OF_FILE
if test 10454 -ne `wc -c <'real.c'`; then
echo shar: \"'real.c'\" unpacked with wrong size!
fi
# end of 'real.c'
fi
if test -f 'misc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'misc.c'\"
else
echo shar: Extracting \"'misc.c'\" \(11006 characters\)
sed "s/^X//" >'misc.c' <<'END_OF_FILE'
X/* **************************************************** */
X/* file misc.c: contains pattern manipulation routines */
X/* and miscellaneous other functions. */
X/* */
X/* Copyright (c) 1990 by Donald R. Tveter */
X/* */
X/* **************************************************** */
X
X#include <stdio.h>
X#ifdef INTEGER
X#include "ibp.h"
X#else
X#include "rbp.h"
X#endif
X
Xextern short backoutput();
Xextern void backinner();
Xextern short cbackoutput();
Xextern void cbackinner();
Xextern WTTYPE rdr();
Xextern WTTYPE readchar();
Xextern void saveweights();
Xextern WTTYPE scale();
Xextern double unscaleint();
Xextern void updatej();
Xextern void updateo();
X
Xextern char backprop;
Xextern FILE *data;
Xextern char datafilename[50];
Xextern UNIT *hlayer;
Xextern UNIT *ilayer;
Xextern char informat;
Xextern UNIT *jlayer;
Xextern UNIT *klayer;
Xextern LAYER *last;
Xextern int lastprint;
Xextern int npats;
Xextern int prevnpats;
Xextern int readerror;
Xextern int saverate;
Xextern int skiprate;
Xextern LAYER *start;
Xextern char summary;
Xextern WTTYPE toler;
X#ifdef INTEGER
Xextern int totaldiff;
X#else
Xextern double totaldiff;
X#endif
Xextern int totaliter;
Xextern int unlearnedpats;
Xextern char update;
Xextern WTTYPE wtlimit;
Xextern char wtlimithit;
Xextern int wttotal;
X
Xvoid nullpatterns() /* dispose of any patterns before reading more */
X{
X PATLIST *pl, *nextpl;
X PATNODE *pn, *nextpn;
X if (start->patstart != NULL)
X {
X pl = start->patstart;
X nextpl = pl->next;
X while (pl != NULL)
X {
X pn = pl->pats;
X nextpn = pn->next;
X while (pn != NULL)
X {
X free(pn);
X pn = nextpn;
X nextpn = pn->next;
X };
X free(pl);
X pl = nextpl;
X nextpl = pl->next;
X };
X pl = last->patstart;
X nextpl = pl->next;
X while (pl != NULL)
X {
X pn = pl->pats;
X nextpn = pn->next;
X while (pn != NULL)
X {
X free(pn);
X pn = nextpn;
X nextpn = pn->next;
X };
X free(pl);
X pl = nextpl;
X nextpl = pl->next;
X };
X };
X start->patstart = NULL;
X last->patstart = NULL;
X npats = 0;
X prevnpats = 0;
X}
X
Xvoid resetpats()
X{
X start->currentpat = NULL;
X last->currentpat = NULL;
X}
X
Xvoid findendofpats(layer) /* purpose is to set all layer->currentpat */
XLAYER *layer; /* fields to end of pattern list so more */
X /* patterns can be added at the end. */
X{
X PATLIST *pl;
X
X pl = (PATLIST *) layer->patstart;
X while (pl->next != NULL) pl = pl->next;
X layer->currentpat = pl;
X}
X
Xint copyhidden(input,hidden,l)
XUNIT *input, **hidden;
Xint l;
X{
X if (hidden == NULL)
X {
X printf("ran out of hidden units in layer %d\n",l);
X return(1);
X }
X input->oj = (*hidden)->oj;
X *hidden = (*hidden)->next;
X return(0);
X}
X
Xvoid nextpat()
X{
X if (start->currentpat == NULL)
X {
X start->currentpat = start->patstart;
X last->currentpat = last->patstart;
X }
X else
X {
X start->currentpat = (start->currentpat)->next;
X last->currentpat = (last->currentpat)->next;
X };
X}
X
Xvoid setonepat() /* sets up patterns on input units */
X{
X register PATNODE *p;
X register UNIT *u;
X register LAYER *innerlayers;
X UNIT *hunit, *iunit, *junit, *kunit;
X PATLIST *pl;
X
X hunit = hlayer;
X iunit = ilayer;
X junit = jlayer;
X kunit = klayer;
X pl = start->currentpat;
X p = (PATNODE *) pl->pats;
X u = (UNIT *) start->units;
X while (p != NULL)
X {
X if (p->val > KCODE) u->oj = p->val;
X else if (p->val == HCODE)
X {if (copyhidden(u,&hunit,2) == 1) return;}
X else if (p->val == ICODE)
X {if (copyhidden(u,&iunit,3) == 1) return;}
X else if (p->val == JCODE)
X {if (copyhidden(u,&junit,4) == 1) return;}
X else if (copyhidden(u,&kunit,5) == 1) return;
X u = u->next;
X p = p->next;
X };
X
X innerlayers = start->next;
X while (innerlayers->next != NULL)
X { /* set errors on the inner layer units to 0 */
X u = (UNIT *) innerlayers->units;
X while (u != NULL)
X {
X u->error = 0;
X u = u->next;
X };
X innerlayers = innerlayers->next;
X };
X}
X
Xvoid limitwts()
X{
X register LAYER *layer;
X register UNIT *u;
X register WTNODE *w;
X
X layer = start->next;
X while (layer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X#ifdef SYMMETRIC
X if (*(w->weight) > wtlimit)
X {
X *(w->weight) = wtlimit;
X wtlimithit = 1;
X }
X else if (*(w->weight) < -wtlimit)
X {
X *(w->weight) = -wtlimit;
X wtlimithit = 1;
X };
X#else
X if (w->weight > wtlimit)
X {
X w->weight = wtlimit;
X wtlimithit = 1;
X }
X else if (w->weight < -wtlimit)
X {
X w->weight = -wtlimit;
X wtlimithit = 1;
X };
X#endif
X w = w->next;
X };
X u = u->next;
X };
X layer = layer->next;
X };
X}
X
X#ifndef SYMMETRIC
X
Xvoid whittle(amount) /* removes weights whose absolute */
XWTTYPE amount; /* value is less than amount */
X{LAYER *layer;
X UNIT *u;
X WTNODE *w, *wprev;
X
X layer = start->next;
X while (layer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X wprev = (WTNODE *) NULL;
X while (w->next != (WTNODE *) NULL)
X {
X if ((w->weight) < amount && (w->weight) > -amount)
X {
X if (wprev == NULL) (WTNODE *) u->wtlist = w->next;
X else (WTNODE *) wprev->next = w->next;
X wttotal = wttotal - 1;
X }
X else wprev = w;
X w = w->next;
X }
X u = u->next;
X }
X layer = layer->next;
X }
X}
X
X#endif
X
Xvoid oneset() /* go through the patterns once and update weights */
X{ int i;
X LAYER *layer;
X register UNIT *u;
X register WTNODE *w;
X short numbernotclose, attempted, passed;
X
Xbegin:
X layer = last; /* make all b->totals = 0 */
X while (layer->backlayer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X#ifdef SYMMETRIC
X *(w->total) = 0;
X#else
X w->total = 0;
X#endif
X w = w->next;
X };
X u = u->next;
X };
X layer = layer->backlayer;
X };
X attempted = 0;
X passed = 0;
X unlearnedpats = npats;
X resetpats();
X for(i=1;i<=npats;i++)
X {
X nextpat();
X if (last->currentpat->bypass <= 0)
X {
X setonepat();
X forward();
X attempted = attempted + 1;
X if (update == 'c' || update == 'C')
X numbernotclose = cbackoutput();
X else numbernotclose = backoutput();
X if (numbernotclose != 0)
X {
X#ifndef SYMMETRIC
X if (update == 'c' || update == 'C') cbackinner();
X else backinner();
X#endif
X }
X else /* this one pattern has been learned */
X {
X passed = passed + 1;
X unlearnedpats = unlearnedpats - 1;
X last->currentpat->bypass = skiprate;
X#ifndef SYMMETRIC
X if (backprop)
X {
X if (update == 'c' || update == 'C') cbackinner();
X else backinner();
X };
X#endif
X }
X }
X else last->currentpat->bypass = last->currentpat->bypass - 1;
X };
X if (unlearnedpats == 0) return;
X if (attempted == passed)
X {
X resetpats();
X for (i=1;i<=npats;i++)
X {
X nextpat();
X last->currentpat->bypass = 0;
X };
X goto begin;
X };
X if (update == 'j') updatej();
X else if (update == 'o' || update == 'd') updateo();
X if (wtlimit != 0) limitwts();
X}
X
Xvoid kick(size,amount) /* give the network a kick */
XWTTYPE size;
XWTTYPE amount;
X{ LAYER *layer;
X UNIT *u;
X WTNODE *w;
X WTTYPE value;
X WTTYPE delta;
X int sign;
X
X layer = start->next;
X while (layer != NULL)
X {
X u = (UNIT *) layer->units;
X while (u != NULL)
X {
X w = (WTNODE *) u->wtlist;
X while (w != NULL)
X {
X#ifdef SYMMETRIC
X value = *(w->weight);
X#else
X value = w->weight;
X#endif
X if (value != 0) sign = 1;
X else if (rand() > 16383) sign = -1;
X else sign = 1;
X delta = (sign * amount * rand()) / 32768;
X if (value >= size) value = value - delta;
X else if (value < -size) value = value + delta;
X#ifdef SYMMETRIC
X if (((UNIT *) w->backunit)->unitnumber != u->unitnumber)
X *(w->weight) = value;
X#else
X w->weight = value;
X#endif
X w = w->next;
X }
X u = u->next;
X }
X layer = layer->next;
X }
X}
X
Xvoid printpats(first,finish,printheader,printerrors,callfromrun)
Xint first,finish,printheader,printerrors,callfromrun;
X{
X int i;
X double err;
X
X if (summary == '+' && callfromrun)
X {
X printf("%6d ",totaliter);
X printf("%6d learned ",npats-unlearnedpats);
X printf("%6d unlearned ",unlearnedpats);
X err = unscaleint(totaldiff) / (npats * last->unitcount);
X printf("%7.5lf error/unit\n",err);
X return;
X };
X lastprint = totaliter;
X if (printheader == 1)
X printf("%d iterations, file = %s\n",totaliter,datafilename);
X resetpats();
X for (i=2;i<=first;i++) nextpat();
X for (i=first;i<=finish;i++)
X {
X nextpat();
X setonepat();
X printf("%3d ",i);
X forward();
X printoutunits(last,printerrors);
X };
X}
X
Xvoid run(n,prpatsrate)
Xint n; /* the number of iterations to run */
Xint prpatsrate; /* rate at which to print output patterns */
X
X{ int i;
X char wtlimitbefore;
X
X printf("running . . .\n");
X for (i=1;i<=n;i++)
X {
X totaldiff = 0;
X wtlimitbefore = wtlimithit;
X oneset();
X totaliter = totaliter + 1;
X if (wtlimitbefore == 0 && wtlimithit == 1)
X printf(">>>>> WEIGHT LIMIT HIT <<<<< at %d\n",totaliter);
X if (unlearnedpats == 0)
X {
X if (update != 'c' && update != 'C') totaliter = totaliter - 1;
X if ((prpatsrate > 0) && (lastprint != totaliter))
X printpats(1,npats,1,1,1);
X printf("patterns learned to within %4.2lf",unscale(toler));
X printf(" at iteration %d\n",totaliter);
X return;
X };
X if (totaliter % saverate == 0) saveweights();
X if ((prpatsrate > 0) && ((i % prpatsrate == 0) || (i == n)))
X printpats(1,npats,1,1,1);
X };
X}
END_OF_FILE
echo shar: 1 control character may be missing from \"'misc.c'\"
if test 11006 -ne `wc -c <'misc.c'`; then
echo shar: \"'misc.c'\" unpacked with wrong size!
fi
# end of 'misc.c'
fi
echo shar: End of archive 4 \(of 4\).
cp /dev/null ark4isdone
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