home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 306_01 / parity.c < prev    next >
C/C++ Source or Header  |  1991-02-21  |  8KB  |  243 lines

  1. /*******************************************************************************
  2.                                 PARITY.C
  3.                    COPYRIGHT 1988, 1989 GREGORY COLVIN.
  4.                             ALL RIGHTS RESERVED.
  5.  
  6. Pattern recognition demonstration.  Learn parity of input.
  7.  
  8. Suggested input for XOR:
  9.  
  10.     show intermediate results? (y/n):
  11.     n
  12.     enter number of input neurons (<= 8):
  13.     2
  14.     bias input? (y/n):
  15.     y
  16.     enter number of hidden neurons (<= 8):
  17.     3
  18.     enter max iterations/pattern:
  19.     1
  20.     enter learning rate (<= 100):
  21.     24
  22.     momentum? (y/n):
  23.     y
  24.     enter amount to randomize synapses (<=100):
  25.     20
  26.     enter seed:
  27.     1
  28.     enter number of learning trials:
  29.     200
  30.  
  31. *******************************************************************************/
  32.  
  33. #include <stdio.h>
  34. #include "synapsys.h"
  35.  
  36. #define N_INP 8
  37. #define N_HID 8
  38. #define N_OUT 1
  39.  
  40. static NEURON
  41.     Inputs[N_INP],
  42.     Hidden[N_HID],
  43.     Output;
  44.  
  45. static int Target;
  46.  
  47. static SYNAPSE Synapse1[N_INP*N_HID];
  48. static SYNAPSE Synapse2[N_HID*N_OUT];
  49. static SYNAPSE History1[N_INP*N_HID];
  50. static SYNAPSE History2[N_HID*N_OUT];
  51.  
  52. static LAYER
  53.     Layer1 = { 0,N_INP,Inputs,Synapse1,History1,0,0,N_HID,Hidden, 0 },
  54.     Layer2 = { 0,N_HID,Hidden,Synapse2,History2,0,0,N_OUT,&Output,0 };
  55.  
  56. static NETWORK
  57.     Network = { &Layer1, &Layer2 };
  58.  
  59. int parity( i )
  60. int i;
  61. {
  62.     int m,n;
  63.     for (n=0,m=0; i && m<8; m++,i>>=1)
  64.         if (i&1)
  65.             n++;
  66.     return (n&1);
  67. }
  68.  
  69. main()
  70. {
  71.     int verbose = 0, bias = 0;
  72.     char pat, n_pat;
  73.     int n_inp, n_out=N_OUT, n_hid;
  74.     int i, h, rate, momentum, maxrand;
  75.     long seed;
  76.     SYNAPSE *w;
  77.     int iter, maxiter, ntrials;
  78.     long m, n, err, sse1, sse2;
  79.     float oldsse, totsse1, totsse2, minsse1, minsse2;
  80.     char s[80];
  81.  
  82.     for(;;)
  83.     {
  84.  
  85.         printf( "show intermediate results? (y/n):\n" );
  86.         gets(s);
  87.         if (strpbrk(s,"yY")) verbose = 1;
  88.         else verbose = 0;
  89.  
  90.         printf( "enter number of input neurons (<= %d):\n", N_INP );
  91.         gets(s), sscanf( s, "%d", &n_inp );
  92.         n_pat = 1 << n_inp;
  93.         printf( "bias input? (y/n):\n" );
  94.         gets(s);
  95.         if (strpbrk(s,"yY")) n_inp++, bias = 1;
  96.         else if (bias) n_inp--, bias = 0;
  97.  
  98.         printf( "enter number of hidden neurons (<= %d):\n", N_HID );
  99.         gets(s), sscanf( s, "%d", &n_hid );
  100.  
  101.         printf( "enter max iterations/pattern:\n" );
  102.         gets(s), sscanf( s, "%d", &maxiter );
  103.  
  104.         printf( "enter learning rate (<= 100):\n" );
  105.         gets(s), sscanf( s, "%d", &rate );
  106.  
  107.         printf( "momentum? (y/n):\n" );
  108.         gets(s);
  109.         if (strpbrk(s,"nN")) momentum = 0;
  110.         else momentum = 1;
  111.  
  112.         printf("enter amount to randomize synapses (<=100):\n");
  113.         gets(s), sscanf( s, "%d", &maxrand );
  114.         if (maxrand > 0)
  115.         {   printf( "enter seed:\n");
  116.             gets(s), sscanf( s,"%d", &seed );
  117.         }
  118.  
  119.         printf( "enter number of learning trials:\n" );
  120.         gets(s), sscanf( s, "%d", &ntrials );
  121.  
  122.         if (bias) printf( "%d inputs, bias, %d hidden", n_inp-1, n_hid );
  123.         else printf( "%d inputs, no bias, %d hidden", n_inp, n_hid );
  124.         printf( " maxrand: %d seed: %d\n", maxrand, seed );
  125.         printf( "learning rate: %d momentum: %d maxiter: %d\n\n",
  126.                         rate, momentum, maxiter );
  127.  
  128.         Network.first_layer->next_layer = Network.last_layer;
  129.         Network.first_layer->n_outputs = n_hid;
  130.         Network.first_layer->n_inputs = n_inp;
  131.         Network.first_layer->rate = rate;
  132.         Network.first_layer->momentum = momentum;
  133.         Network.last_layer->prev_layer = Network.first_layer;
  134.         Network.last_layer->n_inputs = n_hid;
  135.         Network.last_layer->n_outputs = n_out;
  136.         Network.last_layer->momentum = momentum;
  137.         Network.last_layer->rate = rate;
  138.  
  139.         clear( &Network );
  140.  
  141.         randomize( &Network, maxrand, seed );
  142.  
  143.         for (oldsse=minsse1=minsse2=2000000, m=1, n=1; n <= ntrials; n++)
  144.         {
  145.             for (totsse1=totsse2=0, pat=0; pat < n_pat; pat++)
  146.             {
  147.                 for (sse1=2000001, sse2=2000000, iter=0;
  148.                      iter < maxiter /*&& sse1 > sse2*/;
  149.                      iter++,m++)
  150.                 {
  151.                     sse1 = sse2;
  152.  
  153.                     Target = parity(pat) ? 100 : -100;
  154.  
  155.                     if (verbose) printf( "\nINPUTS:\n" );
  156.                     for (i=0; i < n_inp; i++)
  157.                     {
  158.                         if (bias && i+1 == n_inp)
  159.                         {   Inputs[i].activation = 127;
  160.                             if (verbose) printf( "%d",Inputs[i].activation );
  161.                         }
  162.                         else if (pat & (1 << i))
  163.                         {   Inputs[i].activation = 100;
  164.                             if (verbose) printf("%d ",Inputs[i].activation );
  165.                         }
  166.                         else
  167.                         {   Inputs[i].activation = -100;
  168.                             if (verbose) printf("%d ",Inputs[i].activation);
  169.                         }
  170.                     }
  171.                     if (verbose) printf( "\n" );
  172.  
  173.                     feedforward( &Network );
  174.  
  175.                     if (verbose)
  176.                     {
  177.                         printf( "SYNAPSES:\n" );
  178.                         for (w=Synapse1, h = 0; h < n_hid; h++)
  179.                         {
  180.                             for (i = 0; i < n_inp; i++,w++)
  181.                                 printf( "%5d ", (int)*w);
  182.                             printf( "\n" );
  183.                         }
  184.                         printf( "HIDDEN:\n" );
  185.                         for (h = 0; h < n_hid; h++)
  186.                             printf("%5d ",Hidden[h].activation);
  187.                         printf( "\nSYNAPSES:\n" );
  188.                         for (w=Synapse2,h = 0; h < n_hid; h++,w++)
  189.                             printf( "%5d ", (int)*w);
  190.                         printf("\n");
  191.                     }
  192.  
  193.                     err = Target - Output.activation;
  194.                     Output.errors = err;
  195.                     sse2 = err * err;
  196.                         if (iter == 0) totsse1 += sse2;
  197.  
  198.                     if (verbose)
  199.                     {
  200.                         printf( "RESULTS:\n" );
  201.                         printf(
  202.                           "  pattern: %d output: %d target: %d error: %ld\n",
  203.                           pat, Output.activation,  parity(pat)?100:-100, err );
  204.                     }
  205.  
  206.                     feedback( &Network );
  207.  
  208.                     if (verbose && momentum)
  209.                     {
  210.                         printf( "MOMENTUM:\n" );
  211.                         for (w=History1,h=0; h < n_hid; h++)
  212.                         {
  213.                             for (i = 0; i < n_inp; i++,w++)
  214.                                 printf( "%5d ", (int)*w);
  215.                             printf( "\n" );
  216.                         }
  217.                         printf("\n");
  218.                         for (w=History2,h=0; h < n_hid; h++,w++)
  219.                             printf( "%5d ", (int)*w);
  220.                         printf("\n\n");
  221.                     }
  222.                 }
  223.                 totsse2 += sse2;
  224.             }
  225.             oldsse = totsse1;
  226.  
  227.             if (totsse2 < minsse2)
  228.                 minsse2 = totsse2;
  229.             if (totsse1 < minsse1)
  230.                 minsse1 = totsse1;
  231.  
  232.             printf(
  233.               "N: %5ld M: %5ld MSE1: %9.1f %9.1f MSE2: %9.1f %9.1f\n",
  234.               n, m, totsse1/n_pat, minsse1/n_pat, totsse2/n_pat, minsse2/n_pat);
  235.         }
  236.  
  237.         printf( "exit? (y/n):\n");
  238.         gets(s); if (strpbrk(s,"yY"))
  239.             break;
  240.     }
  241.     exit(0);
  242. }
  243.