next up previous contents
Next: 付録B 局所的な追加学習をするプログラム Up: 無題 Previous: 参考文献

付録A 広域的な追加学習をするプログラム

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <local/bgi.h>

#define S   3        /*始めに覚えるパターンの数*/     
#define Z   49       /*ニューロンの総数*/
#define Kr  0.95     /*外部入力の係数*/
#define Ks  0.99     /*相互結合の係数*/
#define Km  0.1      /*不応性の係数*/
#define a   2.0      /*不応性の係数*/
#define v   2.0      /*外部入力の係数*/
#define Q   0.0      /*閾値*/
#define A   7        /*ニューロンの縦の数*/
#define ll  7        /*ニューロンの横の数*/
#define kkk 6
#define Vth 50       /*変化量の閾値*/
#define ZZ  50       /*離散時間の総数*/
#define E   0.015    /*シグモイド関数の係数*/
#define AA  50     
#define BB  100
#define CC  150
#define DD  175      /*各外部入力の離散時間の数*/
#define EE  200
#define FF  225
#define GG  250
#define HH  275

static char tim[ZZ];

FILE *e; 
FILE *f1;
FILE *ff;
FILE *ee;
FILE *f2;

char c[10];
char ccc[10];
char mm[Z];
char gg[Z];

void kazyu1();         /*始めに覚えるパターンを読み込む*/
void kazyu2();         /*結合荷重を計算する*/
void kazyu3();         /*新しいパターンを読み込む*/
void gaibu();          /*外部入力の計算*/
void sougo();          /*相互結合の計算*/
void fuou();           /*不応性の計算*/
void keisan();         /*ニュウロンの出力の計算*/
void hanbetu1();       /*外部入力と相互結合、不応性の影響力*/
void hanbetu2();       /*変化量の計算*/
void hanbetu3();       /*入力パターンの変化の判別*/
void kakikomi();       /*ファイルに書き込む*/
void syuturyoku();     /*グラフィクで表す*/
void graf();           /*グラフを書く*/

double drand48();

int    t,oo,ooo,r,tt,ttt,yy,ss,rr,onazi,onazi1;
int    w[Z][Z],m[ZZ][Z],mnoi[ZZ][Z],mnoi1[ZZ][Z],mnoi2[Z],g[10][Z],xx[ZZ][Z];
double V,yyy;
double xdata[ZZ],xnoi[ZZ],xnoi2[ZZ];
double n[ZZ][Z],nn[ZZ][Z],nnn[ZZ][Z],x[ZZ][Z];



/*メインプログラム*/

main()
 {

  ff=fopen("AS1.DAT","w");
  ee=fopen("MITI.DAT","w"); 
  t=0;
  ooo=0;
  tt=0;
  ttt=0;
  r=S;
  kazyu1();
  kazyu2();
  printf("ノイズなら 1 欠落させるなら0          ");
  scanf("%d",&ss);
  if(ss==1)
    printf("何個 ノイズをいれる      ");
  else
    printf("何個 欠落させる          ");
  scanf("%d",&yy);
  while(ttt<ZZ)
   {
    gaibu();
    hanbetu3();
    sougo();
    fuou();
    keisan();
    hanbetu1();
    kakikomi();
    t=t+1;
    ttt=ttt+1;
    if(oo==Z)
    hanbetu2();
    if(ooo==1)
     {  
      kazyu3();
      kazyu2();
      ooo=0;
     }
   }
  syuturyoku();
  graf();
  fclose(ff);
  fclose(ee);
 }
   


/*結合荷重割り当て*/

