next up previous contents
Next: 想起プログラム Up: 無題 Previous: 参考文献

学習プログラム

/* 内部記憶を持つニューラルネット */

#include  <stdio.h> /* ヘッダ */
#include  <stdlib.h>
#include  <string.h>
#include  <math.h>

#define   STUDY

#include  "grobal.h"   /* 自作のヘッダ */ /* 変数の定義 */
#include  "protfunc.h" /* 関数の定義 */
#include  "funcdef.h"  /* 関数の内容 */

/* main関数 */
int  main( int argc , char **argv ){

  srand48( Seed );               /* 乱数の設定 */
  options_study( argc , argv );  /* コマンド入力から変数を読みとる */
  set_teach( Data );             /* 教師信号をセットする */
  set_file();                    /* 出力ファイルをセットする */
  initialize();                  /* ニューロンの初期化 */
  teach_change();                /* 教師信号を変更する */

  /* 学習ループ */
  r = 0;
  while( Flag_continue != 0 ){

    Flag_success = 0;
    study();                             /* 学習部分 */
    check_recall();                      /* 想起できるか確認 */
    if( r >= Saidai ) Flag_continue = 0; /* 学習最大値を越えたら強制終了 */

  }

  output_weight();   /* 重みを記録する */
  return 0;
}

/* オプションを決定する関数 */
void  options_study( int argc , char **argv ){

  while( --argc ){
    if( **++argv == '-' ){
      switch( *++*argv ){
      case 'z':            /* 内部記憶を全て0にする */
        if( --argc ){
          Flag_zero = 1;
          break;
        }
      case 'n':            /* ノイズを混ぜる  */
        if( --argc ){
          Flag_noize = 1;
          break;
        }
      default:
usage:
        fprintf( stderr , "Usage: naiburand23plus [-z]\n" );
        exit(-1);
      }
    } else {
      break;
    }
  }

}

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

  int   i,j;

  for( j = 0 ; j < Midunit ; j++ ){   /* 入力層〜中間層 */
    for( i = 0 ; i < Inunit ; i++ ){
      wim[j][i] = urand();
      dwim[j][i] = 0;
    }
    sikiiim[j] = urand();
    dim[j] = 0;
    dsikiiim[j] = 0;
    midkeep[j] = 0;
  }

  for( j = 0 ; j < Outunit ; j++ ){   /* 中間層〜出力層 */
    for( i = 0 ; i < Midunit ; i++ ){
      wmo[j][i] = urand();
      dwmo[j][i] = 0;
    }
    sikiimo[j] = urand();
    dmo[j] = 0;
    dsikiimo[j] = 0;
    outkeep[j] = 0;
  }

}

/* 特殊な教師信号をセットする */
void  teach_change(){

  int i,j,h;

  /* 補助入力層の教師信号を作る */
  for( i = 0 ; i < Lunit ; i = i + 2 ){
    inkeep[Tunit + i][0] = inkeep[0][tsmax - ( i / 2 ) - 1];
    inkeep[Tunit + i + 1][0] = inkeep[1][tsmax - ( i / 2 ) - 1];
  }
  for( t = 1 ; t < tsmax ; t++ ){
    h = t - 1;
    for( i = 0 ; i < Lunit ; i = i + 2 ){
      inkeep[Tunit + i][t] = inkeep[i][h];
      inkeep[Tunit + i + 1][t] = inkeep[i + 1][h];
    }
  }

  /* 入力にランダムなデータを与える */
  for( t = 0 ; t < tsmax ; t++ ){
    for( i = TL ; i < Inunit ; i++ ){
      inkeep[i][t] = qrand();
      inkeep[i][t] = quantum( inkeep[i][t] );
    }
  }

  if( Flag_zero != 0 ){  /* 内部記憶層の第一音を0にするようにする */
    for( i = TLC ; i < Inunit ; i++ ){
      inkeep[i][0] = 0;
    }
  }

  if( Flag_noize != 0 ){
    for( t = 0 ; t < tsmax ; t++ ){
      noisein[0][t] = inkeep[0][t] + lenrand();
      noisein[1][t] = inkeep[1][t] + heirand();
    }
  }

}

