声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2557|回复: 5

[人工智能] 经典的SOM人工神经网络例子源码

[复制链接]
发表于 2007-7-6 02:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
  1. /******************************************************************************

  2.                       ===================
  3.         Network:      Self-Organizing Map
  4.                       ===================

  5.         Application:  Control
  6.                       Pole Balancing Problem

  7.         Author:       Karsten Kutza
  8.         Date:         6.6.96

  9.         Reference:    T. Kohonen   
  10.                       Self-Organized Formation
  11.                       of Topologically Correct Feature Maps
  12.                       Biological Cybernetics, 43, pp. 59-69, 1982

  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. #include <math.h>


  20. typedef int           BOOL;
  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_REAL      -HUGE_VAL
  29. #define MAX_REAL      +HUGE_VAL
  30. #define MIN(x,y)      ((x)<(y) ? (x) : (y))
  31. #define MAX(x,y)      ((x)>(y) ? (x) : (y))

  32. #define PI            (2*asin(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*         Output;        /* - output of ith unit                  */
  37.         REAL**        Weight;        /* - connection weights to ith unit      */
  38.         REAL*         StepSize;      /* - size of search steps of ith unit    */
  39.         REAL*         dScoreMean;    /* - mean score delta of ith unit        */
  40. } LAYER;

  41. typedef struct {                     /* A NET:                                */
  42.         LAYER*        InputLayer;    /* - input layer                         */
  43.         LAYER*        KohonenLayer;  /* - Kohonen layer                       */
  44.         LAYER*        OutputLayer;   /* - output layer                        */
  45.         INT           Winner;        /* - last winner in Kohonen layer        */
  46.         REAL          Alpha;         /* - learning rate for Kohonen layer     */
  47.         REAL          Alpha_;        /* - learning rate for output layer      */
  48.         REAL          Alpha__;       /* - learning rate for step sizes        */
  49.         REAL          Gamma;         /* - smoothing factor for score deltas   */
  50.         REAL          Sigma;         /* - parameter for width of neighborhood */
  51. } NET;


  52. /******************************************************************************
  53.         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
  54. ******************************************************************************/


  55. void InitializeRandoms()
  56. {
  57.   srand(4715);
  58. }      


  59. REAL RandomEqualREAL(REAL Low, REAL High)
  60. {
  61.   return ((REAL) rand() / RAND_MAX) * (High-Low) + Low;
  62. }      


  63. REAL RandomNormalREAL(REAL Mu, REAL Sigma)
  64. {
  65.   REAL x,fx;

  66.   do {
  67.     x = RandomEqualREAL(Mu-3*Sigma, Mu+3*Sigma);
  68.     fx = (1 / (sqrt(2*PI)*Sigma)) * exp(-sqr(x-Mu) / (2*sqr(Sigma)));
  69.   } while (fx < RandomEqualREAL(0, 1));
  70.   return x;
  71. }     
复制代码
回复
分享到:

