next up previous contents
Next: 設定ファイル Up: 無題 Previous: 学習プログラム

想起プログラム

/* 内部記憶をもつ形の想起 */
/* 定数をランダムにしたり適当にいれて想起 */

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

#define   RECALL

#include  "grobal.h"      /* 自作のヘッダ */
#include  "protfunc.h"
#include  "funcdef.h"

int main( int argc , char **argv ){

  srand48( Seed );                /* 乱数の設定 */
  options_recall( argc , argv );  /* オプション */
  load_prm( fi_weight );          /* 結合荷重を読み込む */
  set_teach( Data );              /* 教師信号を読み込む */
  set_file();                     /* 出力ファイルの設定 */
  set_input();                    /* 入力値の設定 */
  recall();                       /* 実際に想起を行なう */
  sort();                         /* 曲の順序を並べかえる */
  output_file();                  /* ファイルに出力する */
  output_song();                  /* 曲を出力する */
  if( Flag_weightsearch != 0 ) weight_search(); /* 結合荷重の測定をする */
  return 0;
}

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

  while( --argc ){
    if( **++argv == '-' ){
      switch( *++*argv ){
      case 'r':             /* 内部記憶部分をランダムにする */
        Flag_random = 1;
        break;
      case 'z':             /* 0にする */
        if( --argc ){
          Flag_zero = 1;
          Set_zero = atof( *++argv );
          if( Set_zero < 0 ) Set_zero = 0;
          break;
        }
      case 's':
        if( --argc ){
          Flag_inout = 1;   /* 1にしてそれ以外を0にする */
          Set_inout = atof( *++argv );
          if( Set_inout < 0 ) Set_inout = 0;
          break;
        }
      case 'a':             /* 教師信号を除去する */
        Flag_teachcut = 1;
        break;
      case 'n':             /* 入力にノイズをのせる */
        if( --argc ){
          Flag_inc = 1;
          Noize = atof( *++argv );
          break;
        }
      default:
usage:
        fprintf( stderr , "Usage: pout16 [-r] [-z Number] WeightFile.data\n" );
        exit(-1);
      }
    } else {
      if( fi_weight == NULL ){
        fi_weight = *argv;
      } else {
        goto usage;
      }
    }
  }

}

/* 結合荷重等の定数を読み込む関数 */
void    load_prm( char *filename ){

  FILE  *fp;
  size_t wsize;
  int   i;

  if( filename != NULL ){
    if(( fp = fopen( filename , "r" )) == NULL ){
      fprintf( stderr , "Can't Open %s\n" , filename );
      exit(1);
    }
  } else {
    fp = stdin;
  }
  wsize = sizeof( double );
  
  /* 各定数を読み込む */
  fread( inout , wsize , Inunit * Time , fp );
  fread( inkeep , wsize , Inunit * Time , fp );
  fread( wim , wsize , Inunit * Midunit , fp );
  fread( wmo , wsize , Midunit * Outunit , fp );
  fread( sikiiim , wsize , Midunit ,fp );
  fread( sikiimo , wsize , Outunit ,fp );
  fclose( fp );
  
}

/* 入力データを設定する */
void  set_input(){

  int i;

  if( Flag_random != 0 ){   /* 内部記憶部分をランダムにする */
    for( i = TLC ; i < Inunit ; i++ ){
      inout[i][0] = quantum( qrand() );
    }
  }
  if( Flag_zero != 0 ){     /* 値を0にする */
    for ( i = TLC + Set_zero ; i < Inunit ; i++ ){
      inout[i][0] = 0.0;
    }
  }
  if( Flag_inout != 0 ){    /* 1にしてそれ以外を0にする */
    for( i = TLC ; i < Inunit ; i++ ){
      inout[i][0] = 0.0;
    }
    inout[Set_inout][0] = 1.0;
  }
}