/* 内部記憶を作った時の学習の関数 */
void study(){

  int i,j;
  int g;

  kk = r + Gakusyu;
  for( k = r ; k < kk ; k++ ){

    Flag_success = 0;
    if( k % 1000 == 0 )  printf( "Study %d\n", k / 1000 ); /* 学習回数の表示 */
    gosasumcloseteach = gosasumcloseall = 0;

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

      g = t + 1;
      if( g >= tsmax ) g = 0;

      /* 教師信号を入れる */
      for( i = 0 ; i < TLC ; i++ ){
        inout[i][t] = inkeep[i][t];
      }

      if( Flag_noize != 0 ){
        for( i = 0 ; i < Tunit ; i++ ){
          inout[i][t] = noisein[i][t];
        }
      }

      forward_propagation(); /* フォワードプロパゲーション */
      learn_check();         /* 学習が成功しているかを調べる */
      back_propagation();    /* バックプロパゲーション */

      if( t == 0 && k % 1000 == 0 ){   /* 誤差信号を測定する */
        gosa_plot();
        if( Flag_gosaplotnew != 0 ) gosa_plot_new();
      }

      /* 各出力を保存する*/
      for( i = 0 ; i < Midunit ; i++ ){
        midkeep3[i] = midkeep2[i];
        midkeep2[i] = midkeep[i];
        midkeep[i] = midout[i];
      }
      for( i = 0 ; i < Outunit ; i++ ){
        outkeep3[i] = outkeep2[i];
        outkeep2[i] = outkeep[i];
        outkeep[i] = outout[i];
      }
      for( i = TLC ; i < Outunit ; i++ ){
        outkept[i][t] = outout[i];
      }

      output_correct();    /* 量子化する */
      feedback();          /* 出力をフィードバックする */

    }

    /* 最大値以上であれば強制終了処理 */
    if( kk >= Saidai ){
      kk = Saidai;
      Flag_continue = 0;
    }
  }

  r = k;
}

/* 内部記憶を作った時の想起 */
void check_recall(){

  int i,j;
  int g;

  chsuccess = chfault = 0;
  Flag_success = 0;
  for( k = 0 ; k < Souki ; k++ ){

    if( k % 1000 == 0 )  printf( "Recall_close %d\n", k / 1000 );

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

      if( t == 0 ){
        for( i = 0 ; i < TLC ; i++ ){
          inout[i][t] = inkeep[i][t];
        }
      }
      g = t + 1;
      if( g >= tsmax )  g = 0;

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

      /* 内部記憶の時間的変移特性を記録する */
      if( k >= Souki - 1 ){
        for( i = TLC ; i < Inunit ; i++ ){
          cyclekeep[i][t] = outout[i];
        }
      }

      output_correct();      /* 量子化をする*/
      feedback();            /* 次の時間の入力にする */

      if( k == Souki - 1 ){
        for( i = 0 ; i < Tunit ; i++ ){
          if( (float)inkeep[i][g] != (float)outout[i] ){ /* 教師信号との比較 */
            Flag_success++;
            chfault++;
          } else {
            chsuccess++; /* 全て間違っていなければ学習成功 */
          }
        }
        fprintf( fprecall , "%f %f %f ",inkeep[0][g],outout[0],( inkeep[0][g] - outout[0] ) );
        fprintf( fprecall , "%f %f %f\n",inkeep[1][g],outout[1],( inkeep[1][g] - outout[1] ) );
        if( Flag_success == 0 ){
          Flag_continue = 0;
        } else {
          Flag_continue = 1;
        }
      }

    }
  }

  fprintf( fpplot ,"\n" );  fprintf( fpnaibu ,"\n" );  fprintf( fprecall ,"\n" );

}