使用道具 举报

 楼主| 发表于 2007-7-6 02:46 | 显示全部楼层
  1. /******************************************************************************
  2.                A P P L I C A T I O N - S P E C I F I C   C O D E
  3. ******************************************************************************/


  4. #define ROWS          25
  5. #define COLS          25

  6. #define N             2
  7. #define C             (ROWS * COLS)
  8. #define M             1

  9. #define TRAIN_STEPS   10000
  10. #define BALANCED      100

  11. FILE*                 f;


  12. void InitializeApplication(NET* Net)
  13. {
  14.   INT i;
  15.    
  16.   for (i=0; i<Net->KohonenLayer->Units; i++) {
  17.     Net->KohonenLayer->StepSize[i] = 1;
  18.     Net->KohonenLayer->dScoreMean[i] = 0;
  19.   }
  20.   f = fopen("SOM.txt", "w");
  21. }


  22. void WriteNet(NET* Net)
  23. {
  24.   INT  r,c;
  25.   REAL x,y,z;

  26.   fprintf(f, "\n\n\n");
  27.   for (r=0; r<ROWS; r++) {
  28.     for (c=0; c<COLS; c++) {
  29.       x = Net->KohonenLayer->Weight[r*ROWS+c][0];
  30.       y = Net->KohonenLayer->Weight[r*ROWS+c][1];
  31.       z = Net->OutputLayer->Weight[0][r*ROWS+c];
  32.       fprintf(f, "([%5.1f? %5.1f癩, %5.1fN)    ", x, y, z);
  33.     }
  34.     fprintf(f, "\n");
  35.   }
  36. }


  37. void FinalizeApplication(NET* Net)
  38. {
  39.   fclose(f);
  40. }


  41. /******************************************************************************
  42.                      S I M U L A T I N G   T H E   P O L E
  43. ******************************************************************************/

  44.                                      /* SIMULATION PARAMETERS FOR THE POLE:   */
  45. #define L             1              /* - length of pole [m]                  */
  46. #define Mc            1              /* - mass of cart [kg]                   */
  47. #define Mp            1              /* - mass of pole [kg]                   */
  48. #define G             9.81           /* - acceleration due to gravity [m/s瞉  */
  49. #define T             0.1            /* - time step [s]                       */
  50. #define STEPS         10             /* - simulation steps in one time step   */


  51. typedef struct {                     /* STATE VARIABLES OF A POLE:            */
  52.         REAL          x;             /* - position of cart [m]                */
  53.         REAL          xDot;          /* - velocity of cart [m/s]              */
  54.         REAL          w;             /* - angle of pole [癩                   */
  55.         REAL          wDot;          /* - angular velocity of pole [?s]      */
  56.         REAL          F;             /* - force applied to cart               */
  57. } POLE;                              /*   during current time step [N]        */


  58. void InitializePole(POLE* Pole)
  59. {
  60.   do {
  61.     Pole->x    = 0;
  62.     Pole->xDot = 0;
  63.     Pole->w    = RandomEqualREAL(-30, 30);
  64.     Pole->wDot = 0;
  65.     Pole->F    = 0;
  66.   } while (Pole->w == 0);
  67. }


  68. void SimulatePole(POLE* Pole)
  69. {
  70.   INT  s;
  71.   REAL x, xDot, xDotDot;           
  72.   REAL w, wDot, wDotDot;                  
  73.   REAL F;                    

  74.   x    = Pole->x;
  75.   xDot = Pole->xDot;
  76.   w    = (Pole->w    / 180) * PI;
  77.   wDot = (Pole->wDot / 180) * PI;
  78.   F    = Pole->F;
  79.   for (s=0; s<STEPS; s++) {

  80.     wDotDot = (G*sin(w) + cos(w) * ((-F - Mp*L*sqr(wDot)*sin(w)) / (Mc+Mp))) /
  81.               (L * ((REAL) 4/3 - (Mp*sqr(cos(w))) / (Mc+Mp)));

  82.     xDotDot = (F + Mp*L * (sqr(wDot)*sin(w) - wDotDot*cos(w))) / (Mc+Mp);

  83.     x    += (T / STEPS) * xDot;
  84.     xDot += (T / STEPS) * xDotDot;
  85.     w    += (T / STEPS) * wDot;
  86.     wDot += (T / STEPS) * wDotDot;
  87.   }
  88.   Pole->x    = x;
  89.   Pole->xDot = xDot;
  90.   Pole->w    = (w    / PI) * 180;
  91.   Pole->wDot = (wDot / PI) * 180;
  92. }


  93. BOOL PoleStillBalanced(POLE* Pole)
  94. {
  95.   return (Pole->w >= -60) AND (Pole->w <= 60);
  96. }


  97. REAL ScoreOfPole(POLE* Pole)
  98. {
  99.   return -sqr(Pole->w);
  100. }
