lvq_run.c

来自「face recognition test source code」· C语言 代码 · 共 1,242 行 · 第 1/3 页

C
1,242
字号
  c->rt_alpha = 0.0;
  c->rt_win = 0.3;
  c->rt_epsilon = 0.1;
  c->rlen = c->totrlen = c->rt_rlen = 0;
  c->accuracy = 0.0;
  c->hist_i = c->train_hist_bgn = c->retrain_hist_bgn = 0;
}



void read_classifier_file(CLASSIFIER *c)
{
  char l[CMD_LEN]; int ok;
  do {
    fprintf(stdout,"\n*Enter the name of the file to which the codebook vectors");
    fprintf(stdout,"\n*will be stored (without .cod extension): ");
    getsb(l); 
    if (*l == '\0') ok=0; else {
      strcpy( c->cout, l);
      strcat(l, train_ext);
      ok = check_filename( l, W_OK);
    }
  } while (ok==0);
  
  /* remove old files */
  if (ok==2) remove_classifier_files( c->cout );
}



void read_classifier_parameters(CLASSIFIER *c)
{
  char l[CMD_LEN];
  int ok;
  int i;
  
  fprintf(stdout,sep);
  fprintf(stdout,"Enter now the parameters and associated filenames for this LVQ-classifier.");
  
  do {
    if (c->din[0]) fprintf(stdout,"\n*Enter training data file (%s): ", c->din);
    else fprintf(stdout,"\n*Enter training data file: ");
    getsb(l); 
    if (*l != 0) {
      /* if a new training file was given, all previous
	 training must be rerun */
      decrease_lvq_status(c,NOTHING);
      c->noc = 0; /* must be recomputed */
      sscanf(l, "%s", c->din);
    }
    ok = check_filename( c->din, R_OK);
  } while (!ok);
  
  if (c->noc == 0) {
    fprintf(stdout,"\n Reading input data..."); fflush(stdout);
    estimate_needed_codevectors(c->din, &c->noc, &c->notv);
  }
  
  fprintf(stdout,"*Enter the desired total number of codevectors which will be\n");
  fprintf(stdout,"*divided among classes (default: %d): ",c->noc);
  getsb(l); 
  if (*l != 0) {
    sscanf(l, "%d", &c->noc);
    decrease_lvq_status(c,NOTHING);
    c->rlen = 0; /* must be recomputed */
  }
  
  fprintf(stdout,"\nNext, you have to choose how to initialize the codevectors.\n");
  fprintf(stdout,"The options are: \n");
  fprintf(stdout,"	1: Equal allocation of codevectors to each class.\n");
  fprintf(stdout,"	2: Proportional to the amount of training data for each class.\n");
  fprintf(stdout,"We recommend that you use option 1.\n");
  fprintf(stdout,"*Enter your choice (default is %d): ",c->init_opt);
  getsb(l); 
  if (*l != 0) {
    sscanf(l, "%d", &i);
    if (i != c->init_opt) {
      c->init_opt = i;
      decrease_lvq_status(c,NOTHING);
    }
  }

  
  fprintf(stdout,"\nYou must now specify how many training iterations are used. We suggest ");
  fprintf(stdout,"\na number that is about 40 times the number of codebook vectors.");
  if (c->rlen == 0) {
    c->rlen = 40*c->noc;
    decrease_lvq_status(c,INIT);
  }
  fprintf(stdout,"\n*Enter the number of training iterations (%ld): ",c->rlen);
  getsb(l);
  if (*l != 0) {
    long nrlen;
    sscanf(l,"%ld", &nrlen);

    /* has the classifier once been trained (by olvq1)
       even retrained ? */
    if (c->lvq_status >= TRAIN) {

      /* Can we continue previously done training? */
      if (nrlen > c->totrlen) {

	fprintf(stdout,"You entered a number larger than used previously. In this case we can");
	fprintf(stdout,"\ncontinue previous training because olvq1 saves its final state to a file.");
	c->rlen = nrlen - c->totrlen;
	
	/* Restore the state after previous run(s) of 'olvq1'.
	   This must be done because LVQ{1,2,3} destroys the 
	   file "classifier_name.lra" */
	sprintf(l,"%s%s",c->cout,train_alpha_ext);
	if (faccess(l,F_OK)==0) {
	  sprintf(l,"%s %s%s %s%s",copy_cmd, c->cout,
		  train_alpha_ext,c->cout,alpha_ext);
	  system(l);
	}

	/* remove retraining history */
	decrease_lvq_status(c,TRAIN); 
	c->lvq_status = INIT;
      } else {
	/* Cannot continue previous olvq1-training (less
	   training cycles requested than done at previous run).
	   Start olvq1 from the state after initialization. */
	decrease_lvq_status(c,INIT);
	c->rlen = nrlen;
	c->totrlen = 0;
	
	/* must destroy the current state of olvq1 */
	sprintf(l,"%s%s",c->cout,alpha_ext);remove(l); 
	sprintf(l,"%s%s",c->cout,train_alpha_ext);remove(l); 
	sprintf(l,"%s%s",c->cout,train_ext);remove(l);
	
	/* restore the state after previous (possible) 
	   run(s) of 'balance' */
	sprintf(l,"%s%s",c->cout,init_alpha_ext);
	if (faccess(l,F_OK)==0) {
	  sprintf(l,"%s %s%s %s%s",copy_cmd, c->cout,
		  init_alpha_ext,c->cout,alpha_ext);
	  system(l);
	}
      }
    } else {
      /* The classifier hasn't yet been trained. */
      c->rlen = nrlen;
      c->totrlen = 0;
      decrease_lvq_status(c,INIT);
    }
  }
  
  
  do {
    fprintf(stdout,"\n*Enter the test data file");
    if (c->tdin[0]) fprintf(stdout," (%s): ",c->tdin); else fprintf(stdout,": ");
    getsb(l); 
    if (*l != 0) {
      sscanf(l, "%s", c->tdin);
      c->accuracy = 0.0;
    }
    ok = check_filename( c->tdin, R_OK);
  } while (!ok);
}



