⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lvq_rout.cpp

📁 face recognition test source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  		lensam = length/sammon->times;
  		}
  	else
  		lensam = length + 1;
  
  for (le = 0; le < length; le++, datatmp = next_entry(&p))
    {
      if (datatmp == NULL)
	{
	  datatmp = rewind_entries(data, &p);
	  if (datatmp == NULL)
	    {
	      Msg(0, "lvq1_training: can't rewind data (%ld/%ld iterations)", 
		      le, length);
	      return NULL;
	    }
	}

      find_winner(codes, datatmp, &win, 1);
      shortest = win.diff;
      best = win.winner;
      label = get_entry_label(best);
      
      talpha = get_alpha(le, length, alpha);
      
      /* Was the classification correct? If classification was
         correct; move towards, else move away */

      if (label == get_entry_label(datatmp))
	adapt_vector(best, datatmp, dim, talpha);
      else 
	adapt_vector(best, datatmp, dim, -talpha);


    /* save snapshot when needed */
    if ((snap) && ((le % snap->interval) == 0) && (le > 0))
      {
        ifverbose(3)
	  Msg(0, "Saving snapshot, %ld iterations", le);
        if (save_snapshot(teach, le))
          {
            Msg(0, "snapshot failed");
          }
      }

      
      ifverbose(1) 
	mprint(length - le);
		
		if (sammon != NULL && sammon->length != 0 && (le % lensam) == 0)
			{
			put_sammon(teach, "lvq1 training", le, sammon->times);
			}
    }
  ifverbose(1) 
    Msg(0, "");
  
  return(codes);
}

/* Train by olvq1, whereby optimized alpha values are used.  The
   nearest code vector is modified; If classification is correct, move
   it towards the input entry, if classification is incorrect, move it
   away from the input entry */

struct entries *olvq1_training(struct teach_params *teach, 
			       char *infile, char *outfile)
{
  long i, le, noc, length = teach->length;
  int label;
  int numofe;
  int potobe, dim;
  float shortest;
  float *talpha;
  struct data_entry *datatmp, *best;
  VECTOR_ADAPT *adapt = teach->vector_adapt;
  WINNER_FUNCTION *find_winner = teach->winner;
  /* ALPHA_FUNC *get_alpha = teach->alpha_func; */
  struct entries *data = teach->data;
  struct entries *codes = teach->codes;
  struct snapshot_info *snap = teach->snapshot;
  float alpha = teach->alpha;
  struct winner_info win;
  eptr p;
  long lensam;
  CSammon *sammon = teach->sammon;

  dim = codes->dimension;

  rewind_entries(codes, &p); /* make sure codes are loaded */

  noc = codes->num_entries;

  /* Get the initial alpha values:                                      */
  /* There are several possibilities: the user may define them; */
  /* if not, then they may be read from file;                   */
  /* if no file exists, then default values are used.           */ 
  talpha = (float *) oalloc(sizeof(float) * noc);
  if (alpha == 0.0) {
    if (!alpha_read(talpha, noc, infile)) {
      alpha = 0.3;
      for (i = 0; i < noc; i++) {
	talpha[i] = alpha;
      }
    }
  }
  else {
    for (i = 0; i < noc; i++) {
      talpha[i] = alpha;
    }
  }

  if ((datatmp = rewind_entries(data, &p)) == NULL)
    {
      Msg(0, "olvq1_training: can't get data");
      return NULL;
    }

  numofe = data->flags.totlen_known ? data->num_entries : 0;

	if (sammon != NULL)
  		{
  		lensam = length/sammon->times;
  		}
  	else
  		lensam = length + 1;
  
  for (le = 0; le < length; le++, datatmp = next_entry(&p))
    {
      if (datatmp == NULL)
	{
	  datatmp = rewind_entries(data, &p);
	  if (datatmp == NULL)
	    {
	      Msg(0, "olvq1_training: can't rewind data (%ld/%ld iterations)", 
		      le, length);
	      return NULL;
	    }
	}
      
      find_winner(codes, datatmp, &win, 1);
      shortest = win.diff;
      best = win.winner;
      label = get_entry_label(best);
      potobe = win.index;
      
      /* Individual alphas for every codebook vector; */
      /* Was the classification correct?              */
      if (label == get_entry_label(datatmp)) {
	/* If classification was correct, move towards */

	adapt(best, datatmp, dim, talpha[potobe]);

	talpha[potobe] = talpha[potobe] / (1 + talpha[potobe]);
      }
      else {
	/* If classification was incorrect, move away */

	adapt(best, datatmp, dim, -talpha[potobe]);

	talpha[potobe] = talpha[potobe] / (1 - talpha[potobe]);
	if (talpha[potobe] > alpha)
	  talpha[potobe] = alpha;
      }

		if (sammon != NULL && sammon->length != 0 && (le % lensam) == 0)
			{
			put_sammon(teach, "olvq1 training", le, sammon->times);
			}
    /* save snapshot when needed */
    if ((snap) && ((le % snap->interval) == 0) && (le > 0))
      {
        ifverbose(3)
	  Msg(0, "Saving snapshot, %ld iterations", le);
        if (save_snapshot(teach, le))
          {
            Msg(0, "snapshot failed");
          }
      }

      
      ifverbose(1)
	mprint(length - le);
		                                     
    }
  ifverbose(1)
    Msg(0, "");
  
  /* Store the alphas */
  alpha_write(talpha, noc, outfile);
  
  return(codes);
}

