cont_mgau.c

来自「CMU大名鼎鼎的SPHINX-3大词汇量连续语音识别系统」· C语言 代码 · 共 844 行 · 第 1/2 页

C
844
字号
/* ==================================================================== * Copyright (c) 1999-2004 Carnegie Mellon University.  All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * This work was supported in part by funding from the Defense Advanced  * Research Projects Agency and the National Science Foundation of the  * United States of America, and the CMU Sphinx Speech Consortium. * * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ==================================================================== * *//* * cont_mgau.c -- Mixture Gaussians for continuous HMM models. * * ********************************************** * CMU ARPA Speech Project * * Copyright (c) 1997 Carnegie Mellon University. * ALL RIGHTS RESERVED. * ********************************************** * * HISTORY *  * 26-Aug-2004  ARCHAN (archan@cs.cmu.edu) *              Include changes that allow full floating point-based computation. Checking of computation type  *              is also added to all function of the code.  * 24-Jul-2004  ARCHAN (archan@cs.cmu.edu) *              Include new changes that allow use of Maximum Likelihood Linear Regression (MLLR) for speaker adaptation.  * 26-May-2004  ARCHAN (archan@cs.cmu.edu) *              Incorporate code for numerous fixes.  * 20.Apr.2001  RAH (rhoughton@mediasite.com, ricky.houghton@cs.cmu.edu) *              Added mgau_free to free memory allocated by mgau_init() * 15-Dec-1999	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * 		Added mgau_var_nzvec_floor(). *  * 28-Mar-1999	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University. * 		Started. */#include "s3types.h"#include "bio.h"#include "vector.h"#include "logs3.h"#include "cont_mgau.h"#define MGAU_PARAM_VERSION	"1.0"	/* Sphinx-3 file format version for mean/var */#define MGAU_MIXW_VERSION	"1.0"	/* Sphinx-3 file format version for mixw *//** \file cont_mgau.c     \brief Implementation detail of full GMM *  computation with integer value of log likelihood.   *//** * Sphinx-3 model mean and var files have the same format.  Use this routine for reading * either one. * Warning! You can only read the variance after reading the mean.   */static int32 mgau_file_read(mgau_model_t *g, char *file_name, int32 type){    char tmp;    FILE *fp;    int32 i, k, n;    int32 n_mgau;    int32 n_feat;    int32 n_density;    int32 *veclen;    int32 blk;    int32 byteswap, chksum_present;    float32 *buf, **pbuf;    char **argname, **argval;    uint32 chksum;    if(g->verbose) E_INFO("Reading mixture gaussian file '%s'\n", file_name);        fp = myfopen (file_name, "rb");        /* Read header, including argument-value info and 32-bit byteorder magic */    if (bio_readhdr (fp, &argname, &argval, &byteswap) < 0)	E_FATAL("bio_readhdr(%s) failed\n", file_name);        /* Parse argument-value list */    chksum_present = 0;    for (i = 0; argname[i]; i++) {	if (strcmp (argname[i], "version") == 0) {	    if (strcmp(argval[i], MGAU_PARAM_VERSION) != 0)		E_WARN("Version mismatch(%s): %s, expecting %s\n",		       file_name, argval[i], MGAU_PARAM_VERSION);	} else if (strcmp (argname[i], "chksum0") == 0) {	    chksum_present = 1;	/* Ignore the associated value */	}    }    bio_hdrarg_free (argname, argval);    argname = argval = NULL;        chksum = 0;        /* #Codebooks */    if (bio_fread (&n_mgau, sizeof(int32), 1, fp, byteswap, &chksum) != 1)	E_FATAL("fread(%s) (#codebooks) failed\n", file_name);    if (n_mgau >= MAX_S3MGAUID) {	E_FATAL("%s: #Mixture Gaussians (%d) exceeds limit(%d) enforced by MGAUID type\n",		file_name, n_mgau, MAX_S3MGAUID);    }        /* #Features/codebook */    if (bio_fread (&n_feat, sizeof(int32), 1, fp, byteswap, &chksum) != 1)	E_FATAL("fread(%s) (#features) failed\n", file_name);        if(g->gau_type==CONTHMM){      if (n_feat != 1)	E_FATAL("#Features streams(%d) != 1 in continuous HMM\n", n_feat);    }else if (g->gau_type==SEMIHMM){      if (n_feat != 4)	E_FATAL("#Features streams(%d) != 1 in semi-continuous HMM\n", n_feat);    }        /* #Gaussian densities/feature in each codebook */    if (bio_fread (&n_density, sizeof(int32), 1, fp, byteswap, &chksum) != 1)	E_FATAL("fread(%s) (#density/codebook) failed\n", file_name);        /* Vector length of feature stream */    veclen = ckd_calloc(n_feat, sizeof(uint32));    if (bio_fread (veclen, sizeof(int32), n_feat, fp, byteswap, &chksum) != n_feat)	E_FATAL("fread(%s) (feature-lengths) failed\n", file_name);    for (i = 0, blk = 0; i < n_feat; i++)	blk += veclen[i];    /*    if (bio_fread (&veclen, sizeof(int32), 1, fp, byteswap, &chksum) != 1)	  E_FATAL("fread(%s) (feature vector-length) failed\n", file_name);*/        /* #Floats to follow; for the ENTIRE SET of CODEBOOKS */    if (bio_fread (&n, sizeof(int32), 1, fp, byteswap, &chksum) != 1)	E_FATAL("fread(%s) (total #floats) failed\n", file_name);    if (n != n_mgau * n_density * blk) {	E_FATAL("%s: #float32s(%d) doesn't match dimensions: %d x %d x %d\n",		file_name, n, n_mgau, n_density, blk);    }        if(g->gau_type==SEMIHMM){      E_FATAL("Currently S2 semi-continous HMM is not supported\n");    }    if (type == MGAU_MEAN) {	/* Allocate memory for mixture gaussian densities */	g->n_mgau = n_mgau;	g->max_comp = n_density;	g->veclen = blk;	if(!(g->mgau)) {	  g->mgau = (mgau_t *) ckd_calloc (n_mgau, sizeof(mgau_t));	  buf = (float32 *) ckd_calloc (n, sizeof(float));	  pbuf = (float32 **) ckd_calloc (n_mgau * n_density, sizeof(float32 *));	  	  for (i = 0; i < n_mgau; i++) {	    g->mgau[i].n_comp = n_density;	    g->mgau[i].mean = pbuf;	    	    for (k = 0; k < n_density; k++) {	      g->mgau[i].mean[k] = buf;		buf += blk;			    }	    pbuf += n_density;	  }	}	buf = g->mgau[0].mean[0];	/* Restore buf to original value */    } else {	assert (type == MGAU_VAR);		if (g->n_mgau != n_mgau)	    E_FATAL("#Mixtures(%d) doesn't match that of means(%d)\n", n_mgau, g->n_mgau);	if (g->max_comp != n_density)	    E_FATAL("#Components(%d) doesn't match that of means(%d)\n", n_density, g->max_comp);	if (g->veclen != blk)	    E_FATAL("#Vector length(%d) doesn't match that of means(%d)\n", blk, g->veclen);	if(!(g->mgau[0].var)){	  buf = (float32 *) ckd_calloc (n, sizeof(float32));	  pbuf = (float32 **) ckd_calloc (n_mgau * n_density, sizeof(float32 *));	  	  for (i = 0; i < n_mgau; i++) {	    if (g->mgau[i].n_comp != n_density)	      E_FATAL("Mixture %d: #Components(%d) doesn't match that of means(%d)\n",		      i, n_density, g->mgau[i].n_comp);	    	    g->mgau[i].var = pbuf;	    	    for (k = 0; k < n_density; k++) {	      g->mgau[i].var[k] = buf;	      buf += blk;	      	    }	    pbuf += n_density;	  }	  buf = (float32 *) ckd_calloc (n_mgau * n_density, sizeof(float32));	  	  for (i = 0; i < n_mgau; i++) {	    g->mgau[i].lrd = buf;	    buf += n_density;	  }	}	buf = g->mgau[0].var[0];	/* Restore buf to original value */    }        /* Read mixture gaussian densities data */    if (bio_fread (buf, sizeof(float32), n, fp, byteswap, &chksum) != n)	E_FATAL("fread(%s) (densitydata) failed\n", file_name);    if (chksum_present)	bio_verify_chksum (fp, byteswap, chksum);    if (fread (&tmp, 1, 1, fp) == 1)	E_FATAL("%s: More data than expected\n", file_name);        fclose(fp);        if(g->verbose)      E_INFO("%d mixture Gaussians, %d components, %d streams, veclen %d\n", n_mgau, n_density, n_feat, blk);        ckd_free(veclen);    return 0;}int32 mgau_mean_reload(mgau_model_t *g, char* mean_file_name){  assert (g->mgau!=NULL);  mgau_file_read (g, mean_file_name, MGAU_MEAN);  /* ARCHAN 20040724 should do s3-like verification, need to change interface though. Put it later.  */  return 0; }int32 mgau_dump(mgau_model_t *g, int32 type){  int32 d, c, i;  char* tmpstr;  mgau_t m;  assert (g!=NULL);  assert (g->mgau!=NULL);  assert (g->mgau[0].mean!=NULL);  assert (g->mgau[0].var!=NULL);  assert (type == MGAU_VAR || type == MGAU_MEAN);  tmpstr=ckd_calloc((mgau_veclen(g) * 20),sizeof(char));  E_INFO("\n");  if(type==MGAU_MEAN){    for(d=0;d<mgau_n_mgau(g);d++){      m=g->mgau[d];      sprintf(tmpstr,"Mean of %d\n",d);      E_INFO("%s",tmpstr);            for(c=0;c<mgau_n_comp(g,d);c++){	sprintf(tmpstr,"Component %d",c);	for(i=0;i<mgau_veclen(g);i++){	  sprintf(tmpstr,"%s %f",tmpstr,m.mean[c][i]);	}      sprintf(tmpstr, "%s\n",tmpstr);      E_INFO("%s",tmpstr);      }    }  }  if(type == MGAU_VAR){    for(d=0;d<mgau_n_mgau(g);d++){      m=g->mgau[d];      sprintf(tmpstr,"Variance of %d",d);      E_INFO("%s",tmpstr);            for(c=0;c<mgau_n_comp(g,d);c++){	sprintf(tmpstr,"Component %d\n",c);	for(i=0;i<mgau_veclen(g);i++){	  sprintf(tmpstr,"%s %f",tmpstr,m.var[c][i]);	}      sprintf(tmpstr, "%s\n",tmpstr);      }      E_INFO("%s",tmpstr);  }  }  ckd_free(tmpstr);  return 0 ;}static int32 mgau_mixw_read(mgau_model_t *g, char *file_name, float64 mixwfloor){    char **argname, **argval;    char eofchk;    FILE *fp;    int32 byteswap, chksum_present;    uint32 chksum;    int32 *buf;    float32 *buf_f;    float32 *pdf;    int32 i, j, n;    int32 n_mgau;    int32 n_feat;    int32 n_comp;    int32 n_err;        if(g->verbose) E_INFO("Reading mixture weights file '%s'\n", file_name);        fp = myfopen (file_name, "rb");        /* Read header, including argument-value info and 32-bit byteorder magic */    if (bio_readhdr (fp, &argname, &argval, &byteswap) < 0)	E_FATAL("bio_readhdr(%s) failed\n", file_name);        /* Parse argument-value list */    chksum_present = 0;    for (i = 0; argname[i]; i++) {	if (strcmp (argname[i], "version") == 0) {	    if (strcmp(argval[i], MGAU_MIXW_VERSION) != 0)		E_WARN("Version mismatch(%s): %s, expecting %s\n",			file_name, argval[i], MGAU_MIXW_VERSION);	} else if (strcmp (argname[i], "chksum0") == 0) {	    chksum_present = 1;	/* Ignore the associated value */	}    }    bio_hdrarg_free (argname, argval);    argname = argval = NULL;    chksum = 0;    /* Read #senones, #features, #codewords, arraysize */    if ((bio_fread (&n_mgau, sizeof(int32), 1, fp, byteswap, &chksum) != 1) ||	(bio_fread (&n_feat, sizeof(int32), 1, fp, byteswap, &chksum) != 1) ||	(bio_fread (&n_comp, sizeof(int32), 1, fp, byteswap, &chksum) != 1) ||	(bio_fread (&n, sizeof(int32), 1, fp, byteswap, &chksum) != 1)) {	E_FATAL("bio_fread(%s) (arraysize) failed\n", file_name);    }    if(g->gau_type==CONTHMM){      if (n_feat != 1)	E_FATAL("#Features streams(%d) != 1 in continuous HMM\n", n_feat);    }else if (g->gau_type==SEMIHMM){      if (n_feat != 4)	E_FATAL("#Features streams(%d) != 4 in semi-continuous HMM\n", n_feat);    }else{	E_FATAL("How can this happen? Someone must have moved this part of the code somewhere! Not my fault! ARCHAN at 20040504 :-)\n");    }    if (n != n_mgau * n_comp) {	E_FATAL("%s: #float32s(%d) doesn't match header dimensions: %d x %d\n",		file_name, i, n_mgau, n_comp);    }    if (n_mgau != g->n_mgau){      E_FATAL("%s: #Mixture Gaussians(%d) doesn't match mean/var parameters(%d)\n",	      n_mgau, g->n_mgau);    }        if(g->comp_type==MIX_INT_FLOAT_COMP){      /*Memory allocation of the integer version of mixture weight*/      buf = (int32 *) ckd_calloc (n_mgau * n_comp, sizeof(int32));      for (i = 0; i < n_mgau; i++) {	if (n_comp != mgau_n_comp(g,i))	  E_FATAL("Mixture %d: #Weights(%d) doesn't match #Gaussian components(%d)\n",		  i, n_comp, mgau_n_comp(g,i));	g->mgau[i].mixw = buf;	buf += g->mgau[i].n_comp;      }    }else if(g->comp_type==FULL_FLOAT_COMP){      /*Memory allocation of the floating point version of mixture weight */      buf_f = (float32 *) ckd_calloc(n_mgau * n_comp, sizeof(float32));      for (i = 0; i < n_mgau; i++) {	if (n_comp != mgau_n_comp(g,i))	  E_FATAL("Mixture %d: #Weights(%d) doesn't match #Gaussian components(%d)\n",		  i, n_comp, mgau_n_comp(g,i));	g->mgau[i].mixw_f = buf_f;	buf_f += g->mgau[i].n_comp;      }    }else{      E_FATAL("Unsupported GMM computation type %d \n",g->comp_type);    }    /* Temporary structure to read in floats */    /* In the case of hybrid computation, logs3 will be used to convert        the weight to integer */    pdf = (float32 *) ckd_calloc (n_comp, sizeof(float32));        /* Read mixw data, normalize, floor. */    n_err = 0;    for (i = 0; i < n_mgau; i++) {      if (bio_fread((void *)pdf, sizeof(float32), n_comp, fp, byteswap, &chksum) != n_comp)	E_FATAL("bio_fread(%s) (arraydata) failed\n", file_name);

⌨️ 快捷键说明

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