home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume28 / backprop / part04 / int.c next >
Encoding:
C/C++ Source or Header  |  1992-02-23  |  14.0 KB  |  491 lines

  1. /* *********************************************************** */
  2. /* file int.c:  Contains the network evaluation and weight     */
  3. /*              adjustment procedures for the integer versions */
  4. /*              bp and sbp.                                    */
  5. /*                                                             */
  6. /* Copyright (c) 1991 by Donald R. Tveter                      */
  7. /*                                                             */
  8. /* The code here has been optimized for use with the Motorola  */
  9. /* MC 68010 processor and version 3.5 of the UNIX (tm) PC      */
  10. /* C compiler where UNIX is a trademark of Bell Laboratories.  */
  11. /* *********************************************************** */
  12.  
  13. #include "ibp.h"
  14. #include <stdio.h>
  15.  
  16. extern char activation, backprop, deriv, wtlimithit;
  17. extern WTTYPE alpha, D, decay, eta, eta2, etamax, kappa, noise;
  18. extern WTTYPE theta1, theta2, toler;
  19. extern LAYER *last, *start;
  20. extern INT32 totaldiff;
  21.  
  22. void forward()             /* computes unit activations */
  23. register INT32 sum, x, intpart;
  24. register WTNODE *w;
  25. register UNIT *u, *predu;
  26. LAYER *layer;
  27. register short fract, val;
  28.  
  29. layer = start->next;
  30. while (layer != NULL)
  31.  {
  32.   u = (UNIT *) layer->units;
  33.   while (u != NULL)
  34.    {
  35.     sum = 0;
  36.     w = (WTNODE *) u->wtlist;
  37.     while (w != NULL)
  38.      {
  39.       predu = (UNIT *) w->backunit;
  40. #ifdef SMART
  41. #   ifdef SYMMETRIC
  42.       sum = sum + (INT32) *(w->weight) * predu->oj / 1024;
  43. #   else
  44.       sum = sum + (INT32) w->weight * predu->oj / 1024;
  45. #   endif
  46. #else
  47. #   ifdef SYMMETRIC
  48.       x = (INT32) *(w->weight) * predu->oj;
  49. #   else
  50.       x = (INT32) w->weight * predu->oj;
  51. #   endif
  52.       if (x >= 0) sum = sum + (x >> 10); else sum = sum - ( (-x) >> 10);
  53. #endif
  54.       w = w->next;
  55.      };
  56.     sum = (INT32) D * sum / 1024;
  57.     if (activation == 'p' || activation == 't')
  58.      {
  59.       if (sum > 0) x = sum; else x = -sum;
  60.       intpart = x >> 10;
  61.       fract = x & 01777;
  62.       switch (intpart) {
  63. case 0:  val = 512 + (((INT32) 237 * fract) >> 10);       /* 0 <= x < 1 */
  64.          break;
  65. case 1:  val = 748 + (((INT32) 153 * fract) >> 10);       /* 1 <= x < 2 */
  66.          break;
  67. case 2:  val = 901 + (((INT32) 73 * fract) >> 10);        /* 2 <= x < 3 */
  68.          break;
  69. case 3:
  70. case 4:  val = 976 + (((INT32) (x - 3072) * 20) >> 10);   /* 3 <= x < 5 */
  71.          break;
  72. default: val = 1024;                                      /* x >= 5 */ };
  73.          if (sum < 0) u->oj = 1024 - val; else u->oj = val;
  74.          if (activation == 't') u->oj = (u->oj - 512) * 2;
  75.      }
  76.     else if (activation == 'l') u->oj = sum;
  77.     u = u->next;
  78.    };
  79.     layer = layer->next;
  80.    };
  81. }
  82.  
  83. short backoutput()  /* computes weight changes from the output layer */
  84. {
  85. register short deltaj, temp2, temp3;
  86. register INT32 temp;
  87. register UNIT *bunit, *u;
  88. register WTNODE *w;
  89. register short adiff, notclose;
  90.  
  91. notclose = last->unitcount;
  92. u = (UNIT *) last->units;
  93. while (u != NULL)
  94.  { 
  95.   temp3 = u->oj;
  96.   temp2 = u->tj - temp3;
  97.   if (temp2 > 0) adiff = temp2; else adiff = -temp2;
  98.   if (adiff < toler) notclose = notclose - 1;
  99.   totaldiff = totaldiff + adiff;
  100.   if (adiff >= toler || backprop)  /* then compute errors */
  101.    {
  102.     if (deriv == 'd') /* diff. step size method */
  103.        deltaj = temp2;
  104.     else if (deriv == 'f' || deriv == 'F') /* Fahlman's derivative */
  105.      {
  106.       if (activation == 't') temp3 = temp3 / 2 + 512;
  107.       temp = (INT32) temp2 * ((INT32) 104448 + (INT32) temp3 * ((short)(1024 - temp3)));
  108.       if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
  109.       else deltaj = -((INT32) (524288 - temp) >> 20);
  110.      }
  111.     else /* the derivative in the original formula */
  112.      {
  113.       if (activation == 't') temp3 = temp3 / 2 + 512;
  114.       temp = (INT32) temp2 * ((INT32) temp3 * ((short)(1024 - temp3)));
  115.       if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
  116.       else deltaj = -((INT32) (524288 - temp) >> 20);
  117.      }
  118.     w = (WTNODE *) u->wtlist;
  119. #ifdef SYMMETRIC
  120.     while (w->next != NULL)  /* skips threshold unit at end */
  121. #else
  122.     while (w != NULL)
  123. #endif
  124.      {
  125.       bunit = (UNIT *) w->backunit;
  126. #ifdef SYMMETRIC
  127.       *(w->total) = *(w->total) + (INT32) deltaj * bunit->oj;
  128. #else
  129.       w->total = w->total + (INT32) deltaj * bunit->oj;
  130.       if (bunit->layernumber > 1)
  131.          bunit->error = bunit->error + (INT32) deltaj * w->weight;
  132. #endif
  133.       w = w->next;
  134.      }
  135.    };
  136.   u = u->next;
  137.  };
  138. return(notclose);
  139. }
  140.  
  141. #ifndef SYMMETRIC
  142.  
  143. void backinner()             /* Computes slopes and passes back */
  144. {                            /* errors from hidden layers.      */
  145. register short deltaj, temp3;
  146. register INT32 temp;
  147. register UNIT *bunit, *u;
  148. register WTNODE *w;
  149. LAYER *layer;
  150.  
  151. layer = last->backlayer;
  152. while (layer->backlayer != NULL)
  153.  {
  154.   u = (UNIT *) layer->units;
  155.   while (u != NULL)
  156.    {
  157.     if (activation == 't') temp3 = u->oj / 2 + 512; else temp3 = u->oj;
  158.     if (deriv == 'f') /* Fahlman's derivative */
  159.        temp = (INT32) (((short)(((INT32) temp3*((short)(1024-temp3))+512) >> 10))
  160.               + 102) * u->error;
  161.     else /* either for the original or diff. step size */
  162.        temp = (INT32) ((short)(((INT32) temp3*((short)(1024-temp3))+512) >> 10))
  163.           * u->error;
  164.     if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
  165.     else deltaj = -((INT32) (524288 - temp) >> 20);
  166.     w = (WTNODE *) u->wtlist;
  167.     while (w != NULL)
  168.      {
  169.       bunit = (UNIT *) w->backunit;
  170.       w->total = w->total + (INT32) deltaj * bunit->oj;
  171.       if (bunit->layernumber > 1)
  172.          bunit->error = bunit->error + (INT32) deltaj * w->weight;
  173.       w = w->next;
  174.      };
  175.     u = u->next;
  176.    };
  177.   layer = layer->backlayer;
  178.  };
  179. }
  180.  
  181. #endif
  182.  
  183. #ifdef SYMMETRIC
  184. void dbd_update() {pg("symmetric dbd update no longer supported\n");}
  185. #else
  186. void dbd_update() /* the delta-bar-delta method for weight updates */
  187. {
  188. register short rkappa, temp2, dbarm1, rdecay;
  189. register INT32 temp;
  190. register UNIT *u;
  191. register WTNODE *w;
  192. LAYER *layer;
  193.  
  194. /* w->olddw is used for delta-bar minus 1 */
  195.  
  196. rkappa = kappa;
  197. rdecay = decay;
  198. layer = last;
  199. while (layer->backlayer != NULL)
  200.  {
  201.   u = (UNIT *) layer->units;
  202.   while (u != NULL)
  203.    {
  204.     w = (WTNODE *) u->wtlist;
  205.     while (w != NULL)
  206.      {
  207.       if (w->total > 0) temp2 = (INT32) (w->total + 512) >> 10;
  208.       else temp2 = -((INT32) (512 - w->total) >> 10);
  209.       dbarm1 = w->olddw;
  210.       temp = (INT32) theta2 * temp2 + (INT32) theta1 * dbarm1;
  211.       if (temp > 0) w->olddw = (INT32) (temp + 512) >> 10;
  212.       else w->olddw = -((INT32) (512 - temp) >> 10);
  213.       if (temp2 > 0 && dbarm1 > 0) w->eta = w->eta + rkappa;
  214.       else if (temp2 < 0 && dbarm1 < 0) w->eta = w->eta + rkappa;
  215.       else if (temp2 > 0 && dbarm1 < 0)w->eta = ((INT32) w->eta * rdecay) >> 10;
  216.       else if (temp2 < 0 && dbarm1 > 0)w->eta = ((INT32) w->eta * rdecay) >> 10;
  217.       if (w->eta > etamax) w->eta = etamax;
  218.       temp = (INT32) temp2 * w->eta;
  219.       if (temp > 0) temp2 = (INT32) (temp + 512) >> 10;
  220.       else if (temp < 0) temp2 = -((INT32) (512 - temp) >> 10);
  221.  
  222.       else if (w->slope == 0)
  223.          {if (w->total < 0) temp2 = noise; else temp2 = -noise;}
  224.       w->slope = temp2;
  225.  
  226.       temp = (INT32) w->weight + temp2;
  227.       if (temp > MAXSHORT)
  228.        {
  229.         wtlimithit = 1;
  230.         w->weight = MAXSHORT;
  231.        }
  232.       else if (temp < MINSHORT)
  233.        {
  234.         wtlimithit = 1;
  235.         w->weight = MINSHORT;
  236.        }
  237.       else w->weight = temp;
  238.       w = w->next;
  239.      };
  240.     u = u->next;
  241.    };
  242.   layer = layer->backlayer;
  243.  };
  244. }
  245. #endif
  246.  
  247. void periodic_update()   /* update weights for the original method */
  248. {                        /* and the differential step size algorithm */
  249. register short reta, ralpha;
  250. register INT32 temp;
  251. register short temp2;
  252. register UNIT *u;
  253. register WTNODE *w;
  254. LAYER *layer;
  255.  
  256. ralpha = alpha;
  257. layer = last;
  258. while (layer->backlayer != NULL)
  259.  {
  260.   if (layer == last) reta = eta; else reta = eta2;
  261.   u = (UNIT *) layer->units;
  262.   while (u != NULL)
  263.    {
  264.     w = (WTNODE *) u->wtlist;
  265.     while (w != NULL)
  266.      {
  267. #ifdef SYMMETRIC
  268.       if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
  269.        {
  270.         if (*(w->total) > 0) temp = (INT32) ((INT32)(*(w->total) + 512) >> 10) * reta 
  271.            + (INT32) ralpha * *(w->olddw);
  272.         else temp = (INT32) -(((INT32) 512 - *(w->total)) >> 10) * reta
  273.            + (INT32) ralpha * *(w->olddw);
  274.         if (temp > 0) temp2 = (INT32) (temp + 512) >> 10;
  275.         else temp2 = -(((INT32) 512 - temp) >> 10);
  276.         *(w->olddw) = temp2;
  277.         temp = (INT32) *(w->weight) + temp2;
  278.         if (temp > MAXSHORT)
  279.          {
  280.           wtlimithit = 1;
  281.           *(w->weight) = MAXSHORT;
  282.          }
  283.         else if (temp < MINSHORT)
  284.          {
  285.           wtlimithit = 1;
  286.           *(w->weight) = MINSHORT;
  287.          }
  288.         else *(w->weight) = temp;
  289.        };
  290. #else
  291.       if (w->total > 0)
  292.         temp = (INT32) (((INT32) w->total + 512) >> 10) * reta + (INT32) ralpha * w->olddw;
  293.       else
  294.         temp = (INT32) -(((INT32) 512 - w->total) >> 10) * reta + (INT32) ralpha * w->olddw;
  295.       if (temp > 0) temp2 = (INT32) (temp + 512) >> 10;
  296.       else temp2 = -(((INT32) 512 - temp) >> 10);
  297.       w->olddw = temp2;
  298.       temp = (INT32) w->weight + temp2;
  299.       if (temp > MAXSHORT)
  300.        {
  301.         wtlimithit = 1;
  302.         w->weight = MAXSHORT;
  303.        }
  304.       else if (temp < MINSHORT)
  305.        {
  306.         wtlimithit = 1;
  307.         w->weight = MINSHORT;
  308.        }
  309.       else w->weight = temp;
  310. #endif
  311.       w = w->next;
  312.      };
  313.     u = u->next;
  314.    };
  315.   layer = layer->backlayer;
  316.  };
  317. }
  318.  
  319.  
  320. void qp_update() {pg("quickprop not yet finished\n");}
  321. void supersab() {pg("supersab not yet finished\n");}
  322.  
  323. short cbackoutput()          /* The continuous update version */
  324. {                            /* of back-propagation */
  325. register short deltaj;
  326. register INT32 etadeltaj, temp, temp2;
  327. register short temp3, adiff;
  328. register UNIT *bunit;
  329. register WTNODE *w;
  330. register UNIT *u;
  331. register short ralpha, reta, notclose;
  332.  
  333. ralpha = alpha;
  334. reta = eta;
  335. notclose = last->unitcount;
  336. u = (UNIT *) last->units;
  337. while (u != NULL)
  338.  { 
  339.   temp3 = u->oj;
  340.   temp2 = u->tj - temp3;
  341.   if (temp2 > 0) adiff = temp2; else adiff = -temp2;
  342.   if (adiff < toler) notclose = notclose - 1;
  343.   totaldiff = totaldiff + adiff;
  344.   if (adiff >= toler || backprop)
  345.    {
  346.     if (deriv == 'd') /* the differential step size method */
  347.       deltaj = temp2;
  348.     else if (deriv == 'f' || deriv == 'F') /* Fahlman's derivative */
  349.      { /* deltaj = (u->tj - u->oj) * [0.1 + u->oj*(1.0 - u->oj)] */
  350.       if (activation == 't') temp3 = temp3 / 2 + 512;
  351.       temp = (INT32) temp2 * ((INT32) 104448 + (INT32) temp3 * ((short)(1024 - temp3)));
  352.       if(temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
  353.       else deltaj = -(((INT32) 524288 - temp) >> 20);
  354.      }
  355.     else /* the original derivative */
  356.      { /* deltaj = (u->tj - u->oj) * u->oj * (1.0 - u->oj) */
  357.       if (activation == 't') temp3 = temp3 / 2 + 512;
  358.       temp = (INT32) temp2 * ((INT32) temp3 * ((short)(1024 - temp3)));
  359.       if(temp > 0) deltaj = ((INT32) temp + 524288) >> 20;
  360.       else deltaj = -(((INT32) 524288 - temp) >> 20);
  361.      };
  362.     etadeltaj = (INT32) deltaj * reta;
  363.     w = (WTNODE *) u->wtlist;
  364. #ifdef SYMMETRIC
  365.     while (w->next != NULL)
  366. #else
  367.     while (w != NULL)
  368. #endif
  369.      { /* get a slope for each weight */
  370.       bunit = (UNIT *) w->backunit;
  371.       temp = (INT32) etadeltaj * bunit->oj;
  372.       if(temp > 0) temp = (INT32) (temp + 524288) >> 20;
  373.       else temp = -(((INT32) 524288 - temp) >> 20);
  374. #ifdef SYMMETRIC
  375.       temp2 = (INT32) ralpha * *(w->olddw);
  376. #else
  377.       temp2 = (INT32) ralpha * w->olddw;
  378. #endif
  379.       if (temp2 > 0) temp3 = temp + (((INT32) temp2 + 512) >> 10);
  380.       else temp3 = temp - (((INT32) 512 - temp2) >> 10);
  381. #ifdef SYMMETRIC
  382.       *(w->olddw) = temp3;
  383. #else
  384.       w->olddw = temp3;
  385. #endif
  386.       /* w->weight = w->weight + w->olddw */
  387. #ifdef SYMMETRIC
  388.       temp = (INT32) *(w->weight) + temp3;
  389.       if (temp > MAXSHORT)
  390.        {
  391.         wtlimithit = 1;
  392.         *(w->weight) = MAXSHORT;
  393.        }
  394.       else if (temp < MINSHORT)
  395.        {
  396.         wtlimithit = 1;
  397.         *(w->weight) = MINSHORT;
  398.        }
  399.       else *(w->weight) = temp;
  400. #else
  401.       temp = (INT32) w->weight + temp3;
  402.       if (temp > MAXSHORT)
  403.        {
  404.         wtlimithit = 1;
  405.         temp3 = MAXSHORT;
  406.        }
  407.       else if (temp < MINSHORT)
  408.        {
  409.         wtlimithit = 1;
  410.         temp3 = MINSHORT;
  411.        }
  412.       else temp3 = temp;
  413.       w->weight = temp3;
  414.       if (bunit->layernumber > 1)
  415.          bunit->error = bunit->error + (INT32) deltaj * temp3;
  416. #endif
  417.       w = w->next;
  418.      }
  419.    }
  420.   u = u->next;
  421.  }
  422. return(notclose);
  423. }
  424.  
  425. #ifndef SYMMETRIC
  426.  
  427. void cbackinner()
  428. {
  429. register short deltaj;
  430. register INT32 etadeltaj, temp, temp2;
  431. register short temp3, reta, ralpha;
  432. register UNIT *bunit;
  433. register WTNODE *w;
  434. register UNIT *u;
  435. LAYER *layer;
  436.  
  437. reta = eta2;
  438. ralpha = alpha;
  439. layer = last->backlayer;
  440. while (layer->backlayer != NULL)
  441.  {
  442.   u = (UNIT *) layer->units;
  443.   while (u != NULL)
  444.    {
  445.     if (activation == 't') temp3 = u->oj / 2 + 512;
  446.     else temp3 = u->oj;
  447.     if (deriv == 'f')  /* Fahlman's derivative */
  448.        temp = (INT32) ((((INT32) temp3 * ((short)(1024 - temp3)) + 512) >> 10) + 102)
  449.                * u->error;
  450.     else  /* diff. step size and original derivative */
  451.        temp = (((INT32) temp3 * ((short)(1024 - temp3)) + 512) >> 10)
  452.                 * u->error;
  453.     if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
  454.     else deltaj = -(((INT32) 524288 - temp) >> 20);
  455.     etadeltaj = (INT32) reta * deltaj;
  456.     w = (WTNODE *) u->wtlist;
  457.     while (w != NULL)
  458.      {
  459.       bunit = (UNIT *) w->backunit;
  460.       temp = (INT32) etadeltaj * bunit->oj;
  461.       if (temp > 0) temp = (INT32) (temp + 524288) >> 20;
  462.       else temp = -(((INT32) 524288 - temp) >> 20);
  463.       temp2 = (INT32) ralpha * w->olddw;
  464.       if (temp2 > 0) temp3 = temp + ((INT32) (temp2 + 512) >> 10);
  465.       else temp3 = temp - (((INT32) 512 - temp2) >> 10);
  466.       w->olddw = temp3;
  467.       temp = (INT32) w->weight + temp3;
  468.       if (temp > MAXSHORT)
  469.        {
  470.         wtlimithit = 1;
  471.         temp3 = MAXSHORT;
  472.        }
  473.       else if (temp < MINSHORT)
  474.        {
  475.         wtlimithit = 1;
  476.         temp3 = MINSHORT;
  477.        }
  478.       else temp3 = temp;       
  479.       w->weight = temp3;
  480.       if (bunit->layernumber > 1)
  481.          bunit->error = bunit->error + (INT32) deltaj * temp3;
  482.       w = w->next;
  483.      };
  484.     u = u->next;
  485.    };
  486.   layer = layer->backlayer;
  487.  };
  488. }
  489. #endif
  490.