16 #define MODE_RECOGNIZE 0
23 unsigned char **cimage;
27 int width, height,numinputs;
31 int highx[2], highy[2];
32 double highest_confidence[2];
41 int winner,numf1s,numf2s, resonant,cp,numpatterns;
43 double a, b, c, d, theta, delta_t;
83 for (i=0;i<numf2s;i++)
84 if (Y[i].y > Y[winner].y)
94 for (j=0;j<numf1s;j++)
96 norm += f1_layer[j].P * f1_layer[j].P;
98 norm = sqrt((double) norm);
102 for (j=0;j<numf1s;j++)
104 temp_sum = f1_layer[j].U * f1_layer[j].U;
107 norm = sqrt((double) norm);
109 for (j=0;j<numf1s;j++)
110 f1_layer[j].R = (f1_layer[j].U+ c * f1_layer[j].P)/sum;
112 for (j=0;j<numf1s;j++)
113 norm += f1_layer[j].R * f1_layer[j].R;
114 norm = sqrt((double) norm);
116 if (DB2 && (winner==0)) printf("%5.3f",norm);
124 double Su,Sp,numerator,denom;
129 double e = 0.0000000001; /* 10e-10 */
131 su = sp = sup = su2 = sp2=numerator= 0.0;
132 for (j=0;j<numf1s;j++)
136 su2 += f1_layer[j].U * f1_layer[j].U;
137 sp2 += f1_layer[j].P * f1_layer[j].P;
138 sup += f1_layer[j].U * f1_layer[j].P;
140 Su = ((double)numf1s*su2-su*su)/((double)numf1s*((double)numf1s-1.0));
142 Sp = ((double)numf1s*sp2-sp*sp)/((double)numf1s*((double)numf1s-1.0));
144 numerator = (double) numf1s * sup - su * sp;
145 denom = sqrt((double) numf1s*su2 - su*su) * sqrt((double) numf1s*sp2 - sp*sp);
146 r = (numerator+e)/(denom+e);
148 if ((numerator == 0) || (denom==0))
150 fprintf(stderr,"potential div by zero");
153 if ((numerator != 0) && (denom==0))
155 fprintf(stderr,"div by zero");
158 r *= r; /* trying to match inverse images */
160 if (DB1) printf( " simtest2(r) = %8.6f\n",r);
161 if (DB2 && (winner==0)) printf("%8.4f",r);
169 double er = 0.000000001;
177 fprintf(stdout,"winner %d\n",i);
181 for (j=0;j<numf1s;j++)
183 tds[j][i] += g(i)*(f1_layer[j].P - tds[j][i])*delta_t;
184 if (fabs(temp - tds[j][i]) <= er)
191 for (j=0;j<numf1s;j++)
193 bus[j][i] += g(i) * (f1_layer[j].P - bus[j][i]) * delta_t;
194 if ((fabs(temp - bus[j][i]) <= er) && resonant)
211 printf("bad %d good %d\n",bad_count,good_count);
215 /* init_globs - initialize ART 2 parameters based
216 * on whether we are training a network or loading
217 * the weights of a pretrained network.
219 void init_globs(int mode)
221 if (mode==MODE_RECOGNIZE)
227 theta = 1/sqrt((double) numf1s);
237 theta = 1/sqrt((double) numf1s);
241 } /* end of init_globs */
247 f1_layer = (f1_neuron *)malloc(numf1s * sizeof (f1_neuron));
250 fprintf(stderr,"malloc error in init_net\n");
253 for (i=0;i<numf1s;i++)
256 f1_layer[i].I = (double *)malloc(2*sizeof(double));
257 if (f1_layer[i].I==NULL)
259 fprintf(stderr,"malloc error in init_net\n");
271 Y = (xyz *)malloc(numf2s*sizeof(xyz));
274 fprintf(stdout,"Malloc error for Y\n");
285 fscanf(fp,"%i",&lines);
286 for (j=0;j<lines;j++)
287 { fscanf(fp,"%i %f %i %f",&x1,&y1,&x2,&y2);
289 f1_layer[k].I[cp] = ((y2-y1)/(x2-x1) * (k-x2)) + y2;
290 /*I[cp][k] = ((y2-y1)/(x2-x1) * (k-x2)) + y2;*/
298 for(i=0;i<numf1s;i++)
299 fscanf(fp,"%f",&f1_layer[i].I[cp]);
305 for(i=0;i<numf1s;i++)
308 printf(" %8.5f ",f1_layer[i].I[cp]);
317 for (i=0;i<numf1s;i++)
327 for (i=0;i<numf2s;i++)
339 for (i=0;i<numf1s;i++)
349 for (i=0;i<numf2s;i++)
361 printf("============ TOP down WEIGHTS ==============\n");
362 for (i=0;i<numf1s;i++)
363 for (j=0;j<numf2s;j++)
365 printf(" %8.16f\n",tds[i][j]);
367 printf(" %8.16f ",tds[i][j]);
369 printf("============ BOTTOM up WEIGHTS ==============\n");
370 for (i=0;i<numf1s;i++)
371 for (j=0;j<numf2s;j++)
373 printf(" %8.16f\n",bus[i][j]);
375 printf(" %8.16f ",bus[i][j]);
382 for(j=0;j<numf2s;j++)
383 printf(" j = %i Y= %9.7f\n",j,Y[j].y);
386 void train_match(int spot)
387 { int j,matched,f1res,mt;
390 double xr,qr,tsum,ttemp;
392 double match_confidence;
400 for (j=0;j<9 && !f1res ;j++)
403 /* Compute F1 layer - W values */
405 for (ti=0;ti<numf1s;ti++)
407 f1_layer[ti].W = f1_layer[ti].I[cp] + a*(f1_layer[ti].U);
408 tnorm += f1_layer[ti].W * f1_layer[ti].W;
410 tnorm = sqrt((double)tnorm);
411 /* Compute F1 layer - X values */
413 for (tj=0;tj<numf1s;tj++)
414 f1_layer[tj].X = f1_layer[tj].W/tnorm;
416 /* Compute F1 layer - V values */
419 for (ti=0;ti<numf1s;ti++)
421 if (f1_layer[ti].X < theta)
425 if (f1_layer[ti].Q < theta)
429 f1_layer[ti].V = xr + b*qr;
430 tnorm += f1_layer[ti].V * f1_layer[ti].V;
433 /* Compute F1 layer - U values */
434 tnorm = sqrt((double) tnorm);
435 for (tj=0;tj<numf1s;tj++)
436 f1_layer[tj].U = f1_layer[tj].V/tnorm;
440 /* Compute F1 layer - P values */
444 for (ti=0;ti<numf1s;ti++)
447 ttemp = f1_layer[ti].P;
449 for (tj=spot;tj<numf2s;tj++)
451 if ((tj == winner)&&(Y[tj].y > 0))
452 tsum += tds[ti][tj] * d;
455 f1_layer[ti].P = f1_layer[ti].U + tsum;
457 tnorm += f1_layer[ti].P * f1_layer[ti].P;
459 if (ttemp != f1_layer[ti].P)
464 /* Compute F1 - Q values */
466 tnorm = sqrt((double) tnorm);
467 for (tj=0;tj<numf1s;tj++)
468 f1_layer[tj].Q = f1_layer[tj].P;
470 /* Compute F2 - y values */
471 for (tj=spot;tj<numf2s;tj++)
475 for (ti=0;ti<numf1s;ti++)
476 Y[tj].y += f1_layer[ti].P * bus[ti][tj];
481 for (ti=spot;ti<numf2s;ti++)
483 if (Y[ti].y > Y[winner].y)
490 if (DB1) print_f12();
491 if (DB1) printf("\n num iterations for p to stabalize = %i \n",j);
493 match_confidence=simtest();
495 fprintf(stdout,"rho %e\n",match_confidence);
497 if ((match_confidence) > rho)
500 if (DB2 && (winner==0)) printf("#%i",winner);
509 if (DB1) printf("#%iN",winner);
512 for (mt=spot;mt<numf2s;mt++)
521 } /* end of train_match() */
524 { int j,matched,f1res,mt;
527 double xr,qr,tsum,ttemp;
529 double match_confidence;
540 for (j=0;j<9 && !f1res ;j++)
543 /* Compute F1 layer - W values */
545 for (ti=0;ti<numf1s;ti++)
547 f1_layer[ti].W = f1_layer[ti].I[cp] + a*(f1_layer[ti].U);
548 tnorm += f1_layer[ti].W * f1_layer[ti].W;
550 tnorm = sqrt((double)tnorm);
551 /* Compute F1 layer - X values */
553 for (tj=0;tj<numf1s;tj++)
554 f1_layer[tj].X = f1_layer[tj].W/tnorm;
556 /* Compute F1 layer - V values */
559 for (ti=0;ti<numf1s;ti++)
561 if (f1_layer[ti].X < theta)
565 if (f1_layer[ti].Q < theta)
569 f1_layer[ti].V = xr + b*qr;
570 tnorm += f1_layer[ti].V * f1_layer[ti].V;
573 /* Compute F1 layer - U values */
574 tnorm = sqrt((double) tnorm);
575 for (tj=0;tj<numf1s;tj++)
576 f1_layer[tj].U = f1_layer[tj].V/tnorm;
580 /* Compute F1 layer - P values */
584 for (ti=0;ti<numf1s;ti++)
587 ttemp = f1_layer[ti].P;
589 for (tj=0;tj<numf2s;tj++)
591 if ((tj == winner)&&(Y[tj].y > 0))
592 tsum += tds[ti][tj] * d;
595 f1_layer[ti].P = f1_layer[ti].U + tsum;
597 tnorm += f1_layer[ti].P * f1_layer[ti].P;
599 if (ttemp != f1_layer[ti].P)
604 /* Compute F1 - Q values */
606 tnorm = sqrt((double) tnorm);
607 for (tj=0;tj<numf1s;tj++)
608 f1_layer[tj].Q = f1_layer[tj].P;
610 /* Compute F2 - y values */
611 for (tj=0;tj<numf2s;tj++)
615 for (ti=0;ti<numf1s;ti++)
616 Y[tj].y += f1_layer[ti].P * bus[ti][tj];
621 for (ti=0;ti<numf2s;ti++)
623 if (Y[ti].y > Y[winner].y)
630 if (DB1) print_f12();
631 if (DB1) printf("\n num iterations for p to stabilize = %i \n",j);
633 match_confidence=simtest2();
634 if ((match_confidence) > rho)
636 /* If the winner is not the default F2 neuron (the highest one)
639 if (winner!=numf2s-1)
642 fprintf(stdout,"F2 neuron %d passes vigilance with a value of %0.4f\n",winner,match_confidence);
644 if (match_confidence > highest_confidence[winner])
646 highest_confidence[winner] = match_confidence;
647 set_high[winner] = TRUE;
656 if (DB1) printf("#%i No",winner);
659 for (mt=0;mt<numf2s;mt++)
672 * loadimage - load image to scan
673 * This was rewritten because Windows NT seems to have
674 * problems with sequential calls to getc, scanf, fread,
675 * and fread. The bug is flaky. It appears that I'd
676 * only get one big read and all of the rest of the reads
677 * would contain bogus data, yet no error condition is
678 * generated by the read. Solution: one big read of the
679 * whole image and then a copy to where I really want it,
682 void loadimage(char *input_file)
688 if ((fd=open(input_file,O_RDONLY))==-1)
690 fprintf(stderr,"Error opening %s\n",input_file);
694 printf("made it to loadimage\n");
697 /* Strip Format descriptor */
702 if (buffer[i] != ' ')
703 width = width * 10 + buffer[i] - '0';
708 if (buffer[i] != ' ')
709 height = height * 10 + buffer[i] - '0';
712 fprintf(stderr,"width %d, height %d\n",width,height);
715 superbuffer = (char *)malloc(width * height * sizeof(char ));
716 if (superbuffer == NULL)
718 fprintf(stderr,"Problems with malloc in loadimage()\n");
721 cimage = (unsigned char **) malloc(sizeof(unsigned char *) * height);
724 fprintf(stderr,"Problems with malloc in loadimage()\n");
728 for (i=0;i<height;i++)
730 cimage[i] = (unsigned char *) malloc(width* sizeof(unsigned char));
733 fprintf(stderr,"Problems with malloc in loadimage()\n");
738 read(fd,superbuffer,width*height);
739 for (i=0;i<height;i++)
741 for (j=0;j<width;j++)
743 cimage[i][j] = superbuffer[i*width + j];
749 printf(" upper left 10X10 corner of image\n");
753 printf("%4d",cimage[i][j]);
760 /* load_weights - load neural net weights
761 * This seems to function properly which is odd because
762 * loadimage does not. The only difference really is that
763 * loadimage is trying to load bytes of any value, whereas
764 * load_weights is looking at a file that only contains
765 * ascii characters and reading them as ints or doubles.
767 void load_weights(char *weightfile)
773 if ((inp=fopen(weightfile,"r"))==NULL)
775 fprintf(stderr,"Unable to open %s\n",weightfile);
779 printf("made it to load_weights\n");
780 fscanf (inp,"%d %d",&lwidth,&lheight);
781 numf1s = numinputs = lwidth * lheight;
782 numf2s = numpatterns+1;
787 for (i=0;i<numf1s;i++)
788 { fscanf(inp,"%le",&a);
789 bus[i][j] = tds[i][j] =a;
791 } /* end of load_weights */
793 /* alloc_td_bu - memory alloc of top down and bottom up
798 bus = (double **)malloc(numf1s*sizeof(double *));
799 tds = (double **)malloc(numf1s*sizeof(double *));
800 if ((bus==NULL)||(tds==NULL))
802 fprintf(stderr,"Malloc problem in load_weights\n");
805 for (i=0;i<numf1s;i++)
807 bus[i] = (double *)malloc(numf2s*sizeof(double));
808 tds[i] = (double *)malloc(numf2s*sizeof(double));
810 } /* end of alloc_td_bu */
812 /* init_td - initialize top down weights
813 * start signifies which F2 neuron to initialize for. Enables
814 * training on more than one image.
816 void init_td(int start)
819 for (i=0;i<numf1s;i++)
820 for (j=start;j<numf2s;j++)
822 } /* end of init_td */
824 /* init_bu - initialize bottom up weights
826 void init_bu(int start )
829 for (i=0;i<numf1s;i++)
830 for (j=start;j<numf2s;j++)
831 bus[i][j] = 1/(1.0 - d)/sqrt((double)numf1s);
832 } /* end of init_bu */
834 /* load_train - load a training file into
835 * location f1_layer[].I[spot]
837 void load_train(char *trainfile,int mode, int objects)
846 if (mode==MODE_TRAIN1)
855 if ((fd=open(trainfile,O_RDONLY))==-1)
857 fprintf(stderr,"Error opening %s\n",trainfile);
861 printf("made it to load_train. opening %s\n",trainfile);
867 /* Strip Format descriptor */
872 if (buffer[i] != ' ')
873 lwidth = lwidth * 10 + buffer[i] - '0';
877 if (buffer[i] != ' ')
878 lheight = lheight * 10 + buffer[i] - '0';
881 fprintf(stderr,"width %d, height %d\n",lwidth,lheight);
884 /* The first time through we set up the network
885 * based on what is read from the file.
886 * The second time through (if we have more than
887 * one training file, we make sure the parameters
888 * match what was read the first time, e.g. the
889 * f1 layer is the same size.
891 if (mode==MODE_TRAIN1)
893 numf1s = numinputs = lwidth * lheight;
895 init_globs(MODE_TRAIN1);
900 if ((lwidth * lheight)!= numf1s)
902 fprintf(stderr,"Dimensions of first image do not match");
903 fprintf(stderr," dimensions of second.\n");
908 superbuffer = (char *)malloc(lwidth * lheight * sizeof(char ));
909 if (superbuffer == NULL)
911 fprintf(stderr,"Problems with malloc in loadimage()\n");
915 read(fd,superbuffer,lwidth*lheight);
916 for (i=0;i<lheight*lwidth;i++)
919 f1_layer[i].I[spot] = (double) t;
924 } /* end of load_train */
926 /* This routine is used to simulate training of other objects.
927 * Training on multiple objects would consume the entire execution
928 * time of the benchmark. Instead we train on a few then we simulate
929 * others by copying the interconnections for the objects we are trained
930 * on and then adding noise to the connections. This simulates training on
931 * other objects. Need to blur the objects enough to overcome ART's
934 void sim_other_objects(int low, int high, int stop)
940 printf("sim other low %d high %d stop %d\n",low,high,stop);
941 printf("sim other numf2s %d numpat %d\n",numf2s,numpatterns);
947 for (i=low;i<high;i++) {
948 for (j=0;j<numf1s;j++) {
950 tds[j][i] = tds[j][0];
951 tds[j][i] = bus[j][0];
953 tds[j][i] = tds[j][1];
954 tds[j][i] = bus[j][1];
958 for (i=low;i<high;i++) {
959 for (j=0;j<numf1s;j++) {
960 noise1 = rand()&0xffff;
961 noise2 = (double)noise1/(double)0xffff;
967 for (i=low;i<high;i++) {
968 for (j=0;j<numf1s;j++) {
969 fprintf(stderr,"%d %d %f\n",i,j,tds[j][i]);
973 } /* sim_other_objects */
975 void setup_base_pattern(int spot)
978 for (i=0;i<numf1s;i++)
980 for (j=spot;j<numf2s;j++)
982 tds[i][j] = bus[i][j] = 1.0 /sqrt((double)numf1s) /(1-d);
987 void scan_recognize(int startx, int starty, int endx, int endy, int stride)
993 if ((starty>(height-lheight+1))||(startx>(width-lwidth+1)))
995 fprintf(stderr,"Startx %d or Starty %d is out of range\n", startx, starty);
998 if ((endy>(height-lheight+1))||(endx>(width-lwidth+1)))
1000 fprintf(stderr,"endx %d or endy %d is out of range\n", endx, endy);
1006 fprintf(stdout,"made it to scan_recognize\n");
1007 fprintf(stdout,"w= %d h = %d lw = %d lh = %d\n",width,height,lwidth,lheight);
1010 for (j=starty;j<endy;j=j+stride )
1011 for (i=startx;i<endx;i=i+stride)
1014 for (m=j;m<(lheight+j);m++)
1015 for (n=i;n<(lwidth+i);n++)
1016 f1_layer[k++].I[0] = cimage[m][n];
1022 printf(" at X= %d Y = %d\n",i,j);
1024 if (set_high[0]==TRUE)
1028 set_high[0] = FALSE;
1030 if (set_high[1]==TRUE)
1034 set_high[1] = FALSE;
1039 printf("0.00#%dx%da%2.1fb%2.1f\n",i,j,a,b);
1055 char *scanfile=NULL;
1056 char *weightfile=NULL;
1057 char *trainfile1=NULL;
1058 char *trainfile2=NULL;
1066 if (strcmp(argv[1],"-v")==0)
1068 else if (strcmp(argv[1],"-h")==0)
1079 /* Read command line options */
1081 while (arg_index < argc-1)
1083 if (strcmp(argv[arg_index],"-scanfile")==0)
1085 scanfile= argv[arg_index+1];
1087 else if (strcmp(argv[arg_index],"-weightfile")==0)
1089 weightfile= argv[arg_index+1];
1091 else if (strcmp(argv[arg_index],"-trainfile1")==0)
1093 trainfile1= argv[arg_index+1];
1095 else if (strcmp(argv[arg_index],"-trainfile2")==0)
1097 trainfile2= argv[arg_index+1];
1099 else if (strcmp(argv[arg_index],"-startx")==0)
1101 startx = atoi(argv[arg_index+1]);
1103 else if (strcmp(argv[arg_index],"-starty")==0)
1105 starty = atoi(argv[arg_index+1]);
1107 else if (strcmp(argv[arg_index],"-endx")==0)
1109 endx = atoi(argv[arg_index+1]);
1111 else if (strcmp(argv[arg_index],"-endy")==0)
1113 endy = atoi(argv[arg_index+1]);
1115 else if (strcmp(argv[arg_index],"-stride")==0)
1117 stride = atoi(argv[arg_index+1]);
1119 else if (strcmp(argv[arg_index],"-objects")==0)
1121 objects = atoi(argv[arg_index+1]);
1125 fprintf(stderr,"ERROR: Unknown option -> %s\n",argv[arg_index]);
1128 arg_index+=2; /* this works as long as options are duals!!! */
1131 /* Some basic error checking. */
1135 fprintf(stderr,"ERROR: Must specify input files\n");
1138 if ((weightfile==NULL)&&(trainfile1==NULL))
1140 fprintf(stderr,"ERROR: Must specify weightfile or trainfile1\n");
1143 if ((weightfile!=NULL)&&(trainfile1!=NULL))
1145 fprintf(stderr,"ERROR: Cannot specify weightfile and trainfile1\n");
1150 fprintf(stdout,"scanfile = %s\n weightfile = %s\n startx = %d\n starty = %d\n stride = %d\n",scanfile,weightfile,startx,starty,stride);
1153 loadimage(scanfile);
1155 /* Differentiate between loading pretrained network (load_weights)
1156 * and training. Currently, loading a pretrained network
1157 * supports only 1 object. If we train, we can learn to
1158 * recognize two objects.
1160 if (weightfile!=NULL)
1165 objects = numpatterns;
1167 load_weights(weightfile);
1168 init_globs(MODE_RECOGNIZE);
1173 if (trainfile2!=NULL)
1176 if (objects<numpatterns)
1178 objects = numpatterns;
1180 load_train(trainfile1,MODE_TRAIN1,objects);
1188 fprintf(stdout,"k=%d\n",k);
1193 load_train(trainfile2,MODE_TRAIN2,objects);
1194 init_globs(MODE_TRAIN2);
1201 fprintf(stdout,"k=%d\n",k);
1206 init_globs(MODE_RECOGNIZE);
1209 sim_other_objects(numpatterns,objects,numf2s);
1210 setup_base_pattern(objects);
1215 if (objects<numpatterns)
1217 objects = numpatterns;
1219 load_train(trainfile1,MODE_TRAIN1,objects);
1227 fprintf(stdout,"k=%d\n",k);
1232 init_globs(MODE_RECOGNIZE);
1235 setup_base_pattern(1);
1238 /* Set endx and endy if user never specified */
1241 endy=height-lheight;
1247 highest_confidence[0] = 0.0;
1248 highest_confidence[1] = 0.0;
1253 set_high[0] = FALSE;
1254 set_high[1] = FALSE;
1256 scan_recognize(startx, starty, endx, endy, stride);
1258 fprintf(stdout,"Highest vigilance for 1 = %0.4f for object at X = %d, Y = %d\n", highest_confidence[0], highx[0], highy[0]);
1259 if (numpatterns==2) {
1260 fprintf(stdout,"Highest vigilance for 2 = %0.4f for object at X = %d, Y = %d\n", highest_confidence[1], highx[1], highy[1]);
1264 fprintf(stderr,"Usage: scanner [-startx <num>] [-starty <num>] [-endx <num>] [-endy <num>] [-stride <num>] -scanfile <filename> -trainfile1 <filename> [-trainfile2 <filename>]\n");
1267 fprintf(stderr,"Version 1.00 \n");