void kazyu3()
 {

  int i,j;
 
  if(ooo==1)
   {
    for(rr=0;rr<r;rr++)
     {
      onazi=0;
      for(i=0;i<Z;i++)
      if(g[rr][i]==xx[tt][i])
        onazi=onazi+1;
      if(onazi==Z)
        onazi1=1;
     }
    if(onazi1!=1)
     {
      for(i=0;i<Z;i++)
        g[r][i]=xx[tt][i];
      fprintf(ee,"\n");
      for(i=0;i<Z;i++) 
      if(g[r][i]==1)
        gg[i]='#';
      else
        gg[i]=':';
      j=0;
      for(i=0;i<Z;i++)
        if(j==kkk) 
         {
          fprintf(ee,"%c\n",gg[i]);
          j=0;
         }
        else 
         {
          fprintf(ee,"%c",gg[i]);
          j=j+1;
         }
      r=r+1;
     }
   }
 }


void kazyu1()
 {

  int b,i,j,o,l,y,aa,d,h,hh,k,xx;
  
  i=0;j=0;b=0;o=0;
  e=fopen("HAM.DAT","r");
  for(h=0;h<r;h++)
   {
    b=0;
    for(j=0;j<A;j++)
     {
      fscanf(e,"%s",ccc);
      for(l=0;l<ll;l++) 
       {
        if (ccc[l]=='#')
          xx=1;
        else
          xx=-1;
        g[h][l+b]=xx;
       }
      b=b+ll;
     }
   }
  fclose(e);
 }

  
 void kazyu2()
{

  int i,j,y,aa,d,h;

  for(i=0;i<Z;i++)
    for(j=0;j<Z;j++) 
     {
      d=0;
      if(i!=j)
        for(h=0;h<r;h++) 
         {
          y=g[h][i];
          aa=g[h][j];
          d=d+aa*y;
         }
      else
        d=0;
      w[i][j]=d;
     }
 }
 


/*外部入力*/

void gaibu()
 {

  int    bb,b,l,i,j,cc,aa,kaz,kazu1,dame,noi3;
  double noi,noi1,noi2[Z]; 

  if(ttt<AA)
    f1=fopen("DATA66.DAT","r");
  if(AA-1<ttt && ttt<BB)
    f1=fopen("DATA888.DAT","r");
  if(BB-1<ttt && ttt<CC)
    f1=fopen("DATA999.DAT","r");
  if(CC-1<ttt && ttt<DD)
    f1=fopen("DATA66.DAT","r");
  if(DD-1<ttt && ttt<EE)
    f1=fopen("DATA77.DAT","r");
  if(EE-1<ttt && ttt<FF)
    f1=fopen("DATA44.DAT","r");
  if(FF-1<ttt && ttt<GG)
    f1=fopen("DATA55.DAT","r");
  if(GG-1<ttt && ttt<HH)
    f1=fopen("DATA888.DAT","r");
  if(HH-1<ttt && ttt<ZZ)
    f1=fopen("DATA999.DAT","r");
  b=0;
  for(j=0;j<A;j++) 
   {
    fscanf(f1,"%s",c);
    for(l=0;l<ll;l++) 
     {
      if(c[l]=='#')
        cc=1;
      else
        cc=-1;
      m[ttt][l+b]=cc;
     }
    b=b+ll;
   }
  kaz=1;
  i=1;
  noi=drand48();
  noi1=noi*48;
  noi2[0]=(int)noi1;
  while(kaz<yy)
   {
    kazu1=0;
    while(kazu1<1)
     { 
      noi=drand48();         /*ノイズを入れる*/
      noi1=noi*49;
      noi3=(int)noi1;
      if(noi3==49)
        noi3=48;
      dame=0;
      for(j=0;j<i;j++)
        if(noi2[j]==noi3)
          dame=dame+1;
        if(dame==0)
         {
          kazu1=1;
          noi2[i]=noi3;
         }
        else
      kazu1=0;
     }
    kaz=kaz+1;
    i=i+1;
   } 
  for(i=0;i<Z;i++)
    mnoi[ttt][i]=m[ttt][i];
  for(i=0;i<yy;i++)
   {
    aa=noi2[i];
    if(ss==1)
      if(mnoi[ttt][aa]==1)
        mnoi[ttt][aa]=-1;
      else
        mnoi[ttt][aa]=1;
    else
      mnoi[ttt][aa]=0;
   }
  for(i=0;i<Z;i++)
    if(mnoi[ttt][i]>0)
      mnoi1[ttt][i]=1;
    else
      mnoi1[ttt][i]=-1; 
  for(i=0;i<Z;i++)
   {
    if(t==0)
      n[t][i]=v*mnoi[ttt][i];
    else
      n[t][i]=Ks*n[t-1][i]+v*mnoi[ttt-1][i];
   }
  fclose(f1);
}


 
/*ニューロン間の相互結合*/

