next up previous contents
Next: この文書について ... Up: 無題 Previous: 参考文献

付録A 二つの写像を学習させるプログラム

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

#define Iunits     8             /*    各ユニットの個数    */
#define Hunits    50
#define Ounits     8
#define Tunits     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 AA            0.4
#define BB           -1.2
         
#define fout(x)       ( 1 / (1 + exp( -(x) ) ))
#define urand()       ( drand48() * (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 hkeep[Hunits];

double tsignal[2][Tunits];        /*    教師信号          */
double *tsignal1 = tsignal[0], 
       *tsignal2 = tsignal[1];

double alpha;
double eta;

double drand48();

void  teach_signal1();
void  teach_signal2();
void  (*teach_signal[2])() = {teach_signal1, teach_signal2};

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

  long   kaisuu;
  long   kaisuumax;
  int    i,j,sw,kai;
  
  char  name[64];
  double dummy,error,serror,herror;
  
  void  foward_propagation();
  void  back_propagation();
  void  initialize();

  if (argc != 5){
    printf(" Usage : fryouhou kaisuumax kai eta alpha\n" );
    exit(-1);
  }

  kaisuumax = atol(argv[1]);
  kai       = atol(argv[2]);
  eta       = atof(argv[3]);
  alpha     = atof(argv[4]);
    
  sprintf(name,"GKAI%ld_Eta%0.3f_Alp%0.2f_%d.data"
                                 ,kaisuumax,eta,alpha,kai);

  fp = fopen(name,"w");

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

  initialize();
  tsignal1[0] = tsignal2[0] = X_SYOKICHI;
  tsignal1[1] = tsignal2[1] = Y_SYOKICHI;

  for (i = 0; i < Tunits / 2; i++) {
    teach_signal1();
    teach_signal2();
  }

  for (i = 0; i < Tunits; i++)
    iout[i] = tsignal1[i];
  for (i = Tunits; i < Ounits; i++)
    iout[i] = 0.0;

  error = 2;
  serror = 0;
  herror = 0;
  sw = 0;
  kaisuu = 1;

  while (kaisuu <= kaisuumax){
    for ( j = 0; j < 5; j++){
      foward_propagation();
      teach_signal[sw]();
     for (i = 0; i < Hunits; i++){
        hkeep[i] = hout[i];
      }
     for (i = 0; i < Tunits; i++){
        iout[i] = tsignal[sw][i];
      }
     for (i = Tunits; i < Ounits; i++){
        iout[i] = oout[i];
      }
    }
    for ( j = 0; j < kai; j++, kaisuu++){
      teach_signal[sw]();
      foward_propagation();
      error = 0;
      for (i = 0; i < Tunits; i++){
        dummy = tsignal[sw][i] - oout[i];
        error += (dummy * dummy);
      }
      error *= 0.5;
      herror += error;
      if (serror < error){
        serror = error;
      }
      if (kaisuu % 10000 == 0){
        herror /= 10000;
        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[sw][0]);
        printf( "\n y(t) = %3.5f",iout[1]);
        printf( " y(t+1) = %3.5f",oout[1]);
        printf( " kyoushi = %3.5f",tsignal[sw][1]);
        printf( "\nMaxEr = %5.10f  Er_Heikin = %5.10f",serror,herror);
        serror = 0;
      }
      back_propagation(sw);
      for (i = 0; i < Hunits; i++){
        hkeep[i] = hout[i];
      }
      for (i = 0; i < Tunits; i++){
        iout[i] = tsignal[sw][i];
      }
      for (i = Tunits; i < Ounits; i++){
        iout[i] = oout[i];
      }
    }
    sw = 1 - sw;
  }  
  fwrite(tsignal1,sizeof(double),Tunits,fp);
  fwrite(tsignal2,sizeof(double),Tunits,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'-'@');
}

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_signal1()
{
  int i;
  double x, y;
#if 0
  for (i = Tunits - 1; i > 2; i -= 2) {
    tsignal1[i] = tsignal1[i - 2];
    tsignal1[i - 1] = tsignal1[i - 3];
  }
#endif
  x = tsignal1[0];
  y = tsignal1[1];
  tsignal1[0] = y + 1 - A * x * x; 
  tsignal1[1] = B * x;
#if 0
  tsignal1[2] = A;
  tsignal1[3] = B;
#endif
}

void teach_signal2()
{
  int i;
  double x, y;
#if 0
  for (i = Tunits - 1; i > 2; i -= 2) {
    tsignal2[i] = tsignal2[i - 2];
    tsignal2[i - 1] = tsignal2[i - 3];
  }
#endif
  x = tsignal2[0];
  y = tsignal2[1];
  tsignal2[0] = y + AA * x;
  tsignal2[1] = BB + x * x;
#if 0
  tsignal2[2] = AA;
  tsignal2[3] = BB;
#endif
}

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(x)
     int   x;
{
  int    i,j;
  double dih[Hunits],dht[Tunits],dho[Ounits];           /* 学習信号 */
  double sum;
  
  for (i = 0; i < Tunits; i++){
    dht[i] = (tsignal[x][i] - oout[i]);
  }
  for (i = 0; i < Hunits; i++){
    for (sum = 0, j = 0; j < Tunits; j++){
      dwho[j][i] = (eta * dht[j] * hout[i]) + (alpha * dwho[j][i]);
      who[j][i] += dwho[j][i];
      sum += (dht[j] * who[j][i]);
    }
    dih[i] = hout[i] * (1 - hout[i]) * sum;
  }
  for (i = 0; i < Tunits; i++){
    dshikiio[i] = (eta * dht[i]) + (alpha * dshikiio[i]);
    shikiio[i] += dshikiio[i];
  }
  for (i = 0; i < Iunits; i++){
    for (sum = 0, j = 0; j < Hunits; j++){
      dwih[j][i] = (eta * dih[j] * iout[i]) + (alpha * dwih[j][i]);
      wih[j][i] += dwih[j][i];
      sum += (dih[j] * wih[j][i]);
    }
    dho[i] = sum;
  }
  for (i = 0; i < Hunits; i++){
    dshikiih[i] = (eta * dih[i]) + (alpha * dshikiih[i]);
    shikiih[i] += dshikiih[i];
  }
  for (i = 0; i < Hunits; i++){
    for (j = Tunits; j < Ounits; j++){
      dwho[j][i] = (eta * dho[j] * hkeep[i]) + (alpha * dwho[j][i]);
      who[j][i] += dwho[j][i];
    }
  }
  for (i = Tunits; i < Ounits; i++){
    dshikiio[i] = (eta * dho[i]) + (alpha * dshikiio[i]);
    shikiio[i] += dshikiio[i];
  }
}


Deguchi Toshinori
1996年10月08日 (火) 16時08分54秒 JST