home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / luschsrc.sit / neural.c < prev    next >
Text File  |  1990-05-23  |  4KB  |  203 lines

  1. /********************************************************************************
  2.  *    neural.c
  3.  *
  4.  *    Neural Network Package
  5.  *
  6.  *    Written by Paco Xander Nathan
  7.  *    ⌐1990, Motorola Inc.  Public domain source code.
  8.  ********************************************************************************/
  9.  
  10. #include "applic.h"
  11. #include "neural.h"
  12.  
  13.  
  14. #define NN_INPUT    181
  15. #define NN_HIDDEN    38
  16. #define NN_OUTPUT    1
  17.  
  18.  
  19. typedef enum {
  20.     nnLayerInput = 0, nnLayerHidden, nnLayerOutput
  21. } NNLayerValues;
  22.  
  23.  
  24. /* External Data Structures
  25.  */
  26. float
  27.     nnCertainty = 0.0,
  28.     nnOutput = 0.0;
  29.  
  30. Boolean
  31.     nnClusterFlag = TRUE;
  32.  
  33.  
  34. /* Local Data Structures
  35.  */
  36. static float
  37.     nnHidLayer[NN_HIDDEN],
  38.     nnOutLayer[NN_OUTPUT],
  39.     nnInWeight[NN_INPUT][NN_HIDDEN],
  40.     nnOutWeight[NN_HIDDEN][NN_OUTPUT];
  41.  
  42.  
  43. /* Initialize the network
  44.  */
  45. void
  46. NNInit ()
  47. {
  48.     /* Set default values
  49.      */
  50.     nnCertainty = 0.0;
  51.     nnClusterFlag = TRUE;
  52.     NNSetAllWeights(0.0);
  53. }
  54.  
  55.  
  56. /* Sets the weight of all connections between all neurons in all layers 
  57.  * to the given value
  58.  */
  59. void
  60. NNSetAllWeights (value)
  61.     register float value;
  62. {
  63.     register short i, j; 
  64.  
  65.     /* Weights between input and hidden
  66.      */
  67.     for (i = 0; i < NN_INPUT; i++)
  68.         for (j = 0; j < NN_HIDDEN; j++)
  69.             nnInWeight[i][j] = value;
  70.  
  71.     /* Weights between hidden and output
  72.      */
  73.     for (i = 0; i < NN_HIDDEN; i++)
  74.         for (j = 0; j < NN_OUTPUT; j++)
  75.             nnOutWeight[i][j] = value;
  76. }
  77.  
  78.  
  79. /* Sets the weight between to neurons to a given value
  80.  */
  81. void
  82. NNSetWeight (from, to, layer, value)
  83.     register short from, to, layer;
  84.     register float value;
  85. {
  86.     switch (layer) {
  87.     case nnLayerHidden:
  88.         if ((from <= NN_INPUT) && (to <= NN_HIDDEN))
  89.             nnInWeight[from][to] = value;
  90.  
  91.         break;
  92.  
  93.     case nnLayerOutput:
  94.         if ((from <= NN_HIDDEN) && (to <= NN_OUTPUT))
  95.             nnOutWeight[from][to] = value;
  96.  
  97.         break;
  98.  
  99.     default:
  100.         break;
  101.     }
  102. }
  103.  
  104.  
  105. /* Teach the net a thing or two
  106.  */
  107. void
  108. NNLearn (bit, nBits, theOutput)
  109.     register Boolean *bit;
  110.     register WORD nBits;
  111.     register WORD theOutput;
  112. {
  113.     register WORD theBit, sumBits;
  114.     register float distWeight = 1.0;
  115.  
  116.     /* Use the distributed weight of the input vector to setup 
  117.      * the hidden layer
  118.      */
  119.     for (theBit = 0, sumBits = 0; theBit < nBits; theBit++)
  120.         sumBits += bit[theBit];
  121.  
  122.     if (sumBits > 0)
  123.         distWeight = 1.0 / sumBits;
  124.     
  125.     ApplSpinCurs(FALSE);
  126.     
  127.     for (theBit = 0; theBit < nBits; theBit++)
  128.         if (bit[theBit])
  129.             NNSetWeight(theBit, theOutput, nnLayerHidden, distWeight);
  130.  
  131.     /* Setup the output layer
  132.      */
  133.     NNSetWeight(theOutput, 0, nnLayerOutput, (float) theOutput);
  134. }
  135.  
  136.  
  137. /* Sets a neural network in motion by sequentially activating each neuron
  138.  */
  139. void
  140. NNActivate (bit, nBits)
  141.     register Boolean *bit;
  142.     register WORD nBits;
  143. {
  144.     register float sum, highest = 0.0;
  145.     register WORD i, j, closest = -1;
  146.  
  147.     /* Activate hidden layer
  148.      */
  149.     for (i = 0; i < NN_HIDDEN; i++) {
  150.         for (j = 0, sum = 0.0; j < nBits; j++)
  151.             sum += bit[j] * nnInWeight[j][i];
  152.  
  153.         nnHidLayer[i] = sum;
  154.         ApplSpinCurs(FALSE);
  155.     }
  156.  
  157.     /* Performs a cluster function.  It inhibits (sets to 0) all neurons in the cluster
  158.      * except the one which is closest to the value 1.0.  This neuron is set to 1.0.  The 
  159.      * net's certainty value is assigned the certainty to which the closest neuron felt it 
  160.      * matched the pattern.
  161.      */
  162.     if (nnClusterFlag) {
  163.         for (i = 0; i < NN_HIDDEN; i++) 
  164.              if (nnHidLayer[i] > highest) {
  165.                   closest = i;
  166.                   highest = nnHidLayer[i];
  167.              }
  168.     
  169.         /* All are equally likely - choose the first
  170.          */
  171.         if (closest == -1)       
  172.             closest = 0;
  173.     
  174.         nnCertainty = nnHidLayer[closest] * 100.0;
  175.         
  176.         /* Cause just enough feedback to the neuron which is closest to being "on".
  177.          * That is, set it "on".  All others are given negative feedback to force 
  178.          * them to zero.  (Set them to zero).
  179.          */
  180.         for (i = 0; i < NN_HIDDEN; i++)
  181.             if (i == closest)
  182.                 nnHidLayer[i] = 1.0;
  183.             else
  184.                 nnHidLayer[i] = 0.0;
  185.     }
  186.  
  187.     /* Activate output layer
  188.      */
  189.     for (i = 0, sum = 0.0; i < NN_OUTPUT; i++) {
  190.         for (j = 0; j < NN_HIDDEN; j++) {
  191.             sum += nnHidLayer[j] * nnOutWeight[j][i];
  192.             ApplSpinCurs(FALSE);
  193.         }
  194.  
  195.         nnOutLayer[i] = sum;
  196.     }
  197.     
  198.     /* For the purposes of this application, we only need one 
  199.      * public output...
  200.      */
  201.     nnOutput = nnOutLayer[0];
  202. }
  203.