/* 実際に想起を行なう関数 */
void  recall(){

  int  i,j;
  int  g,h;

  /* 想起部分 */
  for( k = 0 ; k < Souki ; k++ ){

    if( k == 0 ){
      for( i = 0 ; i < TLC ; i++ ){
        if( Flag_teachcut != 0 ){  /* 第1音を与えない */
          inout[i][0] = 0;
        } else {
          inout[i][0] = inkeep[i][0];
        }
      }
      if( Flag_inc != 0 ) inout[0][0] = inout[0][0] + Noize; /* ノイズを含める */
      if( Flag_view != 0 ) input_view(); /* 状態を表示 */
    }

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

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

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

      switch( Flag_caos ){
      case 1 :
        caos_forward_propagation(); /* カオスNNを利用した想起 */
      default :
        forward_propagation();
      }

      if( k == Souki - 1 )  plot_func();  /* 重みと結合荷重の特性をとる */
      output_correct();                   /* 量子化を行なう */

      if( k % 1000 == 0 && Flag_view != 0 )
        printf( "%f %f %f %f\n",outout[0],outout[1],inkeep[0][t],inkeep[1][t] );

      feedback();  /* フィードバックする */

      for( j = 0 ; j < Tunit ; j++ ){ /* 出力値を保存しておく */
        songkeep[j][t] = outout[j];
      }

    }
  }

}

/* 環境状況を標準出力する */
void input_view(){

  int i;

  printf( "Tunit\n" ); /* 教師信号の値を確認 */
  printf( "%f %f\n" , inout[0][0] , inout[1][0] );

  printf( "Lunit\n" ); /* 補助入力層の値を確認 */
  for( i = Tunit ; i < TL ; i = i + 4 ){
    printf( "%f %f %f %f\n" , inout[i][0] , inout[i + 1][0] , inout[i + 2][0] , inout[i + 3][0] );
  }

  printf( "Cunit\n" );
  for( i = TL ; i < TLC ; i = i + 4 ){
    printf( "%f %f %f %f\n" , inout[i][0] , inout[i + 1][0] , inout[i + 2][0] , inout[i + 3][0] );
  }

  printf( "Nunit\n" ); /* 内部記憶層の値を確認 */
  for( i = TLC ; i < TLCN ; i = i + 4 ){
    printf( "%f %f %f %f\n" , inout[i][0] , inout[i + 1][0] , inout[i + 2][0] , inout[i + 3][0] );
  }

  printf( "Eunit\n" );
  for( i = TLCN ; i < Inunit ; i = i + 4 ){
    printf( "%f %f %f %f\n" , inout[i][0] , inout[i + 1][0] , inout[i + 2][0] , inout[i + 3][0] );
  }
  printf( "\n" );

}

/* 想起した曲をファイルに出力する */
void output_song(){

  int i;

  for( t = 0 ; t < tsmax ; t++ ){
    fprintf( fpsong , "%f %f\n",song[0][t] , song[1][t] );
  }

  fclose( fpsong );

}

/* カオスNNを用いたフォワードプロパゲーション */
void    caos_forward_propagation(){

  int     i,j;
  double  sum;

  for( i = 0 ; i < Midunit ; i++ ){
    sum = 0;
    for( j = 0 ; j < Inunit ; j++ ){
      sum += wim[i][j] * inout[j][t];
    }
    old_em[i] = em[i];
    em[i] = km * old_em[i] + sum;
    old_zm[i] = zm[i];
    old_midout[i] = midout[i];
    zm[i] = kr * zm[i] - al * old_midout[i];
    midout[i] = fsig( em[i] + zm[i] + sikiiim[i] );
  }

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

}

/* 想起された曲をならびかえる */
void sort(){

  int  i,k;
  int  set;
  int  delay_s;
  int  flag_minus = 0;

  /* 位相差の測定 */
  for( i = 0 ; i < tsmax ; i++ ){
    if( songkeep[0][i] == 1.0 ) delay_s = i + 1; /* 最終音1.0を基準に */
    if( delay_s >= tsmax / 2 ){  /* この条件ちょっとおかしい */
      delay_s = tsmax - i - 2;
      flag_minus = 1;
    }
  }
  if( flag_minus != 0 ){
    printf( "delay = - %d\n" ,delay_s );
  } else {
    printf( "delay = %d\n" ,delay_s );
  }

  /* 並び替えを行なう */
  set = 0;
  for( i = 0 ; i < tsmax ; i++ ){
    if( songkeep[0][i] == 1.0 ){ /* 最終音1.0を基準に */
      set = i;
      break;
    } else {
      set = 0; /* なければそのまま */
    }
  }
  for( i = 0 , k = set + 1 ; i < tsmax ; i++ , k++ ){
    if( k >= tsmax )  k = 0;
    song[0][i] = songkeep[0][k];
    song[1][i] = songkeep[1][k];
  }
}

