#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]; } }