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 + -
显示快捷键?