/* 内部記憶を持つニューラルネット */
#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;
}
}