/* Train by lvq2.  Two nearest codebook vectors are modified under
   specified conditions */

struct entries *lvq2_training(struct teach_params *teach, float winlen)
{

  long le, total_length, numofe;
  int label, nlabel, datalabel, dim;
  float shortest, nshortest;
  float talpha;
  struct data_entry *datatmp;
  struct data_entry *best, *nbest, *ntmp;
  VECTOR_ADAPT *adapt = teach->vector_adapt;
/*MODIFICATION*/  
  WINNER_FUNCTION *find_winners = find_winner_knn/*teach->winner*/;
  ALPHA_FUNC *get_alpha = teach->alpha_func;
  struct entries *data = teach->data;
  struct entries *codes = teach->codes;
  long length = teach->length;
  float alpha = teach->alpha;
  struct snapshot_info *snap = teach->snapshot;
  struct winner_info win[2];
  eptr p;
  long lensam;
  CSammon *sammon = teach->sammon;

  dim = codes->dimension;

  total_length = length;

  if ((datatmp = rewind_entries(data, &p)) == NULL)
    {
      Msg(0, "lvq2_training: can't get data");
      return NULL;
    }
  numofe = data->flags.totlen_known ? data->num_entries : 0;

	if (sammon != NULL)
  		{
  		lensam = length/sammon->times;
  		}
  	else
  		lensam = length + 1;
  
  for (le = 0; le < length; le++, datatmp = next_entry(&p))
    {
      if (datatmp == NULL)
	{
	  datatmp = rewind_entries(data, &p);
	  if (datatmp == NULL)
	    {
	      Msg(0, "lvq2_training: can't rewind data (%ld/%ld iterations)", 
		      le, length);
	      return NULL;
	    }
	}
      
      /* True alpha is decreasing linearly during the training */
      talpha = get_alpha(le, length, alpha);
      
      /* find two best mathing units */
      find_winners(codes, datatmp, win, 2);
      
      shortest = win[0].diff;
      best = win[0].winner;
      label = get_entry_label(best);
      
      nshortest = win[1].diff;
      nbest = win[1].winner;
      nlabel = get_entry_label(nbest);
      
      datalabel = get_entry_label(datatmp);
      /* Corrections are made only if the two nearest codebook vectors
	 belong to different classes, one of them correct, and if the
	 input entry is located inside a window between the nearest codebook
	 vectors           */
      if (label != nlabel) {
	if ((label == datalabel) || (nlabel == datalabel)) {
	  
	  /* If the ration of distances to the two nearest codebook vectors
	     satisfies a condition */
	  if ((shortest/nshortest) > ((1-winlen)/(1+winlen))) {
	    /* If the second best is correct swap the entries */
	    if (nlabel == datalabel) {
	      ntmp = best;
	      best = nbest;
	      nbest = ntmp;
	    }
	    
	    /* Move the entries */
	    adapt(best, datatmp, dim, talpha);
	    adapt(nbest, datatmp, dim, -talpha);
	  }
	}
      }
      
		if (sammon != NULL && sammon->length != 0 && (le % lensam) == 0)
			{
			put_sammon(teach, "lvq2 training", le, sammon->times);
			}

      /* save snapshot when needed */
      if ((snap) && ((le % snap->interval) == 0) && (le > 0))
	{
	  ifverbose(3)
	    Msg(0, "Saving snapshot, %ld iterations", le);
	  if (save_snapshot(teach, le))
	    {
	      Msg(0, "snapshot failed");
	    }
		
	}
      
      ifverbose(1)
	mprint(length - le);
    }
  ifverbose(1)
    Msg(0, "");

  return(codes);
}

/* Train by lvq3. Two nearest codebook vectors are modified under
   specified conditions */

