home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / util / neural.sit / NetLib.c.bin / NetLib.c
Encoding:
C/C++ Source or Header  |  1989-03-10  |  6.5 KB  |  262 lines  |  [TEXT/MACA]

  1. /*NetLib.c    Core routines for neural Network.
  2.  
  3.      This file is Copyright 1989 by Pierce T. Wetter III
  4.      
  5.      Permission granted for all non-commercial uses of this code. For commercial uses of this code
  6.      contact me at 
  7.      
  8.          Pierce T. Wetter III
  9.          45 Vista Lago Dr.
  10.          Simi Valley, CA 93065
  11.          
  12.          or
  13.          
  14.          wetter@csvax.caltech.edu        or pwetter@caltech.bitnet
  15.          
  16. */
  17.  
  18.  
  19.  
  20.  
  21. #include "NetLib.h"
  22. #include "storage.h"
  23. #include "Math.h"
  24. extern char buffer[256];
  25.  
  26. /*isigma determines whether to take sigma of the inputs. No sigma seems to train faster*/
  27.  
  28. /*#define isigma    */
  29.  
  30. amnesia(themind)
  31. mind    *themind;
  32. {
  33. int i;
  34. int j;
  35.  
  36. #define MRAND (((double) Random())/ 32767.0)
  37.  
  38.     for (i=0;i<themind->nhidden;i++)
  39.     {
  40.         for (j=0;j<themind->nin;j++)
  41.         {
  42.             themind->inweights[i][j]=MRAND;
  43.             themind->inweightdeltas[i][j]=0.0;
  44.         }
  45.         themind->hiddenunits[i]=.5;
  46.         themind->hiddendeltas[i]=0.0;
  47.         themind->hiddenbias[i]=MRAND;
  48.         themind->hiddenbiasdeltas[i]=0.0;
  49.     }
  50.     for (i=0;i<themind->nout;i++)
  51.     {
  52.         for (j=0;j<themind->nhidden;j++)
  53.         {
  54.             themind->hiddenweights[i][j]=MRAND;
  55.             themind->hiddenweightdeltas[i][j]=0.0;
  56.         }
  57.         themind->outunits[i]=.5;
  58.         themind->outdeltas[i]=0.0;
  59.         themind->outbias[i]=MRAND;
  60.         themind->outbiasdeltas[i]=0.0;
  61.     }
  62.     for (j=0;j<themind->nin;j++)
  63.     {
  64.         themind->inunits[j]=.5;
  65.         themind->indeltas[j]=0.0;
  66.         themind->inbias[j]=MRAND;
  67.         themind->inbiasdeltas[j]=0.0;
  68.     }
  69.     
  70.     
  71. }
  72.  
  73. double sigma( x )
  74. double x;
  75. {
  76.     return (1.0/(1.0+exp(-x)));
  77. }
  78.  
  79.  
  80.  
  81. initmind(ni,nh,nout,lrate,moment,mymind)
  82. int ni,nh,nout;
  83. double lrate,moment;
  84. mind **mymind;
  85. {
  86. mind *themind;
  87. int i;
  88.  
  89.     themind= (mind *) mlalloc((long) sizeof(mind));
  90.     themind->nin=ni;
  91.     themind->nhidden=nh;
  92.     themind->nout=nout;
  93.     themind->learnrate=lrate;
  94.     themind->momentum=moment;
  95.     themind->inunits= (double *) mlalloc((long) (ni*sizeof(double)));
  96.     themind->hiddenunits= (double *) mlalloc((long) (nh *sizeof(double)));
  97.     themind->outunits= (double *) mlalloc((long) (nout * sizeof(double)));
  98.     themind->inbias= (double *) mlalloc((long) (ni*sizeof(double)));
  99.     themind->inbiasdeltas= (double *) mlalloc((long) (ni*sizeof(double)));
  100.     themind->hiddenbias= (double *) mlalloc((long) (nh *sizeof(double)));
  101.     themind->hiddenbiasdeltas= (double *) mlalloc((long) (nh *sizeof(double)));
  102.     themind->outbias= (double *) mlalloc((long) (nout * sizeof(double)));
  103.     themind->outbiasdeltas= (double *) mlalloc((long) (nout * sizeof(double)));
  104.     themind->inweights= (double **) mlalloc((long) (nh * sizeof(double *)));
  105.     for (i=0;i<nh;i++) themind->inweights[i]=(double *) mlalloc((long) (ni *sizeof(double)));
  106.     themind->inweightdeltas= (double **) mlalloc((long) (nh * sizeof(double *)));
  107.     for (i=0;i<nh;i++) themind->inweightdeltas[i]=(double *) mlalloc((long) (ni *sizeof(double)));
  108.     themind->hiddenweights= (double **) mlalloc((long) (nout * sizeof(double *)));
  109.     for (i=0;i<nout;i++) themind->hiddenweights[i]=(double *) mlalloc((long) (nh *sizeof(double)));
  110.     themind->hiddenweightdeltas= (double **) mlalloc((long) (nout * sizeof(double *)));
  111.     for (i=0;i<nout;i++) themind->hiddenweightdeltas[i]=(double *) mlalloc((long) (nh *sizeof(double)));
  112.     themind->indeltas= (double *) mlalloc((long) (ni*sizeof(double)));
  113.     themind->hiddendeltas= (double *) mlalloc((long) (nh *sizeof(double)));
  114.     themind->outdeltas= (double *) mlalloc((long) (nout * sizeof(double)));
  115.  
  116.     amnesia(themind);
  117.     themind->certfn=0L;
  118.     *mymind=themind;
  119. }
  120.  
  121. double learn(themind,inputs,outputs)
  122. mind *themind;
  123. double *inputs,*outputs;
  124. {
  125. int i,j,k;
  126. double a,tss=0.0,terror;
  127.  
  128.     think(themind,inputs);
  129.     for(i=0;i<themind->nout;i++)
  130.     {
  131.         a=themind->outunits[i];
  132.         terror=outputs[i]-a;
  133.         tss += terror*terror;
  134.         themind->outdeltas[i]=(terror)*a*(1.0-a);
  135.     }
  136.     for (i=0; i<themind->nhidden;i++)
  137.     {
  138.         a=themind->hiddenunits[i];
  139.         themind->hiddendeltas[i]= 0.0;
  140.         for (k=0; k< themind->nout; k++)
  141.         {
  142.             themind->hiddendeltas[i] += themind->outdeltas[k]*themind->hiddenweights[k][i];
  143.         }
  144.         themind->hiddendeltas[i] *= a*(1.0-a);
  145.     }
  146. /*    sprintf(buffer,"%g %g\r",themind->hiddendeltas[0],themind->hiddenweights[0][0]);
  147.     CtoPstr(buffer);
  148.     DisplayString(buffer);*/
  149.     for (i=0; i< themind->nin; i++)
  150.     {
  151.         a=themind->inunits[i];
  152.         themind->indeltas[i]=0.0;
  153.         for (k=0;k<themind->nhidden;k++)
  154.         {
  155.             themind->indeltas[i] += themind->hiddendeltas[k] * themind -> inweights[k][i];
  156.         }
  157.         themind->indeltas[i] *= a*(1.0-a);
  158.     }
  159.     
  160.     for (i=0; i< themind->nhidden; i++)
  161.     {
  162.         for (j=0; j< themind->nin; j++)
  163.         {
  164.             themind->inweightdeltas[i][j]= themind->learnrate* themind->hiddendeltas[i]*
  165.                            themind->inunits[j] + themind->momentum*themind->inweightdeltas[i][j];
  166.         }
  167.         themind->hiddenbiasdeltas[i] = themind->learnrate * themind->hiddendeltas[i] +
  168.             themind->momentum*themind->hiddenbiasdeltas[i];
  169.     }
  170.     for (i=0; i < themind->nout; i++)
  171.     {
  172.         for (j=0;j< themind->nhidden;j++)
  173.         {
  174.             themind->hiddenweightdeltas[i][j]= themind->learnrate * themind->outdeltas[i]*
  175.                     themind->hiddenunits[j] + themind->momentum* themind->hiddenweightdeltas[i][j];
  176.         }        
  177.         themind->outbiasdeltas[i] = themind->learnrate * themind->outdeltas[i] +
  178.             themind->momentum*themind->outbiasdeltas[i];
  179.     }        
  180.     
  181.     for (i=0; i < themind->nin; i++)
  182.     {
  183.         themind->inbiasdeltas[i] = themind->learnrate * themind->indeltas[i] +
  184.                 themind->momentum*themind->inbiasdeltas[i];
  185.     }
  186.     
  187.     reformmind(themind);
  188.     return(tss);
  189.     
  190. }
  191.  
  192. think(themind,inputs)
  193. mind *themind;
  194. double *inputs;
  195. {
  196. int i,j,k,l;
  197.  
  198.  for (i=0;i<themind->nout;i++) themind->outunits[i]=themind->outbias[i];
  199.  for (i=0;i<themind->nhidden;i++) themind->hiddenunits[i]=themind->hiddenbias[i];
  200.  for (i=0;i<themind->nin;i++)
  201.  {
  202. #ifdef isigma
  203.      themind->inunits[i]= sigma(  inputs[i]+themind->inbias[i] )  ;    
  204. #else
  205.      themind->inunits[i]= inputs[i]+themind->inbias[i]  ;    
  206. #endif
  207.     for (j=0;j<themind->nhidden;j++)
  208.     {
  209.         themind->hiddenunits[j] +=themind->inunits[i]*themind->inweights[j][i];
  210.     }
  211.   }
  212.   
  213.    
  214.  for (i=0;i<themind->nhidden;i++)
  215.  {
  216.       themind->hiddenunits[i] = sigma(themind->hiddenunits[i]);     
  217.     for (j=0;j<themind->nout;j++)
  218.     {
  219.         themind->outunits[j] +=themind->hiddenunits[i]*themind->hiddenweights[j][i];
  220.     }
  221.  }
  222.    
  223.   for (j=0;j< themind->nout;j++)
  224.   {
  225.   
  226.           themind->outunits[j] = sigma(themind->outunits[j]);
  227.   }
  228.     
  229. }
  230.  
  231. reformmind(themind)
  232. mind    *themind;
  233. {
  234. int i;
  235. int j;
  236.  
  237.     for (i=0;i<themind->nhidden;i++)
  238.     {
  239.         for (j=0;j<themind->nin;j++)
  240.         {
  241.             themind->inweights[i][j] += themind->inweightdeltas[i][j];
  242.         }
  243.         themind->hiddenbias[i] += themind->hiddenbiasdeltas[i];
  244.     }
  245.     
  246.     for (i=0;i<themind->nout;i++)
  247.     {
  248.         for (j=0;j<themind->nhidden;j++)
  249.         {
  250.             themind->hiddenweights[i][j] += themind->hiddenweightdeltas[i][j];
  251.         }
  252.         themind->outbias[i] += themind->outbiasdeltas[i];
  253.     }
  254.     
  255.     for (j=0;j<themind->nin;j++)
  256.     {
  257.         themind->inbias[j] += themind->inbiasdeltas[j];
  258.     }
  259.     
  260.     
  261. }
  262.