next up previous contents
Next: 付録B 二つの写像を学習させるプログラム Up: 無題 Previous: 参考文献

付録A エノン写像を学習させるプログラム

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <local/bgi.h>

#define Iunits     2             /*    各ユニットの個数    */
#define Hunits    30
#define Ounits     2

#define Eta           0.05
#define Alpha         0.2
#define Rlow         -0.30
#define Rhigh         0.30
#define X_SYOKICHI    0.1
#define Y_SYOKICHI    0.1
#define A             1.4
#define B             0.3

#define fout(x)       ( 1 / (1 + exp( -(x) ) ))
#define urand()       ( (double)rand() / 0x7fffffffL 
                                       * (Rhigh - Rlow) + Rlow )

double wih[Hunits][Iunits];       /*    結合荷重(重み)  */
double who[Ounits][Hunits];

double dwih[Hunits][Iunits];      /*    重みの変化量      */
double dwho[Ounits][Hunits];

double shikiih[Hunits];            /*    しきい値          */
double shikiio[Ounits];

double dshikiih[Hunits];           /*    しきい値の変化量  */
double dshikiio[Ounits];

double iout[Iunits];              /*    各層の出力        */
double hout[Hunits];
double oout[Ounits];

double tsignal[Ounits];           /*    教師信号          */

main(argc,argv)
     int   argc;
     char *argv[];
{
  FILE  *fp;

  long   kaisuu;
  long   kaisuumax;
  int   i;
  char  name[64];
  double dummy,error,serror;

  double eta   = Eta,
         alpha = Alpha;

  void  foward_propagation();
  void  back_propagation();
  void  initialize();
  void  teach_signal();

  if (argc != 2){
    printf(" Usage : enon kaisuumax \n" );
    exit(-1);
  }

  kaisuumax = atol(argv[1]);

  sprintf(name,"KAISUU%ld_Eta%0.2f_Alpha%0.2f.data",
                                          kaisuumax,eta,alpha);

  fp = fopen(name,"w");

  if (fp == NULL){
    fprintf(stderr,"error\n");
    exit(1);
  }

  initialize();

  iout[0] = tsignal[0] = X_SYOKICHI;
  iout[1] = tsignal[1] = Y_SYOKICHI;

  error = serror = 2;

  for ( kaisuu = 1;(kaisuu <= kaisuumax);kaisuu++ ){
    teach_signal();
    foward_propagation();
    error = 0;
    for (i = 0; i < Ounits; i++){
      dummy = tsignal[i] - oout[i];
      error += (dummy * dummy);
    }
    error *= 0.5;
    serror = 0.4 * serror + error;
    if (kaisuu % 10000 == 0){
      printf( "\n%5d\n",kaisuu);
      printf( " x(t) = %3.5f",iout[0]);
      printf( " x(t+1) = %3.5f",oout[0]);
      printf( " kyoushi = %3.5f",tsignal[0]);
      printf( "\n y(t) = %3.5f",iout[1]);
      printf( " y(t+1) = %3.5f",oout[1]);
      printf( " kyoushi = %3.5f",tsignal[1]);
      printf( "\nERROR = %5.10f",error); 
    }
    back_propagation();
    for (i = 0; i < Iunits; i++){
      iout[i] = tsignal[i];
    }
  }
  
  fwrite(tsignal,sizeof(double),Iunits,fp);
  fwrite(wih,sizeof(double),Iunits * Hunits,fp);
  fwrite(who,sizeof(double),Hunits * Ounits,fp);
  fwrite(shikiih,sizeof(double),Hunits,fp);
  fwrite(shikiio,sizeof(double),Ounits,fp);
 
  fclose(fp);

  printf("\nkaisuu = %d\n",kaisuu);
  putchar('G'-'@');
/*
  initgraph(&i,&i,"800x440");

  while (!kbhit()){
    foward_propagation();
    teach_signal();
    putpixel((int)(oout[0]*75)+200,-(int)(oout[1]*300)+200);
    putpixel((int)(tsignal[0]*75)+500,-(int)(tsignal[1]*300)+200);
    for (i = 0; i < Iunits; i++){
      iout[i] = oout[i];
    }
  }*/
}

void initialize()
{
  int i,j;

  for (i = 0; i < Hunits; i++){
    for (j = 0; j < Iunits; j++){
      wih[i][j] = urand();
    }
    shikiih[i] = urand();
  }

  for (i = 0; i < Ounits; i++){
    for (j = 0; j < Hunits; j++){
      who[i][j] = urand();
    }
    shikiio[i] = urand();
  }
}

void teach_signal()
{
  double x, y;

  x = tsignal[0];
  y = tsignal[1];
  tsignal[0] = y + 1 - A * x * x;
  tsignal[1] = B * x;
}

void foward_propagation()
{
  int i,j;
  double sum;

  for (i = 0; i < Hunits; i++){
    sum = 0;
    for (j = 0; j < Iunits; j++){
      sum += wih[i][j] * iout[j];
    }
    hout[i] = fout(sum + shikiih[i]);
  }
  for (i = 0; i < Ounits; i++){
    sum = 0;
    for (j = 0; j < Hunits; j++){
      sum += who[i][j] * hout[j];
    }
    oout[i] = sum + shikiio[i];
  }
}

void back_propagation()
{
  int    i,j;
  double dih[Hunits],dho[Ounits];           /* 学習信号 */
  double sum;

  for (i = 0; i < Ounits; i++){
    dho[i] = (tsignal[i] - oout[i]);
  }
  for (i = 0; i < Hunits; i++){
    for (sum = 0, j = 0; j < Ounits; j++){
      dwho[j][i] = (Eta * dho[j] * hout[i]) + (Alpha * dwho[j][i]);
      who[j][i] += dwho[j][i];
      sum += (dho[j] * who[j][i]);
    }
    dih[i] = hout[i] * (1 - hout[i]) * sum;
  }
  for (i = 0; i < Ounits; i++){
    dshikiio[i] = (Eta * dho[i]) + (Alpha * dshikiio[i]);
    shikiio[i] += dshikiio[i];
  }
  for (i = 0; i < Iunits; i++){
    for (j = 0; j < Hunits; j++){
      dwih[j][i] = (Eta * dih[j] * iout[i]) + (Alpha * dwih[j][i]);
      wih[j][i] += dwih[j][i];
    }
  }
  for (i = 0; i < Hunits; i++){
    dshikiih[i] = (Eta * dih[i]) + (Alpha * dshikiih[i]);
    shikiih[i] += dshikiih[i];
  }
}



Deguchi Toshinori
1996年11月26日 (火) 09時21分43秒 JST