/*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);
}
}
}