void sougo()
 {

  int    i,j;
  double p,pp;

  for(i=0;i<Z;i++)
   {
    if(t==0)
     { 
      p=0;
      for(j=0;j<Z;j++) 
        p=w[i][j]*mnoi[ttt][j]+p;  
      nn[t][i]=p;
     }
    else
     { 
      pp=0;
      for(j=0;j<Z;j++)
        pp=w[i][j]*x[ttt-1][j]+pp;
      nn[t][i]=Km*nn[t-1][i]+pp;
     }
   }
 
}



/*ニューロン自身の不応性*/

void fuou()
 {

  int i,j;

  for(i=0;i<Z;i++)
    if(t==0)
      nnn[t][i]=-a*mnoi[ttt][i]-Q;
    else
      nnn[t][i]=Kr*nnn[t-1][i]-a*x[ttt-1][i]-Q;

 }



/*ニューロンの計算*/

 void keisan()
 {

  int    i,j;
  double uu;


  uu=0.0;
  for(i=0;i<Z;i++)
   { 
    if(t==0)
      x[ttt][i]=mnoi[ttt][i];
    else
     {
      uu=n[t][i]+nn[t][i]+nnn[t][i];
      x[ttt][i]=2/(1+exp(-uu/E))-1;
     }
    if(x[ttt][i]>0)
      xx[ttt][i]=1;
    else
      xx[ttt][i]=-1;
   }
}



/*書き込み*/
 
void kakikomi()
 {
  int q[Z],i,j;
 
  for(i=0;i<Z;i++)  
    if(x[ttt][i]>0)
      q[i]=1;
    else
      q[i]=-1;
  for(i=0;i<Z;i++)
    if(q[i]==1)
      mm[i]='#';
    else
      mm[i]=':';
  j=0;
  for(i=0;i<Z;i++) 
   {
    if(j==kkk) 
     {
       fprintf(ff,"%c\n",mm[i]);
       j=0;
     }
    else 
     {
      fprintf(ff,"%c",mm[i]);
      j=j+1;
     }
    }
  fprintf(ff,"\n");
 }



/*未知パターン、既知パターンの判別*/
 
void hanbetu1()
 {
  int    i,j;
  double u,z;

  oo=0;
  for(i=0;i<Z;i++) 
   {
    u=fabs(n[t][i]);
    z=fabs(nn[t][i]+nnn[t][i]);
    if(u>z)
      oo=oo+1;
   }
 }


void hanbetu2()
{
  
  int h,i,j;


   V=0; 
   for(h=tt+2;h<ttt;h++)
     for(i=0;i<Z;i++)
       V=fabs(x[h][i]-x[h-1][i])+V;
   if(V>Vth)
    {
     ooo=1;
     tt=ttt-1;
    }
   else
     ooo=0;
 }


void hanbetu3()
 {
  
  int i,j,zz;


  zz=0;
  if(ttt!=0)
    for(i=0;i<Z;i++)
      if(m[ttt][i]!=m[ttt-1][i])
        zz=zz+1;
  if(zz>9)
   {
    t=0;
    tt=ttt;
    gaibu();
   }
 } 



/*グラフィックを描く */

