home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / Source / GPCHAP23 / NETWARE.ZIP / nnlist2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-19  |  9.2 KB  |  334 lines

  1. // HEBBIAN NET SIMULATOR /////////////////////////////////////////////////////////
  2.  
  3. // INCLUDES //////////////////////////////////////////////////////////////////////
  4.  
  5. #include <conio.h>
  6. #include <stdlib.h>
  7. #include <malloc.h>
  8. #include <memory.h>
  9. #include <string.h>
  10. #include <stdarg.h>
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include <io.h>
  14. #include <fcntl.h>
  15.  
  16. // DEFINES ///////////////////////////////////////////////////////////////////////
  17.  
  18. #define MAX_INPUTS        16    // maximum number of inputs
  19. #define MAX_OUTPUTS        16    // maximum number of outputs
  20.  
  21. #define ACTF_STEP        0    // use a binary step activation function fs(x)
  22. #define ACTF_LINEAR        1    // use a linear activation function fl(s)
  23. #define ACTF_EXP        2    // use an inverse exponential activation function fe(x)
  24.  
  25. // MACROS ////////////////////////////////////////////////////////////////////////
  26.  
  27. // used to retrieve the i,jth element of a linear, row major, matrix
  28.  
  29. #define MAT(mat,width,i,j) (mat[((width)*i)+(j)])
  30.  
  31. // GLOBALS ///////////////////////////////////////////////////////////////////////
  32.  
  33. float    input_xi[MAX_INPUTS],    // holds that input values
  34.         input_i[MAX_INPUTS],    // holds a single input vector
  35.         output_i[MAX_OUTPUTS],    // holds a single output vector 
  36.         input_act[MAX_OUTPUTS],    // holds the summed input activations 
  37.         output_yi[MAX_OUTPUTS],    // holds the output values
  38.         bias_bi[MAX_OUTPUTS],    // holds the bias weights bi
  39.         alpha = (float)1.0,        // needed for exponential activation function
  40.         *weight_matrix = NULL;    // dynamically allocated weight matrix
  41.         
  42. int        num_inputs,                // number of inputs in heb net
  43.         num_outputs,            // number of outputs in heb net
  44.         activation_func = ACTF_STEP;    // type of activation function to use
  45.  
  46. // FUNCTIONS /////////////////////////////////////////////////////////////////////
  47.  
  48. void Train_Net(void)
  49. {
  50. // this function is resposible for training the neural net using hebbian learning
  51.  
  52. // ask the user for another input/ouptput vector pair and then add the vectors contribution to
  53. // the weight matrix and bias
  54.  
  55. printf("\nHebbian Training System.");
  56. printf("\nTo train neural net you will enter each input/output vector pair");
  57. printf("\nan element at a time.");
  58.  
  59. printf("\n\nInput vectors have %d components each and outputs have %d\n",num_inputs, num_outputs);
  60.  
  61. while(1)
  62.     {
  63.     // get the input vector
  64.     printf("\nEnter input vector elements\n");
  65.  
  66.     for (int index=0; index<num_inputs; index++)
  67.         {
  68.         printf("Input Vector Element[%d]=?",index);
  69.         scanf("%f",&input_i[index]);
  70.         } // end for
  71.  
  72.     printf("\nNow enter associated output vector elements\n");
  73.  
  74.     // now get the output vector (note there might only be one neuron in this net
  75.  
  76.     for (index=0; index<num_outputs; index++)
  77.         {
  78.         printf("Output Vector Element[%d]=?",index);
  79.         scanf("%f",&output_i[index]);
  80.         } // end for
  81.  
  82.     // train the net with new vector, note we process one neuron at a time
  83.  
  84.     for (int index_j=0; index_j<num_outputs; index_j++)
  85.         {
  86.         for (int index_i=0; index_i<num_inputs; index_i++)
  87.             {
  88.             // hebb learning alg. wi=wi+input*ouput, b=b+output
  89.             
  90.             MAT(weight_matrix,num_outputs,index_i, index_j) += (input_i[index_i]*output_i[index_j]);
  91.             bias_bi[index_j] += output_i[index_i];
  92.  
  93.             } // end for index_i
  94.         } // end for index_j
  95.  
  96.     printf("\nDo you wish to enter another input/output pair Y or N?");
  97.     char ans[8];
  98.     scanf("%s",ans);
  99.     if (toupper(ans[0])!='Y')
  100.         break;
  101.  
  102.     } // end while
  103.  
  104. } // end Train_Net
  105.  
  106. //////////////////////////////////////////////////////////////////////////////////
  107.  
  108. void Run_Net(void)
  109. {
  110. // this function is responsible for running the net, it allows the user to enter test
  111. // vectors and then computes the response of the network
  112.  
  113. printf("\nNetwork Simulation System.");
  114. printf("\nYou will enter in test input vectors and the input will be processed by the net.");
  115. printf("\nAll inputs must have %d elements\n",num_inputs);
  116.  
  117. while(1)
  118.     {
  119.     // get the input vector
  120.     printf("\nEnter input vector elements\n");
  121.  
  122.     for (int index=0; index<num_inputs; index++)
  123.         {
  124.         printf("Input Vector Element[%d]=?",index);
  125.         scanf("%f",&input_i[index]);
  126.         } // end for
  127.  
  128.     // now process the input by performing a matrix mutiply
  129.     // each weight vector is stored as a column in the weight matrix, so to process
  130.     // the input for each neurode, we simply must perform a dot product, and then input
  131.     // the result to the activation function, this is the basis of the parallel 
  132.     // processing a neural net performs, all outputs are independent of the others
  133.  
  134.     // loop thru the columns (outputs, neurodes)
  135.     for (int index_j=0; index_j<num_outputs; index_j++)
  136.         {
  137.         // now compute a dot product with the input vector and the column
  138.  
  139.         input_act[index_j] = (float)0.0; // reset activation
  140.  
  141.         for (int index_i=0; index_i<num_inputs; index_i++)
  142.             {
  143.             input_act[index_j] = input_act[index_j] + 
  144.                 (MAT(weight_matrix,num_outputs,index_i, index_j) * input_i[index_i]);
  145.             } // end for index_i
  146.         
  147.         // add in bias term
  148.         input_act[index_j] = input_act[index_j] + bias_bi[index_j];
  149.  
  150.         // now compute output based on activation function
  151.  
  152.         if (activation_func==ACTF_STEP)
  153.             {
  154.             // perform step activation
  155.             if (input_act[index_j]>=(float)0.0)
  156.                 output_yi[index_j] = (float)1.0;
  157.             else
  158.                 output_yi[index_j] = (float)-1.0;
  159.  
  160.             } // end if
  161.         else
  162.         if (activation_func==ACTF_LINEAR)
  163.             {
  164.             // perform linear activation
  165.             output_yi[index_j] = input_act[index_j];
  166.             }
  167.         else
  168.             {
  169.             // must be exponential activation
  170.             output_yi[index_j] =(float)(1/(1+exp(-input_act[index_j]*alpha)));
  171.     
  172.             } // end else exp
  173.  
  174.         } // end for index_j
  175.  
  176.     // now that ouputs have been computed print everything out
  177.  
  178.     printf("\nNet inputs were:\n[");
  179.     for (index_j=0; index_j<num_outputs; index_j++)
  180.         printf("%2.2f, ",input_act[index_j]);
  181.     printf("]\n");
  182.     
  183.     printf("\nFinal Outputs after activation functions are:\n[");
  184.     for (index_j=0; index_j<num_outputs; index_j++)
  185.         printf("%2.2f, ",output_yi[index_j]);
  186.     printf("]\n");
  187.  
  188.     printf("\nDo you wish to enter another test input Y or N?");
  189.     char ans[8];
  190.     scanf("%s",ans);
  191.     if (toupper(ans[0])!='Y')
  192.         break;
  193.  
  194.     } // end while
  195.  
  196. } // end Run_Net
  197.  
  198. //////////////////////////////////////////////////////////////////////////////////
  199.  
  200. void Print_Net(void)
  201. {
  202. // this function prints out the current weight matrix and biases along with the specifics
  203. // about the net
  204.  
  205. printf("\nThe Hebb Net has %d inputs and %d outputs",num_inputs, num_outputs);
  206. printf("\nThe weight matrix is %dX%d",num_inputs, num_outputs);
  207. printf("\nThe W[i,j]th element refers to the weight from the ith to jth neurode\n");
  208.  
  209. for (int index_i = 0; index_i<num_inputs;index_i++)
  210.     {
  211.     printf("\n|");
  212.     for (int index_j=0; index_j<num_outputs; index_j++)
  213.         {
  214.         // data is in row major form
  215.         printf(" %2.2f ",MAT(weight_matrix,num_outputs,index_i,index_j));
  216.  
  217.         } // end for index_j
  218.  
  219.     printf("|");
  220.     
  221. } // end for index_row
  222.  
  223. printf("\n\nBias weights for the net are:\n[");
  224.  
  225. for (int index_j=0; index_j<num_outputs; index_j++)
  226.     printf("%2.2f, ",bias_bi[index_j]);
  227.  
  228. printf("]\n\n");
  229.  
  230. } // end Print_Net
  231.  
  232. //////////////////////////////////////////////////////////////////////////////////
  233.  
  234. void Reset_Net(void)
  235. {
  236. // clear out all the matrices
  237. memset(weight_matrix,0,num_inputs*num_outputs*sizeof(float));
  238. memset(bias_bi,0,MAX_OUTPUTS*sizeof(float));
  239.  
  240. } // end Reset_Net
  241.  
  242. // MAIN //////////////////////////////////////////////////////////////////////////
  243.  
  244. void main(void)
  245. {
  246. float FORCE_FP_LINK=(float)1.0; // needed for bug in VC++ fp lib link
  247.  
  248. printf("\nHebbian Neural Network Simulator.\n");
  249.  
  250. // querry user for parmaters of network
  251.  
  252. printf("\nEnter number of inputs?");
  253. scanf("%d",&num_inputs);
  254.  
  255. printf("\nEnter number of Neurons (outputs)?");
  256. scanf("%d",&num_outputs);
  257.  
  258. printf("\nSelect Activation Function (Hebbian usually uses Step)\n0=Step, 1=Linear, 2=Exponential?");
  259. scanf("%d",&activation_func);
  260.  
  261. // test for exponential, get alpha is needed
  262. if (activation_func == ACTF_EXP)
  263.     {
  264.     printf("\nEnter value for alpha (decimals allowed)?");
  265.     scanf("%f",&alpha);
  266.     } // end if
  267.  
  268. // allocate weight matrix it is mxn where m is the number of inputs and n is the
  269. // number of outputs
  270. weight_matrix = new float[num_inputs*num_outputs];
  271.  
  272. // clear out matrices
  273. Reset_Net();
  274.  
  275. // enter main event loop
  276.  
  277. int    sel=0,
  278.     done=0;
  279.  
  280. while(!done)
  281.     {
  282.     printf("\nHebb Net Main Menu\n");
  283.     printf("\n1. Input Training Vectors into Neural Net.");
  284.     printf("\n2. Run Neural Net.");
  285.     printf("\n3. Print Out Weight Matrix and Biases.");
  286.     printf("\n4. Reset Weight Matrix and Biases.");
  287.     printf("\n5. Exit Simulator.");
  288.     printf("\n\nSelect One Please?");
  289.     scanf("%d",&sel);
  290.  
  291.     // what was the selection
  292.     switch(sel)
  293.         {
  294.     
  295.         case 1: // Input Training Vectors into Neural Net
  296.             {
  297.             Train_Net();
  298.                 
  299.             } break;
  300.     
  301.         case 2: // Run Neural Net
  302.             {
  303.             Run_Net();
  304.             } break;
  305.     
  306.         case 3: // Print Out Weight Matrix and Biases
  307.             {
  308.             Print_Net();
  309.             } break;
  310.     
  311.         case 4: // Reset Weight Matrix and Biases
  312.             {
  313.             Reset_Net();
  314.             } break;
  315.     
  316.         case 5: // Exit Simulator
  317.             {
  318.             // set exit flag
  319.             done=1;
  320.  
  321.             } break;
  322.     
  323.         default:break;
  324.  
  325.         } // end swtich
  326.  
  327.     } // end while
  328.  
  329. // free up resources
  330.  
  331. delete [] weight_matrix;
  332.  
  333. } // end main
  334.