void learn_check(){

  int  i;
  int  g;

  g = t + 1;
  if( g >= tsmax )  g = 0;

  if( k % 1000 == 0 || k == kk - 1 ){

    for( i = 0 ; i < TLC ; i++ ){
      gosa[i][t] = inkeep[i][g] - outout[i];
      kekka[i] = sqrt( gosa[i][t] * gosa[i][t] );
    }
    for( i = TLC ; i < Outunit ; i++ ){
      gosa[i][t] = outkept[i][t] - outout[i];
      kekka[i] = sqrt( gosa[i][t] * gosa[i][t] );
    }
    if( kekka[0] > 0.1 || kekka[1] > 0.0125 ){
      printf( " t = %d is fault %f %f %f %f\n",t,outout[0],inkeep[0][g],outout[1],inkeep[1][g] );
    }

    if( t == 36 ){
      fprintf( fpplot , "%d %f",( k / 100 ) , kekka[0] );
      fprintf( fpplot , " %f\n" , kekka[1] );
      fprintf( fpnaibu , "%d ",( k / 100 ) );
      for( i = 0 ; i < Nunit ; i++ ){
        if( i > 2 && i < 7 ) fprintf( fpnaibu , "%f ", outout[TLC + i] );
      }
      fprintf( fpnaibu , "\n" );
      fflush( fpplot );
      }
    }

    if( k == kk - 1 ){
      for( i = 0 ; i < Tunit ; i++ ){
        gosasumcloseteach += sqrt( gosa[i][t] * gosa[i][t] );
      }
      for( i = 0 ; i < Outunit ; i++ ){
        gosasumcloseall += sqrt( gosa[i][t] * gosa[i][t] );
      }
      if( kekka[0] > 0.1 || kekka[1] > 0.0125 ){
        if( Flag_success == 0 ){
          kk = kk + 1000;
          Flag_success++;
        }
      }
    }

    if( kk >= Saidai ){
      for( i = 0 ; i < Tunit ; i++ ){
        gosa[i][t] = inkeep[i][g] - outout[i];
        gosasumcloseteach += sqrt( gosa[i][t] * gosa[i][t] );
      }
      for( i = 0 ; i < Outunit ; i++ ){
        gosa[i][t] = inkeep[i][g] - outout[i];
        gosasumcloseall += sqrt( gosa[i][t] * gosa[i][t] );
      }
      kk = Saidai;
      Flag_continue = 0;
    }
}

/* 最後にニューロンの重みなどを記録する */
void output_weight(){

  int i;
  int dn;

  /* 内部記憶に関してのt - t+1 特性をとる */
  for( t = 0 ; t < tsmax ; t++ ){
    if( t >= tsmax - 1 ){
      for( i = 1 ; i < 6 ; i++ ){
        fprintf( fpnaibu2 ,"%f %f ",inout[TLC + i][t],inout[TLC + i][0]);
      }
      fprintf( fpnaibu2 ,"\n" );
    }else{
      for( i = 1 ; i < 6 ; i++ ){
        fprintf( fpnaibu2 ,"%f %f ",inout[TLC + i][t],inout[TLC + i][t + 1]);
      }
      fprintf( fpnaibu2 ,"\n" );
    }
  }

  /* 周期的な内部記憶の特性を出力する */
  for( i = TLC ; i < Inunit ; i++ ){
    for( t = 0 ; t < tsmax ; t++ ){
      fprintf( fpnaibu4 ,"%d %d %f\n",i,t,cyclekeep[i][t] );
    }
  }

  dn = r / 100;
  sprintf( fiout,"kekka19/%dc%d_E%0.3f_A%0.3f.data",Filenumber,dn,Eta,Alpha );
  
  fpout = fopen( fiout,"w" );
  if( fpout == NULL ){
    fprintf( stderr,"Error\n" );
    exit(1);
  }
    
  /* 最終的な各ユニット、その他のデータをファイルに書き込む */  
  fwrite( inout , sizeof( double ),Inunit * Time ,fpout );
  fwrite( inkeep , sizeof( double ) , Inunit * Time , fpout );
  fwrite( wim,sizeof( double ),Inunit * Midunit ,fpout );
  fwrite( wmo,sizeof( double ),Midunit * Outunit ,fpout );
  fwrite( sikiiim,sizeof( double ),Midunit ,fpout );
  fwrite( sikiimo,sizeof( double ),Outunit ,fpout );
  fclose( fpout ); 

  fprintf( fprecall ,"success = %d , fault = %d\n",chsuccess,chfault );
  fprintf( fprecall ,"%f %f\n" ,gosasumcloseteach ,gosasumcloseall );

  fclose( fpplot );
  fclose( fpsumplot );
  fclose( fpnaibu );
  fclose( fpnaibu2 );
  fclose( fprecall );
  fclose( fpnaibu4 );
  fclose( fpnaibucheck );
  printf( "\nkaisuu = %d \n",r );
  putchar( 'G' - '@' );
}

