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

📄 discrime.c

📁 General Hidden Markov Model Library 一个通用的隐马尔科夫模型的C代码库
💻 C
📖 第 1 页 / 共 3 页
字号:
      sum = 0.0;      /* iterate over all classes and training sequences */      for (m = 0; m < noC; m++) {        sq = sqs[m];        if (m == class)          for (l = 0; l < sq->seq_number; l++)            sum -=              omega[class][l] * expect_a[class][l][+class][i * mo[class]->N +                                                           j_id];        else          for (l = 0; l < sq->seq_number; l++)            sum +=              lfactor * omegati[m][l][class] * expect_a[m][l][class][i *                                                                     mo                                                                     [class]->                                                                     N +                                                                     j_id];      }      /* check for valid new parameter */      a_old[j] = mo[class]->s[i].out_a[j];      if (fabs (lagrangian) == 0.0)        a_new[j] = a_old[j];      else        a_new[j] = sum / lagrangian;    }    /* update parameter */    for (j = 0; j < mo[class]->s[i].out_states; j++) {      mo[class]->s[i].out_a[j] = TRIM (a_old[j], a_new[j]);      /*printf("update parameter A[%d] in state %d of model %d with: %5.3g",         j, i, class, mo[class]->s[i].out_a[j]);         printf(" (%5.3g) old value, %5.3g estimted\n", a_old[j], a_new[j]); */      /* mirror out_a to corresponding in_a */      j_id = mo[class]->s[i].out_id[j];      for (g = 0; g < mo[class]->s[j_id].in_states; g++)        if (i == mo[class]->s[j_id].in_id[g]) {          mo[class]->s[j_id].in_a[g] = mo[class]->s[i].out_a[j];          break;        }    }  }STOP:     /* Label STOP from ARRAY_[CM]ALLOC */  m_free (a_old);  m_free (a_new);  return;#undef CUR_PROC}/*----------------------------------------------------------------------------*/static void discrime_update_b_closed (ghmm_dmodel ** mo, ghmm_dseq ** sqs, int noC,                               int class, double lfactor,                               double *****expect_b, long double **omega,                               long double ***omegati){#define CUR_PROC "discrime_update_b_closed"  int i, h, l, m;  int hist, size;  double *b_old = NULL;  double *b_new = NULL;  double sum, lagrangian;  ARRAY_CALLOC (b_old, mo[class]->M);  ARRAY_CALLOC (b_new, mo[class]->M);  /* itarate over all states of the k-th model */  for (i = 0; i < mo[class]->N; i++) {    if (mo[class]->s[i].fix)      continue;    size = ghmm_ipow (mo[class], mo[class]->M, mo[class]->order[i] + 1);    for (hist = 0; hist < size; hist += mo[class]->M) {      /* compute lagrangian multiplier */      lagrangian = 0.0;      for (h = hist; h < hist + mo[class]->M; h++) {        /* iterate over all classes and training sequences */        for (m = 0; m < noC; m++) {          if (m == class)            for (l = 0; l < sqs[m]->seq_number; l++)              lagrangian -= omega[class][l] * expect_b[class][l][class][i][h];          else            for (l = 0; l < sqs[m]->seq_number; l++)              lagrangian +=                lfactor * omegati[m][l][class] * expect_b[m][l][class][i][h];        }      }      for (h = hist; h < hist + mo[class]->M; h++) {        /* iterate over all classes and training sequences */        sum = 0.0;        for (m = 0; m < noC; m++) {          if (m == class)            for (l = 0; l < sqs[m]->seq_number; l++)              sum -= omega[class][l] * expect_b[class][l][class][i][h];          else            for (l = 0; l < sqs[m]->seq_number; l++)              sum +=                lfactor * omegati[m][l][class] * expect_b[m][l][class][i][h];        }        /* check for valid new parameters */        b_old[h] = mo[class]->s[i].b[h];        if (fabs (lagrangian) == 0.0)          b_new[h] = b_old[h];        else          b_new[h] = sum / lagrangian;      }      /* update parameters */      for (h = hist; h < hist + mo[class]->M; h++) {        mo[class]->s[i].b[h] = TRIM (b_old[h], b_new[h]);        /*printf("update parameter B[%d] in state %d of model %d with: %5.3g",           h, i, class, mo[class]->s[i].b[h]);           printf(" (%5.3g) old value, estimate %5.3g\n", b_old[h], b_new[h]); */      }    }  }STOP:     /* Label STOP from ARRAY_[CM]ALLOC */  m_free (b_old);  m_free (b_new);  return;#undef CUR_PROC}/*----------------------------------------------------------------------------*/static void discrime_find_factor (ghmm_dmodel * mo, ghmm_dseq ** sqs, int noC, int k,                           double lfactor, double ****expect_pi,                           double ****expect_a, double *****expect_b,                           long double **omega, long double ***omegati){#define CUR_PROC "discrime_find_factor"  int h, i, j, l, m;  int size, hist, j_id;  double self, other;  ghmm_dseq *sq;  /* itarate over all states of the k-th model */  for (i = 0; i < mo->N; i++) {    /* PI */    /* iterate over all classes */    self = other = 0.0;    for (m = 0; m < noC; m++) {      sq = sqs[m];      /* if current class and class of training sequence match, add the first term */      if (m == k)        for (l = 0; l < sq->seq_number; l++)          self += omega[k][l] * expect_pi[k][l][k][i];      /* otherwise the second */      else        for (l = 0; l < sq->seq_number; l++)          other += lfactor * omegati[m][l][k] * expect_pi[m][l][k][i];    }    if (self < other)      lfactor *= self / other;    /*printf("PI[%d]: %g - %g = %g \t %g\n", k, self, other, self-other, lfactor);*/    /* A */    for (j = 0; j < mo->s[i].out_states; j++) {      j_id = mo->s[i].out_id[j];      /* iterate over all classes and training sequences */      self = other = 0.0;      for (m = 0; m < noC; m++) {        sq = sqs[m];        if (m == k)          for (l = 0; l < sq->seq_number; l++)            self += omega[k][l] * expect_a[k][l][k][i * mo->N + j_id];        else          for (l = 0; l < sq->seq_number; l++)            other +=              lfactor * omegati[m][l][k] * expect_a[m][l][k][i * mo->N +                                                             j_id];      }      if (self < other)        lfactor *= self / other;      /*printf(" A[%d]: %g - %g = %g \t %g\n", k, self, other, self-other, lfactor);*/    }    /* B */    if (mo->s[i].fix)      continue;    size = ghmm_ipow(mo, mo->M, mo->order[i] + 1);    for (hist = 0; hist < size; hist += mo->M) {      for (h = hist; h < hist + mo->M; h++) {        self = other = 0.0;        /* iterate over all classes and training sequences */        for (m = 0; m < noC; m++) {          if (m == k)            for (l = 0; l < sqs[m]->seq_number; l++)              self += omega[k][l] * expect_b[k][l][k][i][h];          else            for (l = 0; l < sqs[m]->seq_number; l++)              other += lfactor * omegati[m][l][k] * expect_b[m][l][k][i][h];        }        if (self < other)          lfactor *= self / other;        /*printf(" B[%d]: %g - %g = %g \t %g\n", k, self, other, self-other, lfactor);*/      }    }  }  return;#undef CUR_PROC}/*----------------------------------------------------------------------------*/static int discrime_onestep (ghmm_dmodel ** mo, ghmm_dseq ** sqs, int noC, int grad,                      int class){#define CUR_PROC "discrime_onestep"  int j, l, retval = -1;  /* expected use of parameter (for partial derivatives) */  double *****expect_b, ****expect_a, ****expect_pi;  /* matrix of log probabilities */  double ***log_p;  /* matrix of outer derivatives */  long double **omega, ***omegati;  long double psum = 0, nsum = 0;  double lfactor;  if (-1 == discrime_galloc (mo, sqs, noC, &expect_b, &expect_a,                             &expect_pi, &omega, &omegati, &log_p)) {    printf ("Allocation Error.\n");    return -1;  }  if (-1 ==      discrime_precompute (mo, sqs, noC, expect_b, expect_a, expect_pi,                           log_p)) {    printf ("precompute Error.\n");    goto FREE;  }  if (-1 == discrime_calculate_omega (mo, sqs, noC, omega, omegati, log_p)) {    printf ("omega Error.\n");    goto FREE;  }  if (grad) {    /* updateing parameters */    discrime_update_pi_gradient (mo, sqs, noC, class, expect_pi, omega,                                 omegati);    discrime_update_a_gradient (mo, sqs, noC, class, expect_a, omega,                                omegati);    discrime_update_b_gradient (mo, sqs, noC, class, expect_b, omega,                                omegati);  }  else {    /* calculate a pleaseant lfactor */    for (j = 0; j < noC; j++) {      for (l = 0; l < sqs[j]->seq_number; l++) {        if (j == class)          psum += omega[class][l];        else          nsum += omegati[j][l][class];      }    }    if (fabs (nsum) > 1e-200 && psum < nsum)      lfactor = (psum / nsum);    else      lfactor = 1.0;    /* determing maximum lfactor */    discrime_find_factor (mo[class], sqs, noC, class, lfactor, expect_pi,                          expect_a, expect_b, omega, omegati);    lfactor *= .99;    printf ("Calculated L: %g\n", lfactor);    /* updating parameters */    discrime_update_pi_closed (mo, sqs, noC, class, lfactor, expect_pi, omega,                               omegati);    discrime_update_a_closed (mo, sqs, noC, class, lfactor, expect_a, omega,                              omegati);    discrime_update_b_closed (mo, sqs, noC, class, lfactor, expect_b, omega,                              omegati);  }  retval = 0;FREE:  discrime_gfree (mo, sqs, noC, expect_b, expect_a, expect_pi, omega,                  omegati, log_p);  return retval;#undef CUR_PROC}/*----------------------------------------------------------------------------*/int ghmm_dmodel_label_discriminative(ghmm_dmodel** mo, ghmm_dseq** sqs, int noC, int max_steps, 		    int gradient){#define CUR_PROC "ghmm_dmodel_label_discriminative"  double last_perf, cur_perf;  int retval=-1, last_cer, cur_cer;  double lambda=0.0;  double noiselevel = 0.0667;  int fp, fn, totalseqs = 0, totalsyms = 0;  int *falseP=NULL, *falseN=NULL;  double * prior_backup=NULL;  int i, k, step;  ghmm_dmodel * last;  ARRAY_CALLOC (falseP, noC);  ARRAY_CALLOC (falseN, noC);  ARRAY_CALLOC (prior_backup, noC);  for (i = 0; i < noC; i++) {    totalseqs += sqs[i]->seq_number;    for (k = 0; k < sqs[i]->seq_number; k++)      totalsyms += sqs[i]->seq_len[k];  }    /* setting priors from number of training sequences and     remember the old values */  for (i=0; i<noC; i++) {    prior_backup[i] = mo[i]->prior;    mo[i]->prior = (double)sqs[i]->seq_number / totalseqs;    printf("original prior: %g \t new prior %g\n", prior_backup[i], mo[i]->prior);  }  last_perf = ghmm_dmodel_label_discrim_perf (mo, sqs, noC);  cur_perf = last_perf;  discrime_print_statistics (mo, sqs, noC, falseP, falseN);  fp = fn = 0;  for (i = 0; i < noC; i++) {    printf ("Model %d likelihood: %g, \t false positives: %d\n", i,            ghmm_dmodel_likelihood (mo[i], sqs[i]), falseP[i]);    fn += falseN[i];    fp += falseP[i];  }  printf    ("\n%d false positives and %d false negatives after ML-initialisation; Performance: %g.\n",     fp, fn, last_perf);  last_cer = cur_cer = fp;  for (k = 0; k < noC; k++) {    last = NULL;    step = 0;    if (gradient)      lambda = .3;    do {      if (last)        ghmm_dmodel_free (&last);      /* save a copy of the currently trained model */      last = ghmm_dmodel_copy (mo[k]);      last_cer = cur_cer;      last_perf = cur_perf;      noiselevel /= 1.8;      discrime_lambda = lambda / totalsyms;      printf        ("==============================================================\n");      printf        ("Optimising class %d, current step %d, lambda: %g  noise: %g, gradient: %d\n",         k, step, discrime_lambda, noiselevel, gradient);/*       if (gradient)   *//* 	ghmm_dmodel_add_noise(mo[k], noiselevel, 0); */      discrime_onestep (mo, sqs, noC, gradient, k);      cur_perf = ghmm_dmodel_label_discrim_perf (mo, sqs, noC);      discrime_print_statistics (mo, sqs, noC, falseP, falseN);      fp = fn = 0;      for (i = 0; i < noC; i++) {        printf ("Model %d likelihood: %g, \t false positives: %d\n", i,                ghmm_dmodel_likelihood (mo[i], sqs[i]), falseP[i]);        fn += falseN[i];        fp += falseP[i];      }      cur_cer = fp;      printf ("MAP=%12g -> training -> MAP=%12g", last_perf, cur_perf);      printf ("  %d false positives, %d false negatives\n", fp, fn);      printf        ("==============================================================\n");    } while ((last_perf < cur_perf || cur_cer < last_cer) && (step++ < max_steps));    mo[k] = ghmm_dmodel_copy (last);    ghmm_dmodel_free (&last);    cur_perf = last_perf;    cur_cer = last_cer;  }  /* resetting priors to old values */  for (i = 0; i < noC; i++)    mo[i]->prior = prior_backup[i];  retval = 0;STOP:     /* Label STOP from ARRAY_[CM]ALLOC */  m_free (prior_backup);  m_free (falseP);  m_free (falseN);  return retval;#undef CUR_PROC}

⌨️ 快捷键说明

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