next up previous contents
Next: 付録B 学習プログラム(内部記憶を持つニューラルネットワーク) Up: 無題 Previous: 参考文献

付録A 学習プログラム(ニューラルネットワーク)

/* 学習プログラム(ニューラルネットワーク) : main.c */

/* ヘッダ */

#include        <stdio.h>
#include        <stdlib.h>
#include        <string.h>
#include        <math.h>

/* ランダム情報のファイル */

#define         DATA  "DATA.dat"
#define ON  ( 1.0 )
#define OFF ( 0.0 )

/* 各層の値 */

#define Inunit          ( 2 + 28 )
#define Midunit         50
#define Outunit         ( 2 + 28 )
#define Tunit           2
#define SMAX            256
/*#define Time            31*/
#define Time          50

#define Rhigh           0.30
#define Rlow            -0.30

#define urand()         ( drand48() * ( Rhigh - Rlow ) + Rlow )

/* 各層の重み */

double  wim[Midunit][Inunit];
double  wmo[Outunit][Midunit];

/* 各層重みの変化分 */

double  dwim[Midunit][Inunit];
double  dwmo[Outunit][Midunit];

/* しきい値 */

double  sikiiim[Midunit];
double  sikiimo[Outunit];

/* しきい値の変化分 */

double  dsikiiim[Midunit];
double  dsikiimo[Outunit];

/* 各層の出力 */

double  inout[Inunit][Time];
double  midout[Midunit];
double  outout[Outunit];
double  tout[Tunit];

double  tsignal[Outunit];
double  outkeep[Outunit];

double  drand48();
double  Eta,Alpha;
double  ts[SMAX];

int     g,m;
double  gosa[Tunit][Time];
double  kekka[Tunit];

int     tsmax,count;
int     t;

FILE    *fpmusic , *fi;
FILE    *flen , *fhei;
char    length[SMAX] , height[SMAX];

/* シグモイド関数 */

double  fsig( double in ){
                 double  out;
                 if( in <= -24 ){
                      in = -24;
                 }
                 out = ( 1 / ( 1 + exp ( - ( in ) )));
                 return( out );
        }

/* 関数の定義 */

void    initialize();
void    forward_propagation();
void    back_propagation();


/* main関数 */