/* ファイルに出力する */
void  output_file(){

  int  i,j;

  for( i = TLC ; i < TLCN ; i++ ){  /* 内部記憶層の出力を保存 */
    for( j = 0 ; j < tsmax ; j++ ){
      fprintf( fpnaibu , "%f\n" , inout[i][j] );
    }
  }
  fclose( fpnaibu );

  if( Flag_timenaibu != 0 ){  /* 内部記憶層のt - t+1 特性の保存 */

    for( i = TLC ; i < TLCN ; i++ ){
      for( j = 0 ; j < tsmax ; j++ ){
        if( j >= tsmax - 1 ){
          fprintf( fpnaibu2 , "%f %f\n" , inout[i][j] , inout[i][0] );
        } else {
          fprintf( fpnaibu2 , "%f %f\n" , inout[i][j] , inout[i][j + 1] );
        }
      }
    }

  }
  fclose( fpnaibu2 );

  if( Flag_weightplot != 0 ){  /* 各結合荷重の保存 */

    for( j = 0 ; j < Midunit ; j++ ){
      for( i = 0 ; i < TLC ; i++ ){
        fprintf( fpweight_tm , "%f " , wim[j][i] );
      }
      fprintf( fpweight_tm , "\n" );

      for( i = TLC ; i < Inunit ; i++ ){
        fprintf( fpweight_nm , "%f " , wim[j][i] );
      }
      fprintf( fpweight_nm , "\n" );

      for( i = 0 ; i < TLC ; i++ ){
        fprintf( fpweight_mt , "%f " , wmo[i][j] );
      }
      fprintf( fpweight_mt , "\n" );

      for( i = TLC ; i < Outunit ; i++ ){
        fprintf( fpweight_mn , "%f " , wmo[i][j] );
      }
      fprintf( fpweight_mn , "\n" );
    }

    fclose( fpweight_tm );
    fclose( fpweight_nm );
    fclose( fpweight_mt );
    fclose( fpweight_mn );

  }

}

/* 結合荷重の積(=入力に1を与えた時の影響)を測定する */
void weight_search(){

  int i , j , k;
  double indata[Inunit][TLC];
  double sum;
  char fi[Smax];
  FILE *fp;

  sprintf( fi , "kekka19/song/wsearch_ver%d.dat" ,Filenumber );
  fp = fopen( fi ,"w" );
  if( fp == NULL ){
    fprintf( stderr, "File not open!\n" );
    exit(1);
  }

  for( k = 0 ; k < TLC ; k++ ){
    for( i = 0 ; i < Inunit ; i++ ){
      sum = 0;
      for( j = 0 ; j < Midunit ; j++ ){
        sum += wim[j][i] * wmo[k][j];
      }
      indata[i][k] = sum;
    }
  }

  for( j = 0 ; j < Inunit ; j++ ){
    for( i = 0 ; i < TLC ; i++ ){
      fprintf( fp , "%f " , indata[j][i] );
    }
    fprintf( fp , "\n" );
  }

  fclose( fp );

}

void plot_func(){

  int i,j;

  if( Flag_weightplot02 != 0 ){  /* 出力値-結合荷重特性 */

    for( j = 0 ; j < TLC ; j++ ){
      for( i = 0 ; i < Midunit ; i++ ){
        fprintf( fpweight02_mt , "%f %f\n" , outout[j] , wmo[j][i] );
      }
    }
    for( j = TLC ; j < Outunit ; j++ ){
      for( i = 0 ; i < Midunit ; i++ ){
        fprintf( fpweight02_mn , "%f %f\n" , outout[j] , wmo[j][i] );
      }
    }
    for( j = 0 ; j < Midunit ; j++ ){
      for( i = 0 ; i < TLC ; i++ ){
        fprintf( fpweight02_tm , "%f %f\n" , midout[j] , wim[j][i] );
      }
      for( i = TLC ; i < Inunit ; i++ ){
        fprintf( fpweight02_nm , "%f %f\n" , midout[j] , wim[j][i] );
      }
    }

    fclose( fpweight02_tm );
    fclose( fpweight02_nm );
    fclose( fpweight02_mt );
    fclose( fpweight02_mn );

  }

}



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