home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 618a.lha / NeuralNetwork / Neural_network.doc < prev    next >
Text File  |  1992-03-08  |  17KB  |  320 lines

  1.  
  2.  
  3.     Neural networks are very useful for solving problems where you know the
  4. inputs that make some output, but you have no idea how they are related.  Some
  5. simple examples are the weather, speech recognition, and vision.  It is very
  6. hard to program a routine which will recognize speech when you don't even
  7. know what makes the word "network" sound like the work "network".  Neural
  8. networks are good classifiers and are able to learn why an input generates
  9. a certain output.  To train a neural network, you first show it many
  10. examples of inputs that you know the output it generates.  After a while, the
  11. network will generate the output that is correct for a given input.  Now if
  12. the network learned correctly, the next time you show it an input which it
  13. has never seen before, it should give the correct output.  Now that some of
  14. you are totally confused, let's do an example.
  15.  
  16. Problem: Let us say that we are trying to predict the weather for the next
  17.          day.  We believe that tomorrow's weather depends upon today's
  18.          temperature, sky conditions (sunny, cloudy, rainy), wind,
  19.          barometric pressure, and humidty.  Assuming that the assumption
  20.          is correct (it is not but lets keep the example simple), then all
  21.          we have to do is give the inputs to the network and tell it what
  22.          has happened in the past.
  23.  
  24.          We have recorded 100 days of readings (inputs) and the next day's
  25.          weather (output).  Now we show the network the inputs and tell it
  26.          what the outputs must look like based on our data.  After training
  27.          the network for a while, all 100 input examples will generate the
  28.          correct output (prediction of tomorrow's weather).  Now if the
  29.          network has sufficient information then when we give it today's
  30.          weather and ask it what tomorrow should be like, it should predict
  31.          correctly.
  32.  
  33.     Now the question is, how do we implement a neural network.  The network
  34. design is a two hidden layer, feed-forward, fully-connected network.  The
  35. size of each layer (input, hidden1, hidden2, and output) is set at run-time
  36. and can be as large as your computer's memory allows.
  37.  
  38. The INPUTS:  The inputs must be between +-1.0.
  39. The OUTPUTS: Generally each output will either be 1 or 0.  For the weather
  40.              problem, a 1 at output 1 may indicate sunny while a 0 indicates
  41.              rain.  Also output 2 could indicate windy or not windy.
  42.  
  43. To train the network:
  44. STEP 1: You first construct the Neural_network with the size and the
  45.         learning parameters that you want.  You may read in the size and
  46.         previously trained weights from a file.
  47.  
  48. STEP 2: You call calc_forward () with a known input which calculates the
  49.         actual output.
  50.  
  51. STEP 3: You call back_propagation () with the desired output which will then
  52.         compare the actual output with the desired output and then calculate
  53.         how to change the connections to reduce the difference.
  54.  
  55. STEP 4: Go back to step 2 with another known input until all know inputs
  56.         have been shown once.
  57.  
  58. STEP 5: Call update_weights () which will actually change all the inter-
  59.         connections the way back_propagation () calculated the should.
  60.  
  61. STEP 6: Go back to step 2 and show all the known inputs again until the
  62.         actual output is close (usually within 0.1) of the desired output.
  63.  
  64. STEP 7: Save the weights (connections) to a file.
  65.  
  66. See the programs xor_dbd.cc and xor_bp.cc for an example of this basic
  67. procedure.
  68.  
  69.  
  70. //****************************************************************************
  71. //
  72. // Neural_network class:
  73. //
  74. //      This class performs all the necessary functions needed to train
  75. //      a Neural Network.  The network has an input layer, two hidden
  76. //      layers, and an output layer.  The size of each layer is specified
  77. //      a run time so there is no restriction on size except memory.
  78. //      This is a feed-forward network with full connctions from one
  79. //      layer to the next.
  80. //
  81. //      The network can perform straight back-propagation with no
  82. //      modifications (Rumelhart, Hinton, and Williams, 1985) which
  83. //      will find a solution but not very quickly.  The network can also
  84. //      perform back-propagation with the delta-bar-delta rule developed
  85. //      by Robert A. Jacobs, University of Massachusetts
  86. //      (Neural Networks, Vol 1. pp.295-307, 1988).  The basic idea of this
  87. //      rule is that every weight has its own learning rate and each
  88. //      learning rate should be continously changed according to the
  89. //      following rules -
  90. //      - If the weight changes in the same direction as the previous update,
  91. //        then the learning rate for that weight should increase by a constant.
  92. //      - If the weight changes in the opposite direction as the previous
  93. //        update, then the learning rate for that weight should decrease
  94. //        exponentially.
  95. //
  96. //      learning rate = e(t) for each individual weight
  97. //      The exact formula for the change in learning rate (DELTA e(t)) is
  98. //
  99. //
  100. //                   | K          if DELTA_BAR(t-1)*DELTA(t) > 0
  101. //      DELTA e(t) = | -PHI*e(t)  if DELTA_BAR(t-1)*DELTA(t) < 0
  102. //                   | 0          otherwise
  103. //
  104. //      where DELTA(t) = dJ(t) / dw(t) ---> Partial derivative
  105. //
  106. //      and DELTA_BAR(t) = (1 - THETA)*DELTA(t) + THETA*DELTA_BAR(t-1).
  107. //
  108. //      For full details of the algorithm, read the article in
  109. //      Neural Networks.
  110. //
  111. //
  112. //      To perform straight back-propagation, just construct a Neural_network
  113. //      with no learning parameters specified (they default to straight
  114. //      back-propagation) or set them to
  115. //      K = 0, PHI = 0, THETA = 1.0
  116. //
  117. //      However, using the delta-bar-delta rule should increase your rate of
  118. //      convergence by a factor of 10 to 100 generally.  The parameters for
  119. //      the delta-bar-delta rule I use are
  120. //      K = 0.025, PHI = 0.2, THETA = 0.8
  121. //
  122. //      One more heuristic method has been employed in this Neural net class-
  123. //      the skip heuristic.  This is something I thought of and I am sure
  124. //      other people have also.  If the output activation is within
  125. //      skip_epsilon of its desired for each output, then the calc_forward
  126. //      routine returns the skip_flag = 1.  This allows you to not waste
  127. //      time trying to push already very close examples to the exact value.
  128. //      If the skip_flag comes back '1', then don't bother calculating forward
  129. //      or back-propagating the example for X number of epochs.  You must
  130. //      write the routine to skip the example yourself, but the Neural_network
  131. //      will tell you when to skip the example.  This heuristic also has the
  132. //      advantage of reducing memorization and increases generalization.
  133. //      Typical values I use for this heuristic -
  134. //      skip_epsilon = 0.01 - 0.05
  135. //      number skipped = 2-10.
  136. //
  137. //      Experiment with all the values to see which work best for your
  138. //      application.
  139. //
  140. //
  141. //      Comments and suggestions are welcome and can be emailed to me
  142. //      anstey@sun.soe.clarkson.edu
  143. //
  144. //****************************************************************************
  145.  
  146.  
  147. //***********************************************************************
  148. // Constructors :                                                       *
  149. //    Full size specifications and learning parameters.                 *
  150. //         Learning parameters are provided defaults which are set to   *
  151. //         just use the BP algorithm with no modifications.             *
  152. //                                                                      *
  153. //    Read constructor which reads in the size and all the weights from *
  154. //         a file.  The network is resized to match the size specified  *
  155. //         by the file.  Learning parameters must be specified          *
  156. //         separately.                                                  *
  157. //***********************************************************************
  158.  
  159. Neural_network (int number_inputs = 1, int number_hidden1 = 1,
  160.                 int number_hidden2 = 1,
  161.                 int number_outputs = 1, double t_epsilon = 0.1,
  162.                 double t_skip_epsilon = 0.0, double t_learning_rate = 0.1,
  163.                 double t_theta = 1.0, double t_phi = 0.0, double t_K = 0.0,
  164.                 double range = 3.0);
  165. Neural_network (char *filename, int& file_error, double t_epsilon = 0.1,
  166.                 double t_skip_epsilon = 0.0, double t_learning_rate = 0.1,
  167.                 double t_theta = 1.0, double t_phi = 0.0, double t_K = 0.0);
  168. ~Neural_network ();
  169.  
  170.  
  171.   //**************************************************************************
  172.   // Weight parameter routines:                                              *
  173.   //     save_weights : This routine saves the weights of the network        *
  174.   //          to the file <filename>.                                        *
  175.   //                                                                         *
  176.   //     read_weights : This routine reads the weight values from the file   *
  177.   //          <filename>.  The network is automatically resized to the       *
  178.   //          size specified by the file.                                    *
  179.   //                                                                         *
  180.   //     Activation routines return the node activation after a calc_forward *
  181.   //          has been performed.                                            *
  182.   //                                                                         *
  183.   //     get_weight routines return the weight between node1 and node2.      *
  184.   //                                                                         *
  185.   //**************************************************************************
  186.  
  187.   int    save_weights (char *filename);
  188.   int    read_weights (char *filename);
  189.  
  190.   double get_hidden1_activation (int node);
  191.   double get_hidden2_activation (int node);
  192.   double get_output_activation (int node);
  193.  
  194.   double get_input_weight (int input_node, int hidden1_node);
  195.   double get_hidden1_weight (int hidden1_node, int hidden2_node);
  196.   double get_hidden2_weight (int hidden2_node, int output_node);
  197.  
  198.  
  199.   //*******************************************************************
  200.   // Size parameters of network.                                      *
  201.   // The size of the network may be changed at any time.  The weights *
  202.   // will be copied from the old size to the new size.  If the new    *
  203.   // size is larger, then the extra weights will be randomly set      *
  204.   // between +-range.  The matrices used to hold learning updates     *
  205.   // and activations will be re-initialized (cleared).                *
  206.   //*******************************************************************
  207.  
  208.   int get_number_of_inputs ();
  209.   int get_number_of_hidden1 ();
  210.   int get_number_of_hidden2 ();
  211.   int get_number_of_outputs ();
  212.   void set_size_parameters (int number_inputs, int number_hidden1,
  213.                             int number_hidden2, int number_outputs,
  214.                             double range = 3.0);
  215.  
  216.  
  217.   //*******************************************************************
  218.   // Learning parameters functions.  These parameters may be changed  *
  219.   // on the fly.  The learning rate and K may have to be reduced as   *
  220.   // more and more training is done to prevent oscillations.          *
  221.   //*******************************************************************
  222.  
  223.   void set_epsilon (double eps);
  224.   void set_skip_epsilon (double eps);
  225.   void set_learning_rate (double l_rate);
  226.   void set_theta (double t_theta);
  227.   void set_phi (double t_phi);
  228.   void set_K (double t_K);
  229.  
  230.   double get_epsilon ();
  231.   double get_skip_epsilon ();
  232.   double get_learning_rate ();
  233.   double get_theta ();
  234.   double get_phi ();
  235.   double get_K ();
  236.   long   get_iterations ();
  237.  
  238.  
  239.   //**************************************************************************
  240.   // The main neural network routines:                                       *
  241.   //                                                                         *
  242.   //      The network input is an array of doubles which has a size of       *
  243.   //           number_inputs.                                                *
  244.   //      The network desired output is an array of doubles which has a size *
  245.   //           of number_outputs.                                            *
  246.   //                                                                         *
  247.   //      back_propagation : Calculates how each weight should be changed.   *
  248.   //           Assumes that calc_forward has been called just prior to       *
  249.   //           this routine to calculate all of the node activations.        *
  250.   //                                                                         *
  251.   //      calc_forward : Calculates the output for a given input.  Finds     *
  252.   //           all node activations which are needed for back_propagation    *
  253.   //           to calculate weight adjustment.  Returns abs (error).         *
  254.   //           The parameter skip is for use with the skip_epsilon           *
  255.   //           parameter.  What it means is if the output is within          *
  256.   //           skip_epsilon of the desired, then it is so close that it      *
  257.   //           should be skipped from being calculated the next X times.     *
  258.   //           Careful use of this parameter can significantly increase      *
  259.   //           the rate of convergence and also help prevent over-learning.  *
  260.   //                                                                         *
  261.   //      calc_forward_test : Calculates the output for a given input.  This *
  262.   //           routine is used for testing rather than training.  It returns *
  263.   //           whether the test was CORRECT, GOOD or WRONG which is          *
  264.   //           determined by the parameters correct_epsilon and              *
  265.   //           good_epsilon.  CORRECT > GOOD > WRONG.                        *
  266.   //                                                                         *
  267.   //      update_weights : Actually adjusts all the weights according to     *
  268.   //           the calculations of back_propagation.  This routine should    *
  269.   //           be called at the end of every training epoch.  The weights    *
  270.   //           can be updated by the straight BP algorithm, or by the        *
  271.   //           delta-bar-delta algorithm developed by Robert A. Jacobs       *
  272.   //           which increases the rate of convergence generally by at       *
  273.   //           least a factor of 10.  The parameters THETA, PHI, and K       *
  274.   //           determine which algorithm is used.  The default settings      *
  275.   //           for these parameters cause update_weights to use the straight *
  276.   //           BP algorithm.                                                 *
  277.   //                                                                         *
  278.   //      kick_weights : This routine changes all weights by a random amount *
  279.   //           within +-range.  It is useful in case the network gets        *
  280.   //           'stuck' and is having trouble converging to a solution.  I    *
  281.   //           use it when the number wrong has not changed for the last 200 *
  282.   //           epochs.  Getting the range right will take some trial and     *
  283.   //           error as it depends on the application and the weights'       *
  284.   //           actual values.                                                *
  285.   //                                                                         *
  286.   //**************************************************************************
  287.  
  288.   void back_propagation (double input [], double desired_output [],
  289.                          int& done);
  290.  
  291.   double calc_forward (double input [], double desired_output [],
  292.                        int& num_wrong, int& skip, int print_it,
  293.                        int& actual_printed);
  294.  
  295.   int calc_forward_test (double input [], double desired_output [],
  296.                          int print_it, double correct_eps, double good_eps);
  297.  
  298.   void update_weights ();
  299.  
  300.   void kick_weights (double range);
  301.  
  302. };
  303.  
  304. KNOWN BUGS:
  305.     There are no known bugs in my code (does not mean there aren't any), but
  306. there is one bug with the Aztec C 5.0a m8 library.  The fscanf routine does
  307. not correctly read in floating point numbers from a text file so you must
  308. use a different math library to compile and link.
  309.  
  310.     This code has been compiled with g++, gcc, and Aztec C 5.0a.  The C version
  311. has not been fully tested but it seems to work just fine.  I also do not
  312. plan to continue revising the C version, just the C++ version.  However, I
  313. will fix any bugs in either version.
  314.  
  315.     You can email me at
  316. anstey@sun.soe.clarkson.edu
  317.  
  318. Hope you like the code!
  319.  
  320.