void read_retrain_parameters(CLASSIFIER *c, int add)
{
  char l[CMD_LEN];
  int i;
  
  fprintf(stdout,"\nChoose the type of LVQ to be used for fine-tuning.\n");
  fprintf(stdout,"	1: LVQ1\n");
  fprintf(stdout,"	2: LVQ2.1\n");
  fprintf(stdout,"	3: LVQ3\n");
  fprintf(stdout,"*Enter your choice (%d): ",c->rt_lvq_type);
  getsb(l); 
  if (*l != 0) {
    sscanf(l, "%d", &i);
    if (i!=1 && i!=2 && i!=3) i=1;
    if (i != c->rt_lvq_type) {
      c->rt_alpha = 0.0; /* if changed LVQ-type set new default */
      c->rt_lvq_type = i;
      if (!add) decrease_lvq_status(c,TRAIN);
    }
  }
  
  /* set default alphas */
  if (c->rt_alpha == 0.0)
    if (c->rt_lvq_type == 1) c->rt_alpha = DEFAULT_LVQ1_ALPHA; else
      if (c->rt_lvq_type == 2) c->rt_alpha = DEFAULT_LVQ2_ALPHA; else
        if (c->rt_lvq_type == 3) c->rt_alpha = DEFAULT_LVQ3_ALPHA; else
	  c->rt_alpha = 0.02;
  
  fprintf(stdout,"\n*Enter the initial value for alpha (%g): ",c->rt_alpha);
  getsb(l);
  if (*l != 0) {
    sscanf(l,"%f", &c->rt_alpha);
    if (!add) decrease_lvq_status(c,TRAIN);
  }
  
  
  fprintf(stdout,"\nYou must now specify how many training iterations are used.");
  fprintf(stdout,"\nWe suggest a number that is at least five times the number of ");
  fprintf(stdout,"\ntraining vectors in your file %s.",c->din);
  if (c->rt_rlen == 0) {
    c->rt_rlen = 5*c->notv;
    if (!add) decrease_lvq_status(c,TRAIN);
  }
  fprintf(stdout,"\n*Enter the number of training iterations (%ld): ",c->rt_rlen);
  getsb(l);
  if (*l != 0) {
    sscanf(l,"%ld", &c->rt_rlen);
    if (!add) decrease_lvq_status(c,TRAIN);
  }
  
  
  if (c->rt_lvq_type == 2 || c->rt_lvq_type == 3) {
    fprintf(stdout,"\nSpecify the width of the window in which the adaptation takes place.");
    fprintf(stdout,"\n*Enter the width (%g): ",c->rt_win);
    getsb(l);
    if (*l != 0) {
      sscanf(l,"%f", &c->rt_win);
      if (!add) decrease_lvq_status(c,TRAIN);
    }
  }

  if (c->rt_lvq_type == 3) {
    fprintf(stdout,"\n*Enter the stabilizing factor (epsilon) (%g): ",c->rt_epsilon);
    getsb(l);
    if (*l != 0) {
      sscanf(l,"%f", &c->rt_epsilon);
      if (!add) decrease_lvq_status(c,TRAIN);
    }
  }
}