复制代码
 楼主| 发表于 2007-7-6 02:46 | 显示全部楼层
  1. /******************************************************************************
  2.                           I N I T I A L I Z A T I O N
  3. ******************************************************************************/


  4. void GenerateNetwork(NET* Net)
  5. {
  6.   INT i;

  7.   Net->InputLayer   = (LAYER*) malloc(sizeof(LAYER));
  8.   Net->KohonenLayer = (LAYER*) malloc(sizeof(LAYER));
  9.   Net->OutputLayer  = (LAYER*) malloc(sizeof(LAYER));

  10.   Net->InputLayer->Units        = N;
  11.   Net->InputLayer->Output       = (REAL*)  calloc(N, sizeof(REAL));
  12.       
  13.   Net->KohonenLayer->Units      = C;
  14.   Net->KohonenLayer->Output     = (REAL*)  calloc(C, sizeof(REAL));
  15.   Net->KohonenLayer->Weight     = (REAL**) calloc(C, sizeof(REAL*));
  16.   Net->KohonenLayer->StepSize   = (REAL*)  calloc(C, sizeof(REAL));
  17.   Net->KohonenLayer->dScoreMean = (REAL*)  calloc(C, sizeof(REAL));
  18.       
  19.   Net->OutputLayer->Units       = M;
  20.   Net->OutputLayer->Output      = (REAL*)  calloc(M, sizeof(REAL));
  21.   Net->OutputLayer->Weight      = (REAL**) calloc(M, sizeof(REAL*));
  22.       
  23.   for (i=0; i<C; i++) {
  24.     Net->KohonenLayer->Weight[i] = (REAL*) calloc(N, sizeof(REAL));
  25.   }
  26.   for (i=0; i<M; i++) {
  27.     Net->OutputLayer->Weight[i] = (REAL*) calloc(C, sizeof(REAL));
  28.   }
  29. }


  30. void RandomWeights(NET* Net)
  31. {
  32.   INT i,j;
  33.    
  34.   for (i=0; i<Net->KohonenLayer->Units; i++) {
  35.     for (j=0; j<Net->InputLayer->Units; j++) {
  36.       Net->KohonenLayer->Weight[i][j] = RandomEqualREAL(-30, 30);
  37.     }
  38.   }
  39.   for (i=0; i<Net->OutputLayer->Units; i++) {
  40.     for (j=0; j<Net->KohonenLayer->Units; j++) {
  41.       Net->OutputLayer->Weight[i][j] = 0;
  42.     }
  43.   }
  44. }


  45. void SetInput(NET* Net, REAL* Input)
  46. {
  47.   INT i;
  48.    
  49.   for (i=0; i<Net->InputLayer->Units; i++) {
  50.     Net->InputLayer->Output[i] = Input[i];
  51.   }
  52. }


  53. void GetOutput(NET* Net, REAL* Output)
  54. {
  55.   INT i;
  56.    
  57.   for (i=0; i<Net->OutputLayer->Units; i++) {
  58.     Output[i] = Net->OutputLayer->Output[i];
  59.   }
  60. }


  61. /******************************************************************************
  62.                      P R O P A G A T I N G   S I G N A L S
  63. ******************************************************************************/


  64. void PropagateToKohonen(NET* Net)
  65. {
  66.   INT  i,j;
  67.   REAL Out, Weight, Sum, MinOut;

  68.   for (i=0; i<Net->KohonenLayer->Units; i++) {
  69.     Sum = 0;
  70.     for (j=0; j<Net->InputLayer->Units; j++) {
  71.       Out = Net->InputLayer->Output[j];
  72.       Weight = Net->KohonenLayer->Weight[i][j];
  73.       Sum += sqr(Out - Weight);
  74.     }
  75.     Net->KohonenLayer->Output[i] = sqrt(Sum);
  76.   }
  77.   MinOut = MAX_REAL;
  78.   for (i=0; i<Net->KohonenLayer->Units; i++) {
  79.     if (Net->KohonenLayer->Output[i] < MinOut)
  80.       MinOut = Net->KohonenLayer->Output[Net->Winner = i];
  81.   }
  82. }


  83. void PropagateToOutput(NET* Net)
  84. {
  85.   INT i;

  86.   for (i=0; i<Net->OutputLayer->Units; i++) {
  87.     Net->OutputLayer->Output[i] = Net->OutputLayer->Weight[i][Net->Winner];
  88.   }
  89. }


  90. void PropagateNet(NET* Net)
  91. {
  92.   PropagateToKohonen(Net);
  93.   PropagateToOutput(Net);
  94. }