void    main( int argc , char *argv[] ){

        int             ct;
        int             a,b;
        unsigned int    dn,i,k,kk;
        long            kaisuu;
        double          averror,dummy,error,serror;
        double          gsritu;
        char            c,music[SMAX],name[SMAX];
        FILE            *fp,*fp2;

        if( argc != 4 ){
                printf( "Usage : main Eta Alpha filename \n" );
                exit(1);
        }

        Eta = atof( argv[1] );
        Alpha = atof( argv[2] );

        /* musicファイルの指定 */

        strcpy( music , argv[3] );

        error = serror = 0;

        /* musicファイルのオープン */

        fpmusic = fopen( music,"r" );
        if( fpmusic == NULL ){
                printf( "Can't open the file \n " );
                exit(1);
        }

        /* データの読み込みとデータ数のカウント */

        ct = 0;
        while( fscanf( fpmusic,"%lf %lf",&ts[ct],&ts[ct + 1] ) == 2 ){
                ct += 2;
        }

        /* 教師信号を記憶 */

        tsmax = ct / 2;

        /* musicファイルのクローズ */
        
        fclose( fpmusic );

        /* ニューロンの初期化 */

        initialize();

        /* 誤差をファイルに書き込む */

        sprintf( name,"gosa_verE%0.3f_A%0.3f.dat" ,Eta ,Alpha );
        fi = fopen( name ,"w" );
        if( fi == NULL ){
          fprintf( stderr, "File not open!\n" );
          exit(1);
        }
        sprintf( length,"length_verE%0.3f_A%0.3f.dat" ,Eta ,Alpha );
        flen = fopen( length ,"w" );
        if( flen == NULL ){
          fprintf( stderr, "File not open!\n" );
          exit(1);
        }
        sprintf( height,"height_verE%0.3f_A%0.3f.dat" ,Eta ,Alpha );
        fhei = fopen( height ,"w" );
        if( flen == NULL ){
          fprintf( stderr, "File not open!\n" );
          exit(1);
        }

        /* ランダムに入力を与える */

        for( t = 0 ; t < tsmax ; t++ ){
          for( count = 2 ; count < Inunit ; count++ ){
            inout[count][t] = urand();
            if( inout[count][t] < -0.12 ){   /* この数字で0,1の量を変える */
              inout[count][t] = OFF;
            }else{
              inout[count][t] = ON;
            }
          }
        }

        /* 初期値入力 */

        for( t = 0 ; t < tsmax ; t++ ){
          for( i = 0 ; i < Tunit ; i++ ){
            inout[i][t] = ts[t * Tunit + i];
          }
        }

        /* 学習開始 */

        kk = 150000;    /* 学習回数 */
        for( k = 0 ; k < kk ; k++ ){
          m = k;

        /* 学習部分 */

        serror = 0;
        for( t = 0 ; t < tsmax ; t++ ){

                if (t + 2 < tsmax) {
                  tsignal[0] = ts[t * 2 + 2];
                  tsignal[1] = ts[t * 2 + 3];
                } else {
                  tsignal[0] = ts[0];
                  tsignal[1] = ts[1];
                }

                for( a = 0 ; a < Outunit ; a++ ){
                  outkeep[a] = outout[a];
                }

                forward_propagation();
        
                error = 0;
                for( i = 0 ; i < Tunit ; i++ ){
                        dummy = tsignal[i] - outout[i];
                        error += ( dummy * dummy );
                }
                error = sqrt( error );
                serror += error;

                g = t + 1;
                if( g >= tsmax ){
                  g = 0 ;
                }
                if( k % 1000 == 0 || k == kk - 1 ){
                  for( a = 0 ; a < Tunit ; a++ ){
                    gosa[a][t] = inout[a][g] - outout[a];
                    kekka[a] = sqrt( gosa[a][t] * gosa[a][t] );
                  }
                 /*fprintf( flen ,  "%d %f\n",k / 1000,kekka[0] );
                  fprintf( fhei ,  "%d %f\n",k / 1000,kekka[1] );*/
                }
                if( k % 10000 == 0 || k == kk - 1 ){
                  printf( "%d\n", k / 10000 );
                }
                if( k == kk - 1 ){
                  for( b = 0 ; b < Outunit ; b++ ){
                    fprintf( fi , "inout[%d][%d] = %f",b,t,inout[b][t]);
                    fprintf( fi , " outkeep[%d] = %f",b,outkeep[b] );
                    fprintf( fi , " outout[%d] = %f\n",b,outout[b] );
                  }
                  /* 誤差が大きければ学習回数を増やす */
                  if( kekka[0] > 0.001 || kekka[1] > 0.001 ){
                    kk = kk + 10000;
                  }
                }

                back_propagation();

        }
 }

        /* 最後にニューロンの重みを記録する */

        if( k == kk ){          
                dn = k / 100;
                sprintf( name,"mu2c%d_E%0.3f_A%0.3f.data",dn,Eta,Alpha );

                fp2 = fopen( name,"w" );
                if( fp2 == NULL ){
                        fprintf( stderr,"Error\n" );
                        exit(1);
                }

        /* 最終的な各ユニット、その他のデータをファイルに書き込む */

        fwrite( inout , sizeof( double ),Inunit * Time ,fp2 );

        fwrite( wim,sizeof( double ),Inunit * Midunit ,fp2 );
        fwrite( wmo,sizeof( double ),Midunit * Outunit ,fp2 );
        fwrite( sikiiim,sizeof( double ),Midunit ,fp2 );
        fwrite( sikiimo,sizeof( double ),Outunit ,fp2 );
        fclose( fp2 ); 
        }

        fclose( flen );
        fclose( fhei );
        fclose( fp );
        fclose( fi );
        printf( "\nkaisuu = %d \n",k );
        putchar( 'G' - '@' );
}