/*---------------Read and write classifiers to/from file---------------------*/

void input_classifier(FILE *f, CLASSIFIER *c)
{
  int i;
  char l[CMD_LEN];
  
  fgets(l,CMD_LEN,f);sscanf(l,"%s", c->din);
  fgets(l,CMD_LEN,f);sscanf(l,"%d", &c->notv);
  fgets(l,CMD_LEN,f);sscanf(l,"%s", c->tdin);
  fgets(l,CMD_LEN,f);sscanf(l,"%s", c->cout);
  fgets(l,CMD_LEN,f);sscanf(l,"%d", &c->noc);
  fgets(l,CMD_LEN,f);sscanf(l,"%d", &c->init_opt);
  fgets(l,CMD_LEN,f);sscanf(l,"%ld",&c->totrlen);
  fgets(l,CMD_LEN,f);sscanf(l,"%ld",&c->rlen);
  fgets(l,CMD_LEN,f);sscanf(l,"%d", &c->lvq_status);
  
  fgets(l,CMD_LEN,f);sscanf(l,"%d", &c->rt_lvq_type);
  fgets(l,CMD_LEN,f);sscanf(l,"%ld", &c->rt_rlen);
  fgets(l,CMD_LEN,f);sscanf(l,"%f", &c->rt_alpha);
  fgets(l,CMD_LEN,f);sscanf(l,"%f", &c->rt_win);
  fgets(l,CMD_LEN,f);sscanf(l,"%f", &c->rt_epsilon);
  
  fgets(l,CMD_LEN,f);sscanf(l,"%f", &c->accuracy);
  
  fgets(l,CMD_LEN,f); 
  fgets(l,CMD_LEN,f); sscanf(l,"%d %d %d", 
			     &c->hist_i, &c->train_hist_bgn, &c->retrain_hist_bgn);
  for (i=0; i < c->hist_i; i++) {
    fgets(l,CMD_LEN,f); 
    l[strlen(l)-1]='\0';
    c->history[i] = dup_history(l);
  }
}



void print_classifier(FILE *f, CLASSIFIER *c)
{
  int i;
  if (f==stdout) {
    fprintf(f,sep);
    fprintf(f,"\n");
  }
  fprintf(f,"%s\t Training data file\n", c->din);
  fprintf(f,"%d\t Number of training vectors\n", c->notv);
  fprintf(f,"%s\t Testing data file\n", c->tdin);
  fprintf(f,"%s\t Codebook vector files\n", c->cout);
  fprintf(f,"%d\t Number of codebook vectors\n", c->noc);
  fprintf(f,"%d\t Initializing option\n", c->init_opt);
  fprintf(f,"%ld\t Training cycles used\n", c->totrlen);
  if (f!=stdout) {
    fprintf(f,"%ld\t Training cycles used in latest teaching\n", c->rlen);
    fprintf(f,"%d\t Current status\n", c->lvq_status);
  }
  
  if ( f!=stdout || c->lvq_status == RETRAIN ) {
    fprintf(f,"%d\t retrain LVQ-type\n", c->rt_lvq_type);
    fprintf(f,"%ld\t Training cycles used\n", c->rt_rlen);
    fprintf(f,"%g\t Initial alpha\n", c->rt_alpha);
    if (f!=stdout || c->rt_lvq_type == 2 || c->rt_lvq_type == 3)
      fprintf(f,"%g\t Window width\n", c->rt_win);
    if (f!=stdout || c->rt_lvq_type == 3)
      fprintf(f,"%g\t Epsilon\n", c->rt_epsilon);
  }
  fprintf(f,"%g\t Accuracy\n", c->accuracy);
  
  fprintf(f,"Recent history:\n");
  if (f!=stdout) fprintf(f,"%d %d %d\n", 
			 c->hist_i, c->train_hist_bgn, c->retrain_hist_bgn);
  for (i=0; i < c->hist_i; i++) fprintf(f,"%s\n", c->history[i]);
}





