ADALINE.C
上传用户:yyh163
上传日期:2022-07-27
资源大小:5k
文件大小:14k
开发平台:

Visual C++

  1. /******************************************************************************
  2.                       ===============
  3.         Network:      Adaline Network
  4.                       ===============
  5.         Application:  Pattern Recognition
  6.                       Classification of Digits 0-9
  7.         Author:       Karsten Kutza
  8.         Date:         15.4.96
  9.         Reference:    B. Widrow, M.E. Hoff
  10.                       Adaptive Switching Circuits
  11.                       1960 IRE WESCON Convention Record, IRE, New York, NY,
  12.                       pp. 96-104, 1960
  13.  ******************************************************************************/
  14. /******************************************************************************
  15.                             D E C L A R A T I O N S
  16.  ******************************************************************************/
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. typedef int           BOOL;
  20. typedef char          CHAR;
  21. typedef int           INT;
  22. typedef double        REAL;
  23. #define FALSE         0
  24. #define TRUE          1
  25. #define NOT           !
  26. #define AND           &&
  27. #define OR            ||
  28. #define MIN(x,y)      ((x)<(y) ? (x) : (y))
  29. #define MAX(x,y)      ((x)>(y) ? (x) : (y))
  30. #define LO            -1
  31. #define HI            +1
  32. #define BIAS           1
  33. #define sqr(x)        ((x)*(x))
  34. typedef struct {                     /* A LAYER OF A NET:                     */
  35.         INT           Units;         /* - number of units in this layer       */
  36.         REAL*         Activation;    /* - activation of ith unit              */
  37.         INT*          Output;        /* - output of ith unit                  */
  38.         REAL*         Error;         /* - error term of ith unit              */
  39.         REAL**        Weight;        /* - connection weights to ith unit      */
  40. } LAYER;
  41. typedef struct {                     /* A NET:                                */
  42.         LAYER*        InputLayer;    /* - input layer                         */
  43.         LAYER*        OutputLayer;   /* - output layer                        */
  44.         REAL          Eta;           /* - learning rate                       */
  45.         REAL          Error;         /* - total net error                     */
  46.         REAL          Epsilon;       /* - net error to terminate training     */
  47. } NET;
  48. /******************************************************************************
  49.         R A N D O M S   D R A W N   F R O M   D I S T R I B U T I O N S
  50.  ******************************************************************************/
  51. void InitializeRandoms()
  52. {
  53.   srand(4711);
  54. }
  55. INT RandomEqualINT(INT Low, INT High)
  56. {
  57.   return rand() % (High-Low+1) + Low;
  58. }      
  59. REAL RandomEqualREAL(REAL Low, REAL High)
  60. {
  61.   return ((REAL) rand() / RAND_MAX) * (High-Low) + Low;
  62. }      
  63. /******************************************************************************
  64.                A P P L I C A T I O N - S P E C I F I C   C O D E
  65.  ******************************************************************************/
  66. #define NUM_DATA      10
  67. #define X             5
  68. #define Y             7
  69. #define N             (X * Y)
  70. #define M             10
  71. CHAR                  Pattern[NUM_DATA][Y][X] = { { " OOO ",
  72.                                                     "O   O",
  73.                                                     "O   O",
  74.                                                     "O   O",
  75.                                                     "O   O",
  76.                                                     "O   O",
  77.                                                     " OOO "  },
  78.                                                   { "  O  ",
  79.                                                     " OO  ",
  80.                                                     "O O  ",
  81.                                                     "  O  ",
  82.                                                     "  O  ",
  83.                                                     "  O  ",
  84.                                                     "  O  "  },
  85.                                                   { " OOO ",
  86.                                                     "O   O",
  87.                                                     "    O",
  88.                                                     "   O ",
  89.                                                     "  O  ",
  90.                                                     " O   ",
  91.                                                     "OOOOO"  },
  92.                                                   { " OOO ",
  93.                                                     "O   O",
  94.                                                     "    O",
  95.                                                     " OOO ",
  96.                                                     "    O",
  97.                                                     "O   O",
  98.                                                     " OOO "  },
  99.                                                   { "   O ",
  100.                                                     "  OO ",
  101.                                                     " O O ",
  102.                                                     "O  O ",
  103.                                                     "OOOOO",
  104.                                                     "   O ",
  105.                                                     "   O "  },
  106.                                                   { "OOOOO",
  107.                                                     "O    ",
  108.                                                     "O    ",
  109.                                                     "OOOO ",
  110.                                                     "    O",
  111.                                                     "O   O",
  112.                                                     " OOO "  },
  113.                                                   { " OOO ",
  114.                                                     "O   O",
  115.                                                     "O    ",
  116.                                                     "OOOO ",
  117.                                                     "O   O",
  118.                                                     "O   O",
  119.                                                     " OOO "  },
  120.                                                   { "OOOOO",
  121.                                                     "    O",
  122.                                                     "    O",
  123.                                                     "   O ",
  124.                                                     "  O  ",
  125.                                                     " O   ",
  126.                                                     "O    "  },
  127.                                                   { " OOO ",
  128.                                                     "O   O",
  129.                                                     "O   O",
  130.                                                     " OOO ",
  131.                                                     "O   O",
  132.                                                     "O   O",
  133.                                                     " OOO "  },
  134.                                                   { " OOO ",
  135.                                                     "O   O",
  136.                                                     "O   O",
  137.                                                     " OOOO",
  138.                                                     "    O",
  139.                                                     "O   O",
  140.                                                     " OOO "  } };
  141. INT                   Input [NUM_DATA][N];
  142. INT                   Output[NUM_DATA][M] =
  143.                       
  144.                                   { {HI, LO, LO, LO, LO, LO, LO, LO, LO, LO},
  145.                                     {LO, HI, LO, LO, LO, LO, LO, LO, LO, LO},
  146.                                     {LO, LO, HI, LO, LO, LO, LO, LO, LO, LO},
  147.                                     {LO, LO, LO, HI, LO, LO, LO, LO, LO, LO},
  148.                                     {LO, LO, LO, LO, HI, LO, LO, LO, LO, LO},
  149.                                     {LO, LO, LO, LO, LO, HI, LO, LO, LO, LO},
  150.                                     {LO, LO, LO, LO, LO, LO, HI, LO, LO, LO},
  151.                                     {LO, LO, LO, LO, LO, LO, LO, HI, LO, LO},
  152.                                     {LO, LO, LO, LO, LO, LO, LO, LO, HI, LO},
  153.                                     {LO, LO, LO, LO, LO, LO, LO, LO, LO, HI}  };
  154. FILE*                 f;
  155. void InitializeApplication(NET* Net)
  156. {
  157.   INT n,i,j;
  158.   Net->Eta     = 0.001;
  159.   Net->Epsilon = 0.0001;
  160.   for (n=0; n<NUM_DATA; n++) {
  161.     for (i=0; i<Y; i++) {
  162.       for (j=0; j<X; j++) {
  163.         Input[n][i*X+j] = (Pattern[n][i][j] == 'O') ? HI : LO;
  164.       }
  165.     }
  166.   }
  167.   f = fopen("ADALINE.txt", "w");
  168. }
  169. void WriteInput(NET* Net, INT* Input)
  170. {
  171.   INT i;
  172.    
  173.   for (i=0; i<N; i++) {
  174.     if (i%X == 0) {
  175.       fprintf(f, "n");
  176.     }
  177.     fprintf(f, "%c", (Input[i] == HI) ? 'O' : ' ');
  178.   }
  179.   fprintf(f, " -> ");
  180. }
  181. void WriteOutput(NET* Net, INT* Output)
  182. {
  183.   INT i;
  184.   INT Count, Index;
  185.    
  186.   Count = 0;
  187.   for (i=0; i<M; i++) {
  188.     if (Output[i] == HI) {
  189.       Count++;
  190.       Index = i;
  191.     }
  192.   }
  193.   if (Count == 1)
  194.     fprintf(f, "%in", Index);
  195.   else
  196.     fprintf(f, "%sn", "invalid");
  197. }
  198. void FinalizeApplication(NET* Net)
  199. {
  200.   fclose(f);
  201. }
  202. /******************************************************************************
  203.                           I N I T I A L I Z A T I O N
  204.  ******************************************************************************/
  205. void GenerateNetwork(NET* Net)
  206. {
  207.   INT i;
  208.   Net->InputLayer  = (LAYER*) malloc(sizeof(LAYER));
  209.   Net->OutputLayer = (LAYER*) malloc(sizeof(LAYER));
  210.   Net->InputLayer->Units       = N;
  211.   Net->InputLayer->Output      = (INT*)   calloc(N+1, sizeof(INT));
  212.   Net->InputLayer->Output[0]   = BIAS;
  213.   Net->OutputLayer->Units      = M;
  214.   Net->OutputLayer->Activation = (REAL*)  calloc(M+1, sizeof(REAL));
  215.   Net->OutputLayer->Output     = (INT*)   calloc(M+1, sizeof(INT));
  216.   Net->OutputLayer->Error      = (REAL*)  calloc(M+1, sizeof(REAL));
  217.   Net->OutputLayer->Weight     = (REAL**) calloc(M+1, sizeof(REAL*));
  218.       
  219.   for (i=1; i<=M; i++) {
  220.     Net->OutputLayer->Weight[i] = (REAL*) calloc(N+1, sizeof(REAL));
  221.   }
  222.   Net->Eta     = 0.1;
  223.   Net->Epsilon = 0.01;
  224. }
  225. void RandomWeights(NET* Net)
  226. {
  227.   INT i,j;
  228.    
  229.   for (i=1; i<=Net->OutputLayer->Units; i++) {
  230.     for (j=0; j<=Net->InputLayer->Units; j++) {
  231.       Net->OutputLayer->Weight[i][j] = RandomEqualREAL(-0.5, 0.5);
  232.     }
  233.   }
  234. }
  235. void SetInput(NET* Net, INT* Input, BOOL Protocoling)
  236. {
  237.   INT i;
  238.    
  239.   for (i=1; i<=Net->InputLayer->Units; i++) {
  240.     Net->InputLayer->Output[i] = Input[i-1];
  241.   }
  242.   if (Protocoling) {
  243.     WriteInput(Net, Input);
  244.   }
  245. }
  246. void GetOutput(NET* Net, INT* Output, BOOL Protocoling)
  247. {
  248.   INT i;
  249.    
  250.   for (i=1; i<=Net->OutputLayer->Units; i++) {
  251.     Output[i-1] = Net->OutputLayer->Output[i];
  252.   }
  253.   if (Protocoling) {
  254.     WriteOutput(Net, Output);
  255.   }
  256. }
  257. /******************************************************************************
  258.                      P R O P A G A T I N G   S I G N A L S
  259.  ******************************************************************************/
  260. void PropagateNet(NET* Net)
  261. {
  262.   INT  i,j;
  263.   REAL Sum;
  264.   for (i=1; i<=Net->OutputLayer->Units; i++) {
  265.     Sum = 0;
  266.     for (j=0; j<=Net->InputLayer->Units; j++) {
  267.       Sum += Net->OutputLayer->Weight[i][j] * Net->InputLayer->Output[j];
  268.     }
  269.     Net->OutputLayer->Activation[i] = Sum;
  270.     if (Sum >= 0)
  271.       Net->OutputLayer->Output[i] = HI;
  272.     else
  273.       Net->OutputLayer->Output[i] = LO;
  274.   }
  275. }
  276. /******************************************************************************
  277.                        A D J U S T I N G   W E I G H T S
  278.  ******************************************************************************/
  279. void ComputeOutputError(NET* Net, INT* Target)
  280. {
  281.   INT  i;
  282.   REAL Err;
  283.    
  284.   Net->Error = 0;
  285.   for (i=1; i<=Net->OutputLayer->Units; i++) {
  286.     Err = Target[i-1] - Net->OutputLayer->Activation[i];
  287.     Net->OutputLayer->Error[i] = Err;
  288.     Net->Error += 0.5 * sqr(Err);
  289.   }
  290. }
  291. void AdjustWeights(NET* Net)
  292. {
  293.   INT  i,j;
  294.   INT  Out;
  295.   REAL Err;
  296.    
  297.   for (i=1; i<=Net->OutputLayer->Units; i++) {
  298.     for (j=0; j<=Net->InputLayer->Units; j++) {
  299.       Out = Net->InputLayer->Output[j];
  300.       Err = Net->OutputLayer->Error[i];
  301.       Net->OutputLayer->Weight[i][j] += Net->Eta * Err * Out;
  302.     }
  303.   }
  304. }
  305. /******************************************************************************
  306.                       S I M U L A T I N G   T H E   N E T
  307.  ******************************************************************************/
  308. void SimulateNet(NET* Net, INT* Input, INT* Target, BOOL Training, BOOL Protocoling)
  309. {
  310.   INT Output[M];
  311.    
  312.   SetInput(Net, Input, Protocoling);
  313.   PropagateNet(Net);
  314.   GetOutput(Net, Output, Protocoling);
  315.    
  316.   ComputeOutputError(Net, Target);
  317.   if (Training)
  318.     AdjustWeights(Net);
  319. }
  320. /******************************************************************************
  321.                                     M A I N
  322.  ******************************************************************************/
  323. void main()
  324. {
  325.   NET  Net;
  326.   REAL Error;
  327.   BOOL Stop;
  328.   INT  n,m;
  329.   InitializeRandoms();
  330.   GenerateNetwork(&Net);
  331.   RandomWeights(&Net);
  332.   InitializeApplication(&Net);
  333.    
  334.   do {
  335.     Error = 0;
  336.     Stop = TRUE;
  337.     for (n=0; n<NUM_DATA; n++) {
  338.       SimulateNet(&Net, Input[n], Output[n], FALSE, FALSE);
  339.       Error = MAX(Error, Net.Error);
  340.       Stop = Stop AND (Net.Error < Net.Epsilon);
  341.     }
  342.     Error = MAX(Error, Net.Epsilon);
  343.     printf("Training %0.0f%% completed ...n", (Net.Epsilon / Error) * 100);
  344.     if (NOT Stop) {
  345.       for (m=0; m<10*NUM_DATA; m++) {
  346.         n = RandomEqualINT(0, NUM_DATA-1);      
  347.         SimulateNet(&Net, Input[n], Output[n], TRUE, FALSE);
  348.       }
  349.     }
  350.   } while (NOT Stop);
  351.    
  352.   for (n=0; n<NUM_DATA; n++) {
  353.     SimulateNet(&Net, Input[n], Output[n], FALSE, TRUE);
  354.   }
  355.    
  356.   FinalizeApplication(&Net);
  357. }