struct entries *lvq3_training(struct teach_params *teach,
			      float epsilon, float winlen)
{
  long le, numofe, total_length;
  int label, nlabel, datalabel, dim;
  float shortest, nshortest;
  float talpha;
  struct data_entry *datatmp, *best, *nbest, *ntmp;
  VECTOR_ADAPT *adapt = teach->vector_adapt;
/*MODIFICATION*/  
  WINNER_FUNCTION *find_winners = find_winner_knn/*teach->winner*/;
  ALPHA_FUNC *get_alpha = teach->alpha_func;
  struct entries *data = teach->data;
  struct entries *codes = teach->codes;
  struct snapshot_info *snap = teach->snapshot;
  long length = teach->length;
  float alpha = teach->alpha;
  struct winner_info win[2];
  eptr p;
  long lensam;
  CSammon *sammon = teach->sammon;

  dim = codes->dimension;
  
  total_length = length;

  if ((datatmp = rewind_entries(data, &p)) == NULL)
    {
      Msg(0, "lvq3_training: can't get data");
      return NULL;
    }
  numofe = data->flags.totlen_known ? data->num_entries : 0;
  
	if (sammon != NULL)
  		{
  		lensam = length/sammon->times;
  		}
  	else
  		lensam = length + 1;
  
  for (le = 0; le < length; le++, datatmp = next_entry(&p))
    {
      if (datatmp == NULL)
	{
	  datatmp = rewind_entries(data, &p);
	  if (datatmp == NULL)
	    {
	      Msg(0, "lvq3_training: can't rewind data (%ld/%ld iterations)", 
		      le, length);
	      return NULL;
	    }
	}
      
      /* True alpha is decreasing linearly during the training */
      talpha = get_alpha(le, length, alpha);
      
      /* find two best mathing units */
      find_winners(codes, datatmp, win, 2);
      
      shortest = win[0].diff;
      best = win[0].winner;
      label = get_entry_label(best);
      
      nshortest = win[1].diff;
      nbest = win[1].winner;
      nlabel = get_entry_label(nbest);
      
      datalabel = get_entry_label(datatmp);
      /* Corrections are made if the two nearest codebook vectors
	 belong to different classes, one of them correct, and if the
	 input entry is located inside a window between the nearest codebook
	 vectors OR the two nearest codebook vectors both belong to the
	 correct Class */
      if (label != nlabel) {
	if ((label == datalabel) || (nlabel == datalabel)) {
	  
	  /* If the ration of distances to the two nearest codebook vectors
	     satisfies a condition */
	  if ((shortest/nshortest) > ((1-winlen)/(1+winlen))) {
	    /* If the second best is correct swap the entries */
	    if (nlabel == datalabel) {
	      ntmp = best;
	      best = nbest;
	      nbest = ntmp;
	    }
	    
	    /* Move the entries */
	    adapt(best, datatmp, dim, talpha);
	    adapt(nbest, datatmp, dim, -talpha);
	  }
	}
      }
      else {
	if (label == datalabel) {
	  /* Move the entries, both toward */
	  adapt(best, datatmp, dim, talpha * epsilon);
	  adapt(nbest, datatmp, dim, talpha * epsilon);
	}
      }

		if (sammon != NULL && sammon->length != 0 && (le % lensam) == 0)
			{
			put_sammon(teach, "lvq3 training", le, sammon->times);
			}
      /* save snapshot when needed */
      if ((snap) && ((le % snap->interval) == 0) && (le > 0))
	{
	  ifverbose(3)
	    Msg(0, "Saving snapshot, %ld iterations", le);
	  if (save_snapshot(teach, le))
	    {
	      Msg(0, "snapshot failed");
	    }
		
	}
      
      ifverbose(1)
	mprint(length - le);
    }
  ifverbose(1)
    Msg(0, "");

  return(codes);
}

float devdist( float *v1, float *v2, int dim)
{
  float diff, d;
  d = 0.0;
  while (dim-- > 0) {
    diff = *v1++ - *v2++;
    d += diff*diff;
  }
  return(d);
}

struct mindists *deviations(struct entries *codes, struct mindists *md)
{
  int i, j;
  int nol, dim, *noe, label;
  int *count;
  float *devs;
  float *avers;
  struct data_entry *entr;
  eptr p;

  dim = codes->dimension;
  nol = md->num_classes;
  noe = md->noe;

  count = (int *) oalloc(sizeof(int) * nol);

  devs = (float*)calloc(nol, sizeof(float));
  if ((md->devs = devs) == NULL)
    {
      return NULL;
    }

  avers = (float *) oalloc(sizeof(float) * nol * dim);
  for (i = 0; i < nol; i++) {
    devs[i] = 0.0;
    for (j = 0; j < dim; j++) {
      avers[i*dim+j] = 0.0;
    }
    count[i] = 0;
  }

  /* Compute averages */

  entr = rewind_entries(codes, &p);
  while (entr != NULL) {
    label = get_entry_label(entr);

    for (i = 0; i < nol; i++)
      if (label == md->Class[i])
	break;
    
    for (j = 0; j < dim; j++)
      if (!((entr->mask != NULL) && (entr->mask[j] != 0)))
	{
	  avers[i*dim+j] += entr->points[j];
	}
    /* count[i]++; */

    entr = next_entry(&p);
  }
  
  for (i = 0; i < nol; i++) {
    for (j = 0; j < dim; j++) {
      avers[i*dim+j] /= noe[i];
    }
  }

  /* Compute deviations */
  entr = rewind_entries(codes, &p);
  while (entr != NULL) {
    label = get_entry_label(entr);

    for (i = 0; i < nol; i++)
      if (label == md->Class[i])
	break;

    devs[i] += devdist(entr->points,
          &(avers[i*dim]), dim);
    entr = next_entry(&p);
  }
  for (i = 0; i < nol; i++) {
    devs[i] = sqrt(devs[i]/noe[i]);
  }

  return(md);
}


⌨️ 快捷键说明

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