/*ランダム層モデル 5*3pattern ニューロン数173*/ #include <stdio.h> #define M (5) #define L (3) #define N (173) #define s (4) #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], r[M * L][N],xin[N],xout[N],rout[N], yout[N],xbefore[N],yrout[N]; short int i,j,t,pattern,right,ctr,ct,count,sum,sumr; short int woo[N][N], wor[N][N], wro[N][N], wrr[N][N]; double ratio; FILE *fi; srand48(7); /* 記憶するパターンをファイルから読み込む */ if((fi = fopen(DATA,"r")) == NULL){ fprintf(stderr,"データが読めません\n"); exit(-1); } pattern = -1; i = 0; while ((c = getc(fi)) != EOF && pattern < M * L * 2){ switch(c){ case('0'): case('1'): if ((pattern < M * L) && (i < N)){ x[pattern][i] = (c == '0' ? OFF :ON); i++; } else if (i < N) { r[pattern - M * L][i] = (c == '0' ? OFF :ON); i++; } break; case('x'): pattern ++; i = 0; break; default: break; } } if (!((pattern == M * L * 2) || ((pattern == M * L * 2 - 1) && (i == N)))) { fprintf(stderr, "パターンが足りない\n"); } fclose(fi); for (t = 1;t < 5;t++){ for (i = 0;i < N;i++){ x[t + 4][i] = x[t][i]; } } /* シナプス荷重初期化 */ for(i = 0;i < N;i++){ for(j = 0;j < N;j++){ woo[i][j] = 0; wor[i][j] = 0; wro[i][j] = 0; wrr[i][j] = 0; } } /* 記憶過程 */ for(pattern = 0;pattern < M * L;pattern++){ for(i = 0;i < N;i++){ for(j = 0;j < N;j++){ woo[i][j] += ( x[pattern][i] * x[next(pattern)][j] ); wor[i][j] += ( x[pattern][i] * r[next(pattern)][j] ); wro[i][j] += ( r[pattern][i] * x[next(pattern)][j] ); wrr[i][j] += ( r[pattern][i] * r[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){ xin[i] = (c == '0' ? OFF : ON); i++; } break; default: break; } } fclose(fi); /* 想起過程 */ for(i = 0;i < N;i++){ xout[i] = xin[i]; xbefore[i] = OFF; rout[i] = ((drand48() < 0.5) ? OFF : ON); } for(j = 0;j < N;j++){ yout[j] = yrout[j] = OFF; } /* 安定したかどうか */ count = 0;ctr = 0; while(ctr != N && count < CTMAX){ for(ct = 0;ct < M;ct++){ for(j = 0;j < N;j++){ sum = sumr = 0; for(i = 0;i < N;i++){ sum += (woo[i][j] * xout[i] + wro[i][j] * rout[i]); sumr += (wor[i][j] * xout[i] + wrr[i][j] * rout[i]); } yout[j] = (sum < (ON + OFF) / 2 ? OFF :ON); yrout[j] = (sumr < (ON + OFF) / 2 ? OFF :ON); } for(i = 0;i < N;i++){ xout[i] = yout[i]; rout[i] = yrout[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[0][i] ) right++; } ratio = (double)right / (double)N * 100; printf("%d %f\n",a,ratio); fflush(stdout); } } }