📄 discrime.c
字号:
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 + -