int retrieve_classifiers(int argc, char **argv, CLASSIFIER c[])
{
  int i,ci;
  char l[CMD_LEN];
  FILE *f;
  
  for (ci=0,i=1; i<argc; i++) {
    if (argv[i][0] != '-') {
      sprintf(l,"%s%s", argv[i],log_ext );
      f = fopen(l,"r");
      if (f==NULL) {
        fprintf(stdout,"\nERROR: cannot find classifier %s!\n",l);
      } else {
        fprintf(stdout,"\nReading classifier %s.",l);
        input_classifier(f,&c[ci++]);
        fclose(f);
      }
    }
    else
      i++;
  }
  return(ci);
}


/*-----------------------Run the LVQ_PAK programs----------------------------*/

void init_classifier (CLASSIFIER *c)
{
  char l[CMD_LEN];
  
  if (c->lvq_status < INIT) {
    
    fprintf(stdout,"\nRunning initialization: %d\n", (int) c->init_opt);
    
    switch(c->init_opt) {
    case EVEN:
      sprintf(l,"%seveninit -noc %d -din %s -cout %s%s -knn 5",
	      prog_dir, c->noc, c->din, c->cout, init_ext);
      systemh(l,c);
      break;
    case PROP:
      sprintf(l,"%spropinit -noc %d -din %s -cout %s%s -knn 5",
	      prog_dir, c->noc, c->din, c->cout, init_ext);
      systemh(l,c);
      break;
    default:
      fprintf(stdout,"\nIllegal initializing option %d\n",c->init_opt);
      exit(-1);
    }
    
    /* check that the initialized code file was created */
    sprintf( l, "%s%s", c->cout, init_ext);
    if ( faccess(l, R_OK) != 0) {
      fprintf(stdout,"\nUnsuccesful initialization!\n");
      exit(-1);
    }
    
    fprintf(stdout,"\nNow you have the possibility to modify the number of codevectors");
    fprintf(stdout,"\nso that the minimum distances between the codevectors within each");
    fprintf(stdout,"\nclass will be balanced. The current situation is as follows:\n");
    
    /* display distances between codevectors */
    sprintf(l,"%smindist -cin %s%s", prog_dir, c->cout, init_ext);
    systemd(l);
    
    do {
      fprintf(stdout,"\nDo you want to run an iteration of balancing? y/n (default=n) ");
      getsb(l); 
      if (*l != 'y') break;
      
      sprintf(l,"%sbalance -din %s -cin %s%s -cout %s%s -knn 5",
	      prog_dir, c->din, c->cout, init_ext, c->cout, init_ext);
      systemh(l,c);
    } while (1);
    
    c->lvq_status = INIT;
    fix_init_history(c);
    
    /* If balance was used, it created a file containing learning
       rates for each of the codevectors. It is stored for further
       use (rerun training but keep initialization). */
    sprintf( l, "%s%s", c->cout, alpha_ext);
    if ( faccess(l, F_OK) == 0) {
      sprintf(l,"%s %s%s %s%s",copy_cmd, c->cout, alpha_ext,
	      c->cout, init_alpha_ext);
      system(l);
    }
  }
}




void train_classifier (CLASSIFIER *c)
{
  char l[CMD_LEN], *input_ext;
  
  if (c->lvq_status < TRAIN) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?