/* 各重み、しきい値にランダムな値を与える       関数:initialize() */

void    initialize(){

        int     i,j;
        int     a,b;

        for( j = 0 ; j < Midunit ; j++ ){
          for( i = 0 ; i < Inunit ; i++ ){
            wim[j][i] = urand();
          }
          sikiiim[j] = urand();
        }
        for( j = 0 ; j < Outunit ; j++ ){
          for( i = 0 ; i < Midunit ; i++ ){
            wmo[j][i] = urand();
          }
          sikiimo[j] = urand();
        }

        /* 各差分値を初期化しておく */
        for( a = 0 ; a < Inunit ; a++ ){
          for( b = 0 ; b < Midunit ; b++ ){
            dwim[b][a] = 0;
          }
        }
        for( a = 0 ; a < Midunit ; a++ ){
          for( b = 0 ; b < Outunit ; b++ ){
            dwmo[b][a] = 0;
          }
        }

        for( a = 0 ; a < Midunit ; a++ ){
          dsikiiim[a] = 0;
        }
        for( a = 0 ; a < Outunit ; a++ ){
          dsikiimo[a] = 0;
        }
}

/* フォワードプロパゲーション   関数:forward_propagation() */

void    forward_propagation(){

        int             i,j,h;
        double          sum;

        for( j = 0 ; j < Midunit ; j++ ){
          sum = 0;
          for( i = 0 ; i < Inunit ; i++ ){
            sum += wim[j][i] * inout[i][t] ;
          }
          midout[j] = fsig( sum + sikiiim[j] );
        }

        for( j = 0 ; j < Outunit ; j++ ){
          sum = 0;
          for( i = 0 ; i < Midunit ; i++ ){
            sum += wmo[j][i] * midout[i];
          }
        outout[j] = fsig( sum + sikiimo[j] );
        }
}

/* バックプロパゲーション       関数:back_propagation() */

void    back_propagation(){

        int             i,j,h;
        /* 誤差 */
        double          dim[Midunit];
        double          dmo[Outunit];
        double          sum;

        h = t + 1;
        if( h >= tsmax ){
          h = 0;
        }
        /* 出力層の学習信号の計算 */
        for( j = 0 ; j < Outunit ; j++ ){
          dmo[j] = outout[j] * ( 1 - outout[j] ) * ( inout[j][h] - outout[j] );
        }
        
        /* 出力の重み補正 */

        for( j = 0 ; j < Midunit ; j++ ){
          for( sum = 0 , i = 0 ; i < Outunit ; i++ ){
            dwmo[i][j] = ( Eta * dmo[i] * midout[j] ) + ( Alpha * dwmo[i][j] );
            sum += ( dmo[i] * wmo[i][j] );
            wmo[i][j] += dwmo[i][j];
          }
        /* 中間層の学習信号の計算 */
          dim[j] = midout[j] * ( 1 - midout[j] ) * sum;
        }

        /* 出力のしきい値補正 */

        for( j = 0 ; j < Outunit ; j++ ){
          dsikiimo[j] = ( Eta * dmo[j] ) * ( Alpha * dsikiimo[j] );
          sikiimo[j] += dsikiimo[j];
        }

        /* 中間層の重み補正 */
        for( j = 0 ; j < Inunit ; j++ ){
          for( sum = 0 , i = 0 ; i < Midunit ; i++ ){
            dwim[i][j] = ( Eta * dim[i] * inout[j][t] ) + ( Alpha * dwim[i][j] );
            wim[i][j] += dwim[i][j];
          }
        }
          
        /* 中間層のしきい値補正 */
        for( j = 0 ; j < Midunit ; j++ ){
          dsikiiim[j] = ( Eta * dim[j] ) + ( Alpha * dsikiiim[j] );
          sikiiim[j] += dsikiiim[j];
        }
      }



Deguchi Toshinori
Wed Feb 21 11:55:53 JST 2001