/* 伝搬させる誤差の比率を測定する */
void gosa_plot(){

  int i;

  double gettmax,gettmin;
  double getnmax,getnmin;
  double dmotmax,dmotmin;
  double dmonmax,dmonmin;

  gettmax = gettmin = dmoteach[0];
  for( i = 1 ; i < TLC ; i++ ){
    if( dmoteach[i] > gettmax ) gettmax = dmoteach[i];
    if( dmoteach[i] < gettmin && dmoteach[i] != 0 ) gettmin = dmoteach[i];
  }

  getnmax = getnmin = dmonaibu[0];
  for( i = 1 ; i < Nunit ; i++ ){
    if( dmonaibu[i] > getnmax ) getnmax = dmonaibu[i];
    if( dmonaibu[i] < getnmin && dmonaibu[i] != 0 ) getnmin = dmonaibu[i];
  }

  fprintf( fpsumplot , "%d %f %f %f %f %f %f %f %f\n" , ( k / 100 ) , gettmax , gettmin , getnmax , getnmin ,
    ( getnmax / gettmax ) , ( getnmin / gettmin ) , ( getnmax / gettmin ) , ( getnmin / gettmax ) );

}

/* 遅れ学習による中間層での誤差信号の大きさを測定する */
void gosa_plot_new(){

  int i;

  fprintf( fpdimplot , "%d " , ( k / 100 ) );
  for( i = 0 ; i < Midunit ; i++ ){
    fprintf( fpdimplot , "%f " , dimget[i] );
  }
  for( i = 0 ; i < Midunit ; i++ ){
    fprintf( fpdimplot , "%f " , dimlate[i] );
  }
  for( i = 0 ; i < Midunit ; i++ ){
    fprintf( fpdimplot , "%f " , dimlate2[i] );
  }
  fprintf( fpdimplot , "\n" );

}

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

  int           i,j,g,h,f,e;
  double        sum;  /* 誤差 */
  
  g = t + 1;      /* 前の時間・先の時間を決める */
  if( g >= tsmax ) g = 0;
  h = t - 1;
  if( t == 0 ) h = tsmax - 1;
  f = t - 2;
  if( t == 0 ) f = tsmax - 2;
  if( t == 1 ) f = tsmax - 1;
  e = t - 3;
  if( t == 0 ) e = tsmax - 3;
  if( t == 1 ) e = tsmax - 2;
  if( t == 2 ) e = tsmax - 1;

  /* t : 出力層の誤差信号の計算 */
  for( j = 0 ; j < TLC ; j++ ){
    dmo[j] = outout[j] * ( 1 - outout[j] ) * ( inkeep[j][g] - outout[j] );
    dmoteach[j] = sqrt( ( inkeep[j][g] - outout[j] ) * ( inkeep[j][g] - outout[j] ) );
  }

  switch( Flag_backpro ){
/* ******** 普通のBP ************************** */
  case 1:

    /* t : 出力層の重み補正 */
    for( j = 0 ; j < Midunit ; j++ ){
      for( sum = 0 , i = 0 ; i < TLC ; 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];
      }
      /* t : 中間層の誤差信号の計算 */
      dim[j] = midout[j] * ( 1 - midout[j] ) * sum;
      dimget[j] = sqrt( sum * sum );
    }

    /* t : 出力層の閾値補正 */
    for( i = 0 ; i < TLC ; i++ ){
      dsikiimo[i] = ( Eta * dmo[i] ) + ( Alpha * dsikiimo[i] );
      sikiimo[i] += dsikiimo[i];
    }

    /* t : 中間層の重み補正 */
    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] );
        sum += ( dim[i] * wim[i][j] );
        wim[i][j] += dwim[i][j];
      }
      /* t : 内部記憶層の誤差信号の計算 */
      if( j >= TLC && j < TLCN ){
        dmo[j] = outkeep[j] * ( 1 - outkeep[j] ) * sum;
        dmonaibu[j - TLC] = sqrt( sum * sum );
      }
    }

    /* t : 中間層の重み補正 */
    for( i = 0 ; i < Midunit ; i++ ){
      dsikiiim[i] = ( Eta * dim[i] ) + ( Alpha * dsikiiim[i] );
      sikiiim[i] += dsikiiim[i];
    }

    /* t-1 : 内部記憶層の重み補正 */
    for( j = 0 ; j < Midunit ; j++ ){
      for( i = TLC ; i < TLCN ; i++ ){
        dwmo[i][j] = ( Eta2 * dmo[i] * midkeep[j] ) + ( Alpha * dwmo[i][j] );
        wmo[i][j] += dwmo[i][j];
      }
    }

    /* t-1 : 内部記憶層の閾値補正 */
    for( i = TLC ; i < TLCN ; i++ ){
      dsikiimo[i] = ( Eta2 * dmo[i] ) + ( Alpha * dsikiimo[i] );
      sikiimo[i] += dsikiimo[i];
    }

    break;

