cont_mgau.c
来自「CMU大名鼎鼎的SPHINX-3大词汇量连续语音识别系统」· C语言 代码 · 共 844 行 · 第 1/2 页
C
844 行
/* Normalize and floor */ if (vector_is_zero (pdf, n_comp)) { n_err++; for (j = 0; j < n_comp; j++){ if(g->comp_type==MIX_INT_FLOAT_COMP) mgau_mixw(g,i,j) = S3_LOGPROB_ZERO; else if (g->comp_type==FULL_FLOAT_COMP) mgau_mixw_f(g,i,j) = S3_LOGPROB_ZERO_F; else E_FATAL("Unsupported computation type %d \n",g->comp_type); } } else { vector_nz_floor (pdf, n_comp, mixwfloor); vector_sum_norm (pdf, n_comp); for (j = 0; j < n_comp; j++){ if(g->comp_type==MIX_INT_FLOAT_COMP) mgau_mixw(g,i,j) = (pdf[j] != 0.0) ? logs3(pdf[j]) : S3_LOGPROB_ZERO; else if(g->comp_type==FULL_FLOAT_COMP) mgau_mixw_f(g,i,j) = (pdf[j] != 0.0) ? log(pdf[j]) : S3_LOGPROB_ZERO_F; else E_FATAL("Unsupported computation type %d \n",g->comp_type); } } } if (n_err > 0) E_ERROR("Weight normalization failed for %d senones\n", n_err); ckd_free (pdf); if (chksum_present) bio_verify_chksum (fp, byteswap, chksum); if (fread (&eofchk, 1, 1, fp) == 1) E_FATAL("More data than expected in %s\n", file_name); fclose(fp); if(g->verbose) E_INFO("Read %d x %d mixture weights\n", n_mgau, n_comp); return 0;}/** * Compact each mixture Gaussian in the given model by removing any uninitialized components. * A component is considered to be uninitialized if its variance is the 0 vector. Compact by * copying the data rather than moving pointers. Otherwise, malloc pointers could get * corrupted. */static void mgau_uninit_compact (mgau_model_t *g){ int32 m, c, c2, n, nm; if(g->verbose) E_INFO("Removing uninitialized Gaussian densities\n"); n = 0; nm = 0; for (m = 0; m < mgau_n_mgau(g); m++) { for (c = 0, c2 = 0; c < mgau_n_comp(g,m); c++) { if (! vector_is_zero (mgau_var(g,m,c), mgau_veclen(g))) { if (c2 != c) { memcpy (mgau_mean(g,m,c2), mgau_mean(g,m,c), mgau_veclen(g) * sizeof(float32)); memcpy (mgau_var(g,m,c2), mgau_var(g,m,c), mgau_veclen(g) * sizeof(float32)); if(g->comp_type==MIX_INT_FLOAT_COMP) mgau_mixw(g,m,c2) = mgau_mixw(g,m,c); else if(g->comp_type==FULL_FLOAT_COMP) mgau_mixw_f(g,m,c2) = mgau_mixw_f(g,m,c); else E_FATAL("Unsupported computation type %d \n",g->comp_type); } c2++; } else { n++; } } mgau_n_comp(g,m) = c2; if (c2 == 0) { fprintf (stderr, " %d", m); fflush (stderr); nm++; } } if (nm > 0) fprintf (stderr, "\n"); if ((nm > 0) || (n > 0)) E_WARN ("%d densities removed (%d mixtures removed entirely)\n", n, nm);}static void mgau_var_floor (mgau_model_t *g, float64 floor){ int32 m, c, i, n; if(g->verbose) E_INFO("Applying variance floor\n"); n = 0; for (m = 0; m < mgau_n_mgau(g); m++) { for (c = 0; c < mgau_n_comp(g,m); c++) { for (i = 0; i < mgau_veclen(g); i++) { if (g->mgau[m].var[c][i] < floor) { g->mgau[m].var[c][i] = (float32) floor; n++; } } } } if(g->verbose) E_INFO("%d variance values floored\n", n);}int32 mgau_var_nzvec_floor (mgau_model_t *g, float64 floor){ int32 m, c, i, n, l; float32 *var; if(g->verbose) E_INFO("Applying variance floor to non-zero variance vectors\n"); l = mgau_veclen(g); n = 0; for (m = 0; m < mgau_n_mgau(g); m++) { for (c = 0; c < mgau_n_comp(g,m); c++) { var = g->mgau[m].var[c]; if (! vector_is_zero (var, l)) { for (i = 0; i < l; i++) { if (var[i] < floor) { var[i] = (float32) floor; n++; } } } } } if(g->verbose) E_INFO("%d variance values floored\n", n); return n;}/** * Some of the Mahalanobis distance computation (between Gaussian density means and given * vectors) can be carried out in advance. (See comment in .h file.) */static int32 mgau_precomp (mgau_model_t *g){ int32 m, c, i; float64 lrd; if(g->verbose) E_INFO("Precomputing Mahalanobis distance invariants\n"); for (m = 0; m < mgau_n_mgau(g); m++) { for (c = 0; c < mgau_n_comp(g,m); c++) { lrd = 0.0; for (i = 0; i < mgau_veclen(g); i++) { lrd += log(g->mgau[m].var[c][i]); /* Precompute this part of the exponential */ g->mgau[m].var[c][i] = (float32) (1.0 / (g->mgau[m].var[c][i] * 2.0)); } lrd += mgau_veclen(g) * log(2.0 * PI); /* (2pi)^velen */ mgau_lrd(g,m,c) = (float32)(-0.5 * lrd); /* Reciprocal, sqrt */ } } return 0;}/** Hack! Temporary measure to make classifier works. */int32 mgau_precomp_hack_log_to_float(mgau_model_t *g){ int32 m, c; if(g->verbose) E_INFO("Revert log values back to normal\n"); for (m = 0; m < mgau_n_mgau(g); m++) { for (c = 0; c < mgau_n_comp(g,m); c++) { mgau_lrd(g,m,c)=exp(mgau_lrd(g,m,c)); mgau_mixw_f(g,m,c)=exp(mgau_mixw_f(g,m,c)); } } return 0;}/** At the moment, S3 models have the same #means in each codebook and 1 var/mean */mgau_model_t *mgau_init (char *meanfile, char *varfile, float64 varfloor, char *mixwfile, float64 mixwfloor, int32 precomp, char* senmgau, int32 comp_type){ mgau_model_t *g; assert (meanfile != NULL); assert (varfile != NULL); assert (varfloor >= 0.0); assert (mixwfile != NULL); assert (mixwfloor >= 0.0); g = (mgau_model_t *) ckd_calloc (1, sizeof(mgau_model_t)); if(strcmp(senmgau,".cont.") == 0) { g->gau_type=CONTHMM; }else if(strcmp(senmgau,".semi.") == 0){ g->gau_type=SEMIHMM; }else{ E_FATAL("Feature should be either .semi. or .cont."); } if(comp_type==FULL_INT_COMP) E_INFO("Currently full integer GMM computation is not supported yet.\n"); assert(comp_type==FULL_FLOAT_COMP||comp_type==MIX_INT_FLOAT_COMP); g->comp_type=comp_type; /* Hardwire verbose to 1 */ g->verbose=1; /* Read means and (diagonal) variances for all mixture gaussians */ mgau_file_read (g, meanfile, MGAU_MEAN); mgau_file_read (g, varfile, MGAU_VAR); mgau_mixw_read (g, mixwfile, mixwfloor); mgau_uninit_compact (g); /* Delete uninitialized components */ if (varfloor > 0.0) mgau_var_floor (g, varfloor); /* Variance floor after above compaction */ if (precomp) mgau_precomp (g); /* Precompute Mahalanobis distance invariants */ if(g->comp_type==MIX_INT_FLOAT_COMP) g->distfloor = logs3_to_log (S3_LOGPROB_ZERO); /* Floor for Mahalanobis distance values */ else if(g->comp_type==FULL_FLOAT_COMP) g->distfloor = S3_LOGPROB_ZERO_F; return g;}int32 mgau_comp_eval (mgau_model_t *g, int32 s, float32 *x, int32 *score){ mgau_t *mgau; int32 veclen; float32 *m, *v; float64 dval, diff, f; int32 bs; int32 i, c; veclen = mgau_veclen(g); mgau = &(g->mgau[s]); f = log_to_logs3_factor(); bs = MAX_NEG_INT32; for (c = 0; c < mgau->n_comp; c++) { m = mgau->mean[c]; v = mgau->var[c]; dval = mgau->lrd[c]; for (i = 0; i < veclen; i++) { diff = x[i] - m[i]; dval -= diff * diff * v[i]; } if (dval < g->distfloor) dval = g->distfloor; score[c] = (int32) (f * dval); if (score[c] > bs) bs = score[c]; } return bs;}int32 mgau_eval (mgau_model_t *g, int32 m, int32 *active, float32 *x){ mgau_t *mgau; int32 veclen, score; float32 *m1, *m2, *v1, *v2; float64 dval1, dval2, diff1, diff2, f; int32 i, j, c; veclen = mgau_veclen(g); mgau = &(g->mgau[m]); assert(g->comp_type==MIX_INT_FLOAT_COMP); f = log_to_logs3_factor(); score = S3_LOGPROB_ZERO; if (! active) { /* No short list; use all */ for (c = 0; c < mgau->n_comp-1; c += 2) { /* Interleave 2 components for speed */ m1 = mgau->mean[c]; m2 = mgau->mean[c+1]; v1 = mgau->var[c]; v2 = mgau->var[c+1]; dval1 = mgau->lrd[c]; dval2 = mgau->lrd[c+1]; for (i = 0; i < veclen; i++) { diff1 = x[i] - m1[i]; dval1 -= diff1 * diff1 * v1[i]; diff2 = x[i] - m2[i]; dval2 -= diff2 * diff2 * v2[i]; } if (dval1 < g->distfloor) /* Floor */ dval1 = g->distfloor; if (dval2 < g->distfloor) dval2 = g->distfloor; score = logs3_add (score, (int32)(f * dval1) + mgau->mixw[c]); score = logs3_add (score, (int32)(f * dval2) + mgau->mixw[c+1]); } /* Remaining iteration if n_mean odd */ if (c < mgau->n_comp) { m1 = mgau->mean[c]; v1 = mgau->var[c]; dval1 = mgau->lrd[c]; for (i = 0; i < veclen; i++) { diff1 = x[i] - m1[i]; dval1 -= diff1 * diff1 * v1[i]; } if (dval1 < g->distfloor) dval1 = g->distfloor; score = logs3_add (score, (int32)(f * dval1) + mgau->mixw[c]); } } else { for (j = 0; active[j] >= 0; j++) { c = active[j]; m1 = mgau->mean[c]; v1 = mgau->var[c]; dval1 = mgau->lrd[c]; for (i = 0; i < veclen; i++) { diff1 = x[i] - m1[i]; dval1 -= diff1 * diff1 * v1[i]; } if (dval1 < g->distfloor) dval1 = g->distfloor; score = logs3_add (score, (int32)(f * dval1) + mgau->mixw[c]); } } if(score == S3_LOGPROB_ZERO){ /* E_INFO("Warning!! Score is S3_LOGPROB_ZERO\n");*/ } return score;}/* RAH, free memory allocated in mgau_init I've not verified that this function catches all of the leaks, just most of them. *//* ARCHAN, I noticed this program because of Ricky's comment. In 2004, a very useful tool called valgrind started to be available for Linux. This tool allows me to pick up a lot of memory problems easily. */void mgau_free (mgau_model_t *g){ if (g) { /* Free memory allocated for the mean structure*/ if (g->mgau[0].mean[0]) ckd_free (g->mgau[0].mean[0]); if (g->mgau[0].mean) ckd_free ((void *) g->mgau[0].mean); /* Free memory allocated for the var structure*/ if (g->mgau[0].var[0]) ckd_free (g->mgau[0].var[0]); if (g->mgau[0].var) ckd_free ((void *) g->mgau[0].var); if (g->mgau[0].lrd) ckd_free ((void *) g->mgau[0].lrd); /* Free memory allocated for the mixture weights*/ if (g->mgau[0].mixw) ckd_free ((void *) g->mgau[0].mixw); if (g->mgau[0].mixw_f) ckd_free ((void *) g->mgau[0].mixw_f); if (g->mgau) ckd_free ((void *) g->mgau); ckd_free ((void *) g); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?