/*3層モデル 3*5pattern ニューロン数173*/ #include <stdio.h> #define M (3) #define L (5) #define N (173) #define ON (1) #define OFF (-1) #define CTMAX (20) #define DATA "3sou_rand1.dat" #define NOISE "3sou_noise1.dat" double drand48(); int next(p) int p; { if(((p + 1) % M ) == 0) return (p +1 -M); else return (p +1 ); } void noise(a) int a; { FILE *fi,*fo; int c,count; fi = fopen(DATA,"r"); fo = fopen(NOISE,"w"); count = 0; while ((c = getc(fi)) != EOF && count < N){ switch(c){ case('0'): case('1'): count ++; if (drand48() < (double)a / 100) c = (c == '1' ? '0' :'1'); putc(c,fo); break; default: putc(c,fo); break; } } fclose(fi); fclose(fo); } void main() { int a,b,c; short int x[M * L][N], xin[N],xhide[N],xout[N],yin[N], yhide[N],yout[N],xbefore[N],xoinit[N],xiinit[N],xhinit[N]; short int right,ctr,ct,i,j,pattern,count,sumi,sumh,sumo; short int wii[N][N],wih[N][N],wio[N][N],whi[N][N], whh[N][N],who[N][N],woi[N][N],woh[N][N],woo[N][N]; double ratio; FILE *fi; srand48(6); /* 記憶するパターンをファイルから読み込む */ if((fi = fopen(DATA,"r")) == NULL){ fprintf(stderr,"データが読めません\n"); exit(-1); } pattern = -1; i = 0; while ((c = getc(fi)) !=EOF && pattern < M * L){ switch(c){ case('0'): case('1'): if (i < N){ x[pattern][i] = (c == '0' ? OFF :ON); i++; } break; case('x'): pattern ++; i = 0; break; default: break; } } fclose(fi); /* シナプス荷重初期化 */ for(i = 0;i < N;i++){ for(j = 0;j < N;j++){ wii[i][j] = 0; wih[i][j] = 0; wio[i][j] = 0; whi[i][j] = 0; whh[i][j] = 0; who[i][j] = 0; woi[i][j] = 0; woh[i][j] = 0; woo[i][j] = 0; } } /* 記憶過程 */ for(pattern = 0;pattern < M * L;pattern++){ for(i = 0;i < N ;i++){ for(j = 0;j < N;j++){ wii[i][j] += (x[pattern][i] * x[next(pattern)][j] ); wih[i][j] += (x[pattern][i] * x[next(next(pattern))][j] ); wio[i][j] += (x[pattern][i] * x[pattern][j] ); whi[i][j] += (x[pattern][i] * x[pattern][j] ); whh[i][j] += (x[pattern][i] * x[next(pattern)][j] ); who[i][j] += (x[pattern][i] * x[next(next(pattern))][j] ); woi[i][j] += (x[pattern][i] * x[next(next(pattern))][j] ); woh[i][j] += (x[pattern][i] * x[pattern][j] ); woo[i][j] += (x[pattern][i] * x[next(pattern)][j] ); } } } fprintf(stderr,"学習させてもらいました。これからノイズを加えます。\n"); /* ノイズを変えてゆく */ for(a = 15;a <=50;a++){ for(b = 0;b < 100;b++){ noise(a); if ((fi = fopen(NOISE,"r")) == NULL){ fprintf(stderr,"ノイズファイルを開けません \n"); exit(-1); } i = 0; while ((c = getc(fi)) !=EOF){ switch(c){ case('0'): case('1'): if(i < N ){ xiinit[i] = (c == '0' ? OFF : ON); i++; } else if(i < N * 2){ xhinit[i - N] = (c == '0' ? OFF :ON); i++; } else if( i < N * 3){ xoinit[i - 2 * N] = (c == '0' ? OFF :ON); i++; } break; default: break; } } fclose(fi); /* 想起過程 */ for(i = 0;i < N;i++){ xout[i] = xoinit[i]; xhide[i] = xhinit[i]; xin[i] = xiinit[i]; xbefore[i] = OFF; } for(j = 0;j < N;j++){ yout[j] = OFF; } /* 安定したかどうか */ count = 0;ctr = 0; while(ctr != N && count < CTMAX){ for(ct = 0;ct < M ;ct++){ for(j = 0; j< N;j++){ sumi = 0; sumh = 0; sumo = 0; for(i = 0;i < N;i++){ sumi += (wii[i][j] * xin[i] + whi[i][j] * xhide[i] + woi[i][j] * xout[i]); sumh += (wih[i][j] * xin[i] + whh[i][j] * xhide[i] + woh[i][j] * xout[i]); sumo += (wio[i][j] * xin[i] + who[i][j] * xhide[i] + woo[i][j] * xout[i]); } yin[j] = (sumi < (ON + OFF) / 2 ? OFF : ON); yhide[j] = (sumh < (ON + OFF) /2 ? OFF :ON); yout[j] = (sumo < (ON + OFF) /2 ? OFF :ON); } for(i = 0;i < N ;i++){ xin[i] = yin[i]; xhide[i] = yhide[i]; xout[i] = yout[i]; } } ctr = 0; for(i = 0;i < N;i++){ if (xout[i] == xbefore[i] ) ctr++; xbefore[i] = xout[i]; } count++; } /* 安定した割合 */ right = 0; for(i = 0;i < N ;i++){ if(xout[i] == x[2][i] ) right++; } ratio = (double)right / (double)N *100; printf("%d %f\n",a,ratio); fflush(stdout); } } }