void syuturyoku()
 {

  int Gd,Gm,i,ii,jj,kai,ka,kka,kki,ki,ku,ke;
  int dd,ddd,tttt,v1,v2,v3,v4;

  ka=100;
  ki=100;
  kka=150;
  kki=150;
  ku=300;
  ke=300; 
  initgraph(Gd,Gm,"1140x960");
  settextfont("7x14");
  for(tttt=0;tttt<ZZ;tttt++)
   {
    sprintf(tim,"t=%u",tttt);
    ddd=tttt%25;
    if(ddd==0)
      dd=tttt/25*80;
    ka=ddd*45+2+10;
    ki=76+dd+2;
    outtextxy(ka,ki,tim);
    v1=ddd*45+1+10;
    v2=dd+1;
    v3=ddd*45+37+10;
    v4=dd+1;
    line(v1,v2,v3,v4);
    v1=ddd*45+1+10;
    v2=dd+1;
    v3=ddd*45+1+10;
    v4=dd+65;
    line(v1,v2,v3,v4);
    v1=ddd*45+37+10;
    v2=dd+1;
    v3=ddd*45+37+10;
    v4=dd+65;
    line(v1,v2,v3,v4);
    v1=ddd*45+1+10;
    v2=dd+65;
    v3=ddd*45+37+10;
    v4=dd+65;
    line(v1,v2,v3,v4);
    for(ii=0;ii<7;ii++)
      for(jj=0;jj<7;jj++)
        if(xx[tttt][ii*7+jj]==-1)
         {
          ka=jj*5+2+ddd*45+2+10;
          ki=ii*9+3+dd+2;
          putpixel(ka,ki,WHITE);
          ka=jj*5+2+ddd*45+2+10;
          ki=ii*9+4+dd+2;
          putpixel(ka,ki,WHITE);
         }
        else
         {
          kka=jj*5+ddd*45+2+10;
          kki=ii*9+dd+2;
          ku=jj*5+4+ddd*45+2+10;
          ke=ii*9+8+dd+2;
          bar(kka,kki,ku,ke);
         }
   }
  graph2xbm("output2.xbm");
  while(!kbhit());
  closegraph();

 }



/*グラフを描く*/

void graf()
 {

  char moji = '"';
  static char str[] = "TitleText:";
  int    i,danoi,daanoi;
  double da,daa,daa2,daa1;

  for(ttt=0;ttt<ZZ;ttt++)
   { 
    da=0;
    daa=0;
    danoi=0;
    daanoi=0;
    for(i=0;i<Z;i++)
     {   
      da=(double)m[ttt][i]*x[ttt][i]+da;
      daa1=(double)abs(m[ttt][i]); 
      daa2=fabs(x[ttt][i]);
      daa=daa1*daa2+daa;
      danoi=m[ttt][i]*mnoi[ttt][i]+danoi;
      daanoi=abs(m[ttt][i])*abs(mnoi[ttt][i])+daanoi;
     }
  
    xdata[ttt]=da/daa;
    xnoi[ttt]=(double)danoi/(double)daanoi;
   } 
  f2=fopen("data2.dat","w");
  if(ss==1)
    fprintf(f2,"%s Noizu Data\n",str);
  else
    fprintf(f2,"%s Keturaku Data\n",str);
  fprintf(f2,"%c |A| \n",moji);
  for(ttt=0;ttt<ZZ;ttt++)
   { 
    fprintf(f2,"%d",ttt);
    fprintf(f2,"%c",' ' );
    fprintf(f2,"%f\n",xdata[ttt]);
   }
  fprintf(f2,"\n");
  fprintf(f2,"%c |A|+|B+C|\n",moji);
  for(ttt=0;ttt<ZZ;ttt++)
   {
    fprintf(f2,"%d",ttt);
    fprintf(f2,"%c",' ' );
    fprintf(f2,"%f\n",xnoi[ttt]);
   }
  fprintf(f2,"\n");
  fprintf(f2,"%c |A+B+C| \n",moji);
  for(ttt=0;ttt<ZZ;ttt++)
   {
    fprintf(f2,"%d",ttt);
    fprintf(f2,"%c",' ' );
    fprintf(f2,"%f\n",xnoi2[ttt]);
   } 
  fclose(f2);
 }



Deguchi Toshinori
1998年03月18日 (水) 13時22分42秒 JST