复制代码
 楼主| 发表于 2007-7-6 02:46 | 显示全部楼层
  1. /******************************************************************************
  2.                         T R A I N I N G   T H E   N E T
  3. ******************************************************************************/


  4. REAL Neighborhood(NET* Net, INT i)
  5. {
  6.   INT  iRow, iCol, jRow, jCol;
  7.   REAL Distance;

  8.   iRow = i / COLS; jRow = Net->Winner / COLS;
  9.   iCol = i % COLS; jCol = Net->Winner % COLS;

  10.   Distance = sqrt(sqr(iRow-jRow) + sqr(iCol-jCol));

  11.   return exp(-sqr(Distance) / (2*sqr(Net->Sigma)));
  12. }


  13. void TrainKohonen(NET* Net, REAL* Input)
  14. {
  15.   INT  i,j;
  16.   REAL Out, Weight, Lambda, StepSize;

  17.   for (i=0; i<Net->KohonenLayer->Units; i++) {
  18.     for (j=0; j<Net->InputLayer->Units; j++) {
  19.       Out = Input[j];
  20.       Weight = Net->KohonenLayer->Weight[i][j];
  21.       Lambda = Neighborhood(Net, i);
  22.       Net->KohonenLayer->Weight[i][j] += Net->Alpha * Lambda * (Out - Weight);
  23.     }
  24.     StepSize = Net->KohonenLayer->StepSize[i];
  25.     Net->KohonenLayer->StepSize[i] += Net->Alpha__ * Lambda * -StepSize;
  26.   }
  27. }


  28. void TrainOutput(NET* Net, REAL* Output)
  29. {
  30.   INT  i,j;
  31.   REAL Out, Weight, Lambda;

  32.   for (i=0; i<Net->OutputLayer->Units; i++) {
  33.     for (j=0; j<Net->KohonenLayer->Units; j++) {
  34.       Out = Output[i];
  35.       Weight = Net->OutputLayer->Weight[i][j];
  36.       Lambda = Neighborhood(Net, j);
  37.       Net->OutputLayer->Weight[i][j] += Net->Alpha_ * Lambda * (Out - Weight);
  38.     }
  39.   }
  40. }


  41. void TrainUnits(NET* Net, REAL* Input, REAL* Output)
  42. {
  43.   TrainKohonen(Net, Input);
  44.   TrainOutput(Net, Output);
  45. }


  46. void TrainNet(NET* Net)
  47. {
  48.   INT  n,t;
  49.   POLE Pole;
  50.   REAL wOld, wNew, ScoreOld, ScoreNew, dScore, dScoreMean, StepSize;
  51.   REAL Input[N];
  52.   REAL Output[M];
  53.   REAL Target[M];

  54.   n = 0;
  55.   while (n<TRAIN_STEPS) {
  56.     t = 0;
  57.     InitializePole(&Pole);
  58.     fprintf(f, " Time     Angle     Force\n");
  59.     fprintf(f, "%4.1fs    %5.1f?   %5.1fN\n", t * T, Pole.w, Pole.F);
  60.     wOld = Pole.w;
  61.     ScoreOld = ScoreOfPole(&Pole);
  62.     SimulatePole(&Pole);
  63.     wNew = Pole.w;
  64.     ScoreNew = ScoreOfPole(&Pole);
  65.     while (PoleStillBalanced(&Pole) AND (t<BALANCED)) {
  66.       n++;
  67.       t++;
  68.       Net->Alpha   = 0.5 * pow(0.01, (REAL) n / TRAIN_STEPS);
  69.       Net->Alpha_  = 0.5 * pow(0.01, (REAL) n / TRAIN_STEPS);
  70.       Net->Alpha__ = 0.005;
  71.       Net->Gamma   = 0.05;
  72.       Net->Sigma   = 6.0 * pow(0.2, (REAL) n / TRAIN_STEPS);
  73.       Input[0] = wOld;
  74.       Input[1] = wNew;
  75.       SetInput(Net, Input);
  76.       PropagateNet(Net);
  77.       GetOutput(Net, Output);
  78.       Pole.F = Output[0];
  79.       StepSize = Net->KohonenLayer->StepSize[Net->Winner];
  80.       Pole.F += StepSize * RandomNormalREAL(0, 10);
  81.       fprintf(f, "%4.1fs    %5.1f?   %5.1fN\n", t * T, Pole.w, Pole.F);
  82.       wOld = Pole.w;
  83.       ScoreOld = ScoreOfPole(&Pole);
  84.       SimulatePole(&Pole);
  85.       wNew = Pole.w;
  86.       ScoreNew = ScoreOfPole(&Pole);
  87.       dScore = ScoreNew - ScoreOld;
  88.       dScoreMean = Net->KohonenLayer->dScoreMean[Net->Winner];
  89.       if (dScore > dScoreMean) {
  90.         Target[0] = Pole.F;
  91.         TrainUnits(Net, Input, Target);
  92.       }
  93.       Net->KohonenLayer->dScoreMean[Net->Winner] += Net->Gamma * (dScore - dScoreMean);
  94.     }
  95.     if (PoleStillBalanced(&Pole))
  96.       fprintf(f, "Pole still balanced after %0.1fs ...\n\n", t * T);
  97.     else
  98.       fprintf(f, "Pole fallen after %0.1fs ...\n\n", (t+1) * T);
  99.   }
  100. }


  101. /******************************************************************************
  102.                                     M A I N
  103. ******************************************************************************/


  104. void main()
  105. {
  106.   NET Net;

  107.   InitializeRandoms();
  108.   GenerateNetwork(&Net);
  109.   RandomWeights(&Net);
  110.   InitializeApplication(&Net);
  111.   TrainNet(&Net);
  112.   WriteNet(&Net);
  113.   FinalizeApplication(&Net);
  114. }
复制代码
发表于 2008-12-19 22:23 | 显示全部楼层

:lol :lol :lol :lol :lol :lol :lol :lol :lol :lol
发表于 2009-1-4 19:37 | 显示全部楼层

还是要先理解SOM的机理后,使用这段程序才会得心应手!

还没有学过SOM,只是学过BP。
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-12-23 19:22 , Processed in 0.081533 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表