/* ******** 2-step Learning ************************** */
  case 2:

    /* t : 出力層の誤差伝搬 */
    for( j = 0 ; j < Midunit ; j++ ){
      for( sum = 0 , i = 0 ; i < TLC ; i++ ){
        sum += ( dmo[i] * wmo[i][j] );
      }
      /* t : 中間層の誤差信号の計算 */
      dim[j] = midout[j] * ( 1 - midout[j] ) * sum;
      dimget[j] = sqrt( sum * sum );
    }

    /* t : 中間層の誤差伝搬 */
    for( j = 0 ; j < Inunit ; j++ ){
      for( sum = 0 , i = 0 ; i < Midunit ; i++ ){
        sum += ( dim[i] * wim[i][j] );
      }
      /* t : 内部記憶層の誤差信号の計算 */
      if( j >= TLC && j < TLCN ){
        dmo[j] = outkeep[j] * ( 1 - outkeep[j] ) * sum;
        dmonaibu[j - TLC] = sqrt( sum * sum );
      }
    }

    /* t-1 : 出力層の誤差信号の計算 */
    for( i = 0 ; i < TLC ; i++ ){
      dmo[i] = outkeep[i] * ( 1 - outkeep[i] ) * ( inkeep[i][t] - outkeep[i] );
    }

    /* t-1 : 出力層と内部記憶層の重み補正 */
    for( j = 0 ; j < Midunit ; j++ ){
      for( sum = 0 , i = 0 ; i < TLC ; i++ ){
        dwmo[i][j] = ( Eta * dmo[i] * midkeep[j] ) + ( Alpha * dwmo[i][j] );
        sum += ( dmo[i] * wmo[i][j] );
        wmo[i][j] += dwmo[i][j];
      }
      for( i = TLC ; i < TLCN ; i++ ){
        dwmo[i][j] = ( Eta2 * dmo[i] * midkeep[j] ) + ( Alpha * dwmo[i][j] );
        sum += ( dmo[i] * wmo[i][j] );
        wmo[i][j] += dwmo[i][j];
      }
      dim[j] = midkeep[j] * ( 1 - midkeep[j] ) * sum;
      dimlate[j] = sqrt( sum * sum );
    }

    /* t-1 : 出力層の閾値補正 */
    for( i = 0 ; i < TLC ; i++ ){
      dsikiimo[i] = ( Eta * dmo[i] ) + ( Alpha * dsikiimo[i] );
      sikiimo[i] += dsikiimo[i];
    }
    /* t-1 : 内部記憶層の閾値補正 */
    for( i = TLC ; i < TLCN ; i++ ){
      dsikiimo[i] = ( Eta2 * dmo[i] ) + ( Alpha * dsikiimo[i] );
      sikiimo[i] += dsikiimo[i];
    }

    /* t-1 : 中間層の重み補正 */
    for( j = 0 ; j < Inunit ; j++ ){
      for( i = 0 ; i < Midunit ; i++ ){
        dwim[i][j] = ( Eta * dim[i] * inout[j][h] ) + ( Alpha * dwim[i][j] );
        wim[i][j] += dwim[i][j];
      }
    }

    /* t-1 : 中間層の閾値補正 */
    for( i = 0 ; i < Midunit ; i++ ){
      dsikiiim[i] = ( Eta * dim[i] ) + ( Alpha * dsikiiim[i] );
      sikiiim[i] += dsikiiim[i];
    }

    break;

/* ******** 3-step Learning ************************** */
  default:

    /* t : 出力層の誤差伝搬 */
    for( j = 0 ; j < Midunit ; j++ ){
      for( sum = 0 , i = 0 ; i < TLC ; i++ ){
        sum += ( dmo[i] * wmo[i][j] );
      }
      /* t : 中間層の誤差信号の計算 */
      dim[j] = midout[j] * ( 1 - midout[j] ) * sum;
      dimget[j] = sqrt( sum * sum );
    }

    /* t : 中間層の誤差伝搬 */
    for( j = 0 ; j < Inunit ; j++ ){
      for( sum = 0 , i = 0 ; i < Midunit ; i++ ){
        sum += ( dim[i] * wim[i][j] );
      }
      /* t : 内部記憶層の誤差信号の計算 */
      if( j >= TLC && j < TLCN ){
        dmo[j] = outkeep[j] * ( 1 - outkeep[j] ) * sum;
        dmonaibu[j - TLC] = sqrt( sum * sum );
      }
    }

    /* t-1 : 出力層の誤差信号の計算 */
    for( i = 0 ; i < TLC ; i++ ){
      dmo[i] = outkeep[i] * ( 1 - outkeep[i] ) * ( inkeep[i][t] - outkeep[i] );
    }

    /* t-1 : 出力層と内部記憶層の重み補正 */
    for( j = 0 ; j < Midunit ; j++ ){
      for( sum = 0 , i = 0 ; i < TLCN ; i++ ){
        sum += ( dmo[i] * wmo[i][j] );
      }
      dim[j] = midkeep[j] * ( 1 - midkeep[j] ) * sum;
      dimlate[j] = sqrt( sum * sum );
    }

    /* t-1 : 中間層の重み補正 */
    for( j = 0 ; j < Inunit ; j++ ){
      for( sum = 0 , i = 0 ; i < Midunit ; i++ ){
        sum += ( dim[i] * wim[i][j] );
      }
      /* t-2 : 内部記憶層の誤差信号の計算 */
      if( j >= TLC && j < TLCN ){
        dmo[j] = outkeep2[j] * ( 1 - outkeep2[j] ) * sum;
      }
    }

    /* t-2 : 出力層の誤差信号の計算 */
    for( i = 0 ; i < TLC ; i++ ){
      dmo[i] = outkeep2[i] * ( 1 - outkeep2[i] ) * ( inkeep[i][h] - outkeep2[i] );
    }

    /* t-2 : 出力層と内部記憶層の重み補正 */
    for( j = 0 ; j < Midunit ; j++ ){
      sum = 0;
      for( i = 0 ; i < TLC ; i++ ){
        dwmo[i][j] = ( Eta * dmo[i] * midkeep2[j] ) + ( Alpha * dwmo[i][j] );
        sum += ( dmo[i] * wmo[i][j] );
        wmo[i][j] += dwmo[i][j];
      }
      for( i = TLC ; i < TLCN ; i++ ){
        dwmo[i][j] = ( Eta * dmo[i] * midkeep2[j] ) + ( Alpha * dwmo[i][j] );
        sum += ( dmo[i] * wmo[i][j] );
        wmo[i][j] += dwmo[i][j];
      }
      dim[j] = midkeep2[j] * ( 1 - midkeep2[j] ) * sum;
      dimlate2[j] = sqrt( sum * sum );
    }

    /* t-2 : 出力層の閾値補正 */
    for( i = 0 ; i < TLC ; i++ ){
      dsikiimo[i] = ( Eta * dmo[i] ) + ( Alpha * dsikiimo[i] );
      sikiimo[i] += dsikiimo[i];
    }
    /* t-2 : 内部記憶層の閾値補正 */
    for( i = TLC ; i < TLCN ; i++ ){
      dsikiimo[i] = ( Eta2 * dmo[i] ) + ( Alpha * dsikiimo[i] );
      sikiimo[i] += dsikiimo[i];
    }

    /* t-2 : 中間層の重み補正 */
    for( j = 0 ; j < Inunit ; j++ ){
      for( i = 0 ; i < Midunit ; i++ ){
        dwim[i][j] = ( Eta * dim[i] * inout[j][f] ) + ( Alpha * dwim[i][j] );
        wim[i][j] += dwim[i][j];
      }
    }

    /* t-2 : 中間層の閾値補正 */
    for( i = 0 ; i < Midunit ; i++ ){
      dsikiiim[i] = ( Eta * dim[i] ) + ( Alpha * dsikiiim[i] );
      sikiiim[i] += dsikiiim[i];
    }    

    break;

    /* ******** 4-step Learning ************************** */
  case 4:

    /* t : 出力層の誤差伝搬 */
    for( j = 0 ; j < Midunit ; j++ ){
      for( sum = 0 , i = 0 ; i < TLC ; i++ ){
        sum += ( dmo[i] * wmo[i][j] );
      }
      /* t : 中間層の誤差信号の計算 */
      dim[j] = midout[j] * ( 1 - midout[j] ) * sum;
      dimget[j] = sqrt( sum * sum );
    }

    /* t : 中間層の誤差伝搬 */
    for( j = 0 ; j < Inunit ; j++ ){
      for( sum = 0 , i = 0 ; i < Midunit ; i++ ){
        sum += ( dim[i] * wim[i][j] );
      }
      /* t : 内部記憶層の誤差信号の計算 */
      if( j >= TLC && j < TLCN ){
        dmo[j] = outkeep[j] * ( 1 - outkeep[j] ) * sum;
        dmonaibu[j - TLC] = sqrt( sum * sum );
      }
    }

    /* t-1 : 出力層の誤差信号の計算 */
    for( i = 0 ; i < TLC ; i++ ){
      dmo[i] = outkeep[i] * ( 1 - outkeep[i] ) * ( inkeep[i][t] - outkeep[i] );
    }

    /* t-1 : 出力層と内部記憶層の重み補正 */
    for( j = 0 ; j < Midunit ; j++ ){
      for( sum = 0 , i = 0 ; i < TLCN ; i++ ){
        sum += ( dmo[i] * wmo[i][j] );
      }
      dim[j] = midkeep[j] * ( 1 - midkeep[j] ) * sum;
      dimlate[j] = sqrt( sum * sum );
    }

    /* t-1 : 中間層の重み補正 */
    for( j = 0 ; j < Inunit ; j++ ){
      for( sum = 0 , i = 0 ; i < Midunit ; i++ ){
        sum += ( dim[i] * wim[i][j] );
      }
      /* t-2 : 内部記憶層の誤差信号の計算 */
      if( j >= TLC && j < TLCN ){
        dmo[j] = outkeep2[j] * ( 1 - outkeep2[j] ) * sum;
      }
    }

    /* t-2 : 出力層の誤差信号の計算 */
    for( i = 0 ; i < TLC ; i++ ){
      dmo[i] = outkeep2[i] * ( 1 - outkeep2[i] ) * ( inkeep[i][h] - outkeep2[i] );
    }

    /* t-2 : 出力層と内部記憶層の重み補正 */
    for( j = 0 ; j < Midunit ; j++ ){
      for( sum = 0 , i = 0 ; i < TLCN ; i++ ){
        sum += ( dmo[i] * wmo[i][j] );
      }
      dim[j] = midkeep2[j] * ( 1 - midkeep2[j] ) * sum;
      dimlate2[j] = sqrt( sum * sum );
    }

    /* t-2 : 中間層の重み補正 */
    for( j = 0 ; j < Inunit ; j++ ){
      for( sum = 0 , i = 0 ; i < Midunit ; i++ ){
        sum += ( dim[i] * wim[i][j] );
      }
      if( j >= TLC && j < TLCN ){
        dmo[j] = outkeep3[j] * ( 1 - outkeep3[j] ) * sum;
      }
    }

    /* t-3 : 出力層の誤差信号の計算 */
    for( i = 0 ; i < TLC ; i++ ){
      dmo[i] = outkeep3[i] * ( 1 - outkeep3[i] ) * ( inkeep[i][f] - outkeep3[i] );
    }

    /* t-3 : 出力層と内部記憶層の重み補正 */
    for( j = 0 ; j < Midunit ; j++ ){
      sum = 0;
      for( i = 0 ; i < TLC ; i++ ){
        dwmo[i][j] = ( Eta * dmo[i] * midkeep3[j] ) + ( Alpha * dwmo[i][j] );
        sum += ( dmo[i] * wmo[i][j] );
        wmo[i][j] += dwmo[i][j];
      }
      for( i = TLC ; i < TLCN ; i++ ){
        dwmo[i][j] = ( Eta2 * dmo[i] * midkeep3[j] ) + ( Alpha * dwmo[i][j] );
        sum += ( dmo[i] * wmo[i][j] );
        wmo[i][j] += dwmo[i][j];
      }
      dim[j] = midkeep3[j] * ( 1 - midkeep3[j] ) * sum;
      dimlate2[j] = sqrt( sum * sum );
    }

    /* t-3 : 出力層の閾値補正 */
    for( i = 0 ; i < TLC ; i++ ){
      dsikiimo[i] = ( Eta * dmo[i] ) + ( Alpha * dsikiimo[i] );
      sikiimo[i] += dsikiimo[i];
    }
    /* t-3 : 内部記憶層の閾値補正 */
    for( i = TLC ; i < TLCN ; i++ ){
      dsikiimo[i] = ( Eta2 * dmo[i] ) + ( Alpha * dsikiimo[i] );
      sikiimo[i] += dsikiimo[i];
    }

    /* t-3 : 中間層の重み補正 */
    for( j = 0 ; j < Inunit ; j++ ){
      for( i = 0 ; i < Midunit ; i++ ){
        dwim[i][j] = ( Eta * dim[i] * inout[j][e] ) + ( Alpha * dwim[i][j] );
        wim[i][j] += dwim[i][j];
      }
    }

    /* t-3 : 中間層の閾値補正 */
    for( i = 0 ; i < Midunit ; i++ ){
      dsikiiim[i] = ( Eta * dim[i] ) + ( Alpha * dsikiiim[i] );
      sikiiim[i] += dsikiiim[i];
    }    

    break;

  }
}



Toshinori DEGUCHI
2003年 4月11日 金曜日 11時42分54秒 JST