📄 hadapt.c
字号:
/* ----------------------------------------------------------- *//* *//* ___ *//* |_| | |_/ SPEECH *//* | | | | \ RECOGNITION *//* ========= SOFTWARE */ /* *//* *//* ----------------------------------------------------------- *//* developed at: *//* *//* Speech Vision and Robotics group *//* Cambridge University Engineering Department *//* http://svr-www.eng.cam.ac.uk/ *//* *//* ----------------------------------------------------------- *//* Copyright: *//* *//* 2003 M.J.F. Gales and *//* Cambridge University *//* Engineering Department *//* *//* Use of this software is governed by a License Agreement *//* ** See the file License for the Conditions of Use ** *//* ** This banner notice must not be removed ** *//* *//* ----------------------------------------------------------- *//* File: HAdapt.c Adaptation Library module *//* ----------------------------------------------------------- */char *hadapt_version = "!HVER!HAdapt: 3.3 [CUED 28/04/05]";char *hadapt_vc_id = "$Id: HAdapt.c,v 1.3 2005/07/22 10:17:01 mjfg Exp $";#include <stdio.h> /* Standard C Libraries */#include <stdlib.h>#include <string.h>#include <math.h>#include <ctype.h>#include "HShell.h" /* HMM ToolKit Modules */#include "HMem.h"#include "HMath.h"#include "HSigP.h"#include "HWave.h"#include "HAudio.h"#include "HParm.h"#include "HLabel.h"#include "HModel.h"#include "HTrain.h"#include "HUtil.h"#include "HAdapt.h"#include "HFB.h"/* trace flags */#define T_TOP 00001 /* Top level tracing */#define T_ADT 00002 /* Trace number of adapted components */#define T_ACC 00004 /* Trace number of accumulates generated */#define T_TRE 00010 /* Trace use of regression class tree */#define T_XFM 00020 /* Trace generation of xforms */#define T_SXF 00040 /* Speaker xform updates */#define T_OBC 00100 /* Trace observation cache */#define T_SWP 00200 /* Trace transform manipulation *//* -------------- Structures to store adaptation info -------------------- */typedef struct { XFormKind xkind; int dim; double occ; IntVec blockSize; DVector *K, D; DMatrix *G;} AccStruct;typedef struct _AInfo { int baseClass; int level; struct _AInfo *next; /* next external file name in list */} AInfo;typedef struct { Vector mean; Covariance cov; float gConst;} MInfo;typedef struct _ObsCache{ int time; Vector obs; float det; struct _ObsCache *next;} ObsCache; /* observation cache to save rotated observations */typedef struct _AccCache{ int baseclass; DVector bVector; TriMat *bTriMat; struct _AccCache *next;} AccCache; /* acc cache to save accumulators related to parent XForm */ typedef struct { float occ; Vector spSum; Vector spSumSq; TriMat *bTriMat; TriMat *bDiagMat; DVector bVector;} RegAcc;typedef struct { AInfo *aInfo; /* current transform information */ MInfo *mInfo; /* any original model information */ AInfo *paInfo; /* parent transform information */ RegAcc *regAcc; /* accumulate information for generating transform */ ObsCache *oc; /* observation cache for input transform */ ObsCache *paoc; /* observation cache for parent transform */ AccCache *paac; /* accummulator cache for parent transform */} XFormInfo;/* General variables */static ConfParam *cParm[MAXGLOBS]; /* config parameters */static int nParm = 0;static int trace = 0; /* trace info *//* Global information about current set of transforms *//* static AdaptXForm* curXForm = NULL;static AdaptXForm* parentXForm = NULL;*/static AdaptXForm* outXForm = NULL;static AdaptXForm* diagCovXForm = NULL;/* Local stack to allow storage of internal structrures */static MemHeap infoStack;static MemHeap obcaStack;/* Global variables */static XFormKind xKind = MLLRMEAN; /* Transform Kind to be created *//* also have the option of storing a model set for each of the speakers */static Boolean saveSpkrModels = FALSE;/* The xform config variable information */static float minOccThresh = 0.0; /* minimum occupancy to accumulate stats to estimate xform */static Boolean useBias = TRUE; /* whether a bias is to be estimated for the xform */static Boolean storeMInfo = TRUE; /* whether original model information is to be stored */static Boolean keepXFormDistinct = TRUE;static Boolean swapXForms = FALSE; /* swap the transforms around after generating transform */static Boolean mllrCov2CMLLR= FALSE; /* apply mllrcov transforms as cmllr transform */ static Boolean mllrDiagCov = FALSE; /* perform diagonal covariance adaptation */static IntVec enableBlockAdapt = NULL;/* split threshold definitions for each xform kind */static float xformSplitThresh = -1000.0;static float mllrMeanSplitThresh = 1000.0;static float mllrCovSplitThresh = 1000.0;static float cmllrSplitThresh = 1000.0;/* adaptation kind definitions for each xform kind */static AdaptKind xformAdaptKind = BASE;static AdaptKind mllrMeanAdaptKind = BASE;static AdaptKind mllrCovAdaptKind = BASE;static AdaptKind cmllrAdaptKind = BASE;/* regression tree definitions for each xform kind */static char *xformRegTree = NULL;static char *mllrMeanRegTree = NULL;static char *mllrCovRegTree = NULL;static char *cmllrRegTree = NULL;/* baseclass definitions for each xform kind */static char *xformBaseClass = NULL;static char *mllrMeanBaseClass = NULL;static char *mllrCovBaseClass = NULL;static char *cmllrBaseClass = NULL;/* block size definitions for each xform kind */static IntVec xformBlockSize = NULL;static IntVec mllrMeanBlockSize = NULL;static IntVec mllrCovBlockSize = NULL;static IntVec cmllrBlockSize = NULL;/* current time when this changes accumulate complete stats *//* -1 indicates that this is the first frame of a new file */static int baseTriMatTime=-1; static double maxXFormIter = 10; /* something big, for CMLLR */ static ObsCache *headoc = NULL; static AccCache *headac = NULL;/*------------------------------------------------------------------------*//* Support Routines for determining internal structures required *//* Note: these only act on the transform NOT any parents. *//*------------------------------------------------------------------------*/static Boolean AccAdaptMean(AdaptXForm *xform){ /* Currently always true */ return (TRUE);}static Boolean AccAdaptVar(AdaptXForm *xform){ XFormKind xkind = xform->xformSet->xkind; if ( (xkind == CMLLR) || (xkind == MLLRCOV) || (mllrDiagCov)) return (TRUE); else return (FALSE);}static Boolean AccAdaptBaseTriMat(AdaptXForm *xform){ XFormKind xkind = xform->xformSet->xkind; if ( (xkind == CMLLR) || (xkind == MLLRCOV)) return (TRUE); else return (FALSE);}Boolean HardAssign(AdaptXForm *xform){ AdaptKind akind = xform->akind; return ((akind == TREE) || (akind == BASE));}static Boolean StoreAdaptMean(AdaptXForm *xform){ XFormKind xkind = xform->xformSet->xkind; return ((xkind == MLLRMEAN) || (xkind == MLLRCOV));}static Boolean StoreAdaptCov(AdaptXForm *xform){ XFormKind xkind = xform->xformSet->xkind; return (xkind == MLLRVAR);}/*------------------------------------------------------------------------*//* Initialisations and general structures allocation *//*------------------------------------------------------------------------*/static void CheckAdaptOptions(){ if ((!keepXFormDistinct) && (swapXForms)) HError(999,"Cannot save swapped XForms in a TMF"); if ((xKind == MLLRCOV) && (useBias)) HError(999,"Cannot have a Bias with a Full variance transform"); if ((mllrDiagCov) && (xKind != MLLRMEAN)) HError(999,"Cannot have mllrDiagCov and not have MLLRMEAN"); if ((!swapXForms) && (mllrCov2CMLLR)) HError(999,"Cannot save mllrCov as CMLLR");}/* ParseConfIntVec: interpret config string as integer array */static IntVec ParseConfIntVec(MemHeap *x, char *inbuf){ IntVec ivec = NULL; int size,cnt; char buf[MAXSTRLEN],tbuf[MAXSTRLEN]; if (sscanf(inbuf,"%s",buf)>0) { if (strcmp(buf,"IntVec") != 0) HError(999,"ParseConfIntVec: format is IntVec d d d ...."); inbuf=strstr(inbuf,"IntVec")+strlen("IntVec"); sscanf(inbuf,"%d",&size); sprintf(tbuf,"%d",size); inbuf=strstr(inbuf,tbuf)+(int)strlen(tbuf); ivec = CreateIntVec(x,size); cnt = 1; while ((strlen(inbuf)>0) && (cnt<=size) && (sscanf(inbuf,"%d",&(ivec[cnt])))) { sprintf(tbuf,"%d",ivec[cnt]); inbuf=strstr(inbuf,tbuf)+(int)strlen(tbuf); cnt++; } if (strlen(inbuf)>0) HError(999,"ParseConfIntVec: residual elements - format is n b1 ... bn"); } else HError(999,"ParseConfIntVec: format is n b1 ... bn"); return ivec;}/* EXPORT->InitAdapt: initialise configuration parameters */void InitAdapt (XFInfo *xfinfo) { int i; Boolean b; double d; char buf[MAXSTRLEN]; Register(hadapt_version,hadapt_vc_id); nParm = GetConfig("HADAPT", TRUE, cParm, MAXGLOBS); /* setup the local memory management - defaults sensible? */ CreateHeap(&infoStack,"InfoStore", MSTAK, 1, 1.0, 50000, 500000); CreateHeap(&obcaStack,"ObsStore", MSTAK, 1, 1.0, 50000, 500000); if (nParm>0){ /* general adaptation config variables */ if (GetConfInt(cParm,nParm,"TRACE",&i)) trace = i; if (GetConfFlt(cParm,nParm,"MINOCCTHRESH",&d)) minOccThresh = (float) d; if (GetConfBool(cParm,nParm,"STOREMINFO",&b)) storeMInfo = b; if (GetConfBool(cParm,nParm,"KEEPXFORMDISTINCT",&b)) keepXFormDistinct = b; if (GetConfBool(cParm,nParm,"SAVESPKRMODELS",&b)) saveSpkrModels = b; /* Adaptation transformation set-up */ if (GetConfBool(cParm,nParm,"USEBIAS",&b)) useBias = b; if (GetConfFlt(cParm,nParm,"SPLITTHRESH",&d)) xformSplitThresh = (float) d; if (GetConfStr (cParm,nParm,"TRANSKIND",buf)) xKind = Str2XFormKind(buf); if (GetConfStr (cParm,nParm,"BLOCKSIZE",buf)) xformBlockSize = ParseConfIntVec(&infoStack,buf); if (GetConfStr (cParm,nParm,"BASECLASS",buf)) xformBaseClass = CopyString(&infoStack,buf); if (GetConfStr (cParm,nParm,"REGTREE",buf)) xformRegTree = CopyString(&infoStack,buf); if (GetConfStr (cParm,nParm,"ADAPTKIND",buf)) xformAdaptKind = Str2AdaptKind(buf); if (GetConfInt(cParm,nParm,"MAXXFORMITER",&i)) maxXFormIter = i; if (GetConfBool(cParm,nParm,"MLLRDIAGCOV",&b)) mllrDiagCov = b; if (GetConfBool(cParm,nParm,"SWAPXFORMS",&b)) swapXForms = b; if (GetConfBool(cParm,nParm,"MLLRCOV2CMLLR",&b)) mllrCov2CMLLR = b; /* Backward compatibility with old configuration options */ /* MLLRMEAN specification */ if (GetConfFlt(cParm,nParm,"MLLRMEANSPLITTHRESH",&d)) mllrMeanSplitThresh = (float) d; if (GetConfStr (cParm,nParm,"MLLRMEANBLOCKSIZE",buf)) mllrMeanBlockSize = ParseConfIntVec(&infoStack,buf); if (GetConfStr (cParm,nParm,"MLLRMEANBASECLASS",buf)) mllrMeanBaseClass = CopyString(&infoStack,buf); if (GetConfStr (cParm,nParm,"MLLRMEANREGTREE",buf)) mllrMeanRegTree = CopyString(&infoStack,buf); if (GetConfStr (cParm,nParm,"MLLRMEANADAPTKIND",buf)) mllrMeanAdaptKind = Str2AdaptKind(buf); /* MLLRCOV specification */ if (GetConfFlt(cParm,nParm,"MLLRCOVSPLITTHRESH",&d)) mllrCovSplitThresh = (float) d; if (GetConfStr (cParm,nParm,"MLLRCOVBLOCKSIZE",buf)) mllrCovBlockSize = ParseConfIntVec(&infoStack,buf); if (GetConfStr (cParm,nParm,"MLLRCOVBASECLASS",buf)) mllrCovBaseClass = CopyString(&infoStack,buf); if (GetConfStr (cParm,nParm,"MLLRCOVREGTREE",buf)) mllrCovRegTree = CopyString(&infoStack,buf); if (GetConfStr (cParm,nParm,"MLLRCOVADAPTKIND",buf)) mllrCovAdaptKind = Str2AdaptKind(buf); /* CMLLR specification */ if (GetConfFlt(cParm,nParm,"CMLLRSPLITTHRESH",&d)) cmllrSplitThresh = (float) d; if (GetConfStr (cParm,nParm,"CMLLRBLOCKSIZE",buf)) cmllrBlockSize = ParseConfIntVec(&infoStack,buf); if (GetConfStr (cParm,nParm,"CMLLRBASECLASS",buf)) cmllrBaseClass = CopyString(&infoStack,buf); if (GetConfStr (cParm,nParm,"CMLLRREGTREE",buf)) cmllrRegTree = CopyString(&infoStack,buf); if (GetConfStr (cParm,nParm,"CMLLRADAPTKIND",buf)) cmllrAdaptKind = Str2AdaptKind(buf); } /* Initialise the XFInfo values */ xfinfo->outSpkrPat = "*.%%%"; xfinfo->inSpkrPat = NULL; xfinfo->paSpkrPat = NULL; xfinfo->outXFormExt = NULL; xfinfo->inXFormExt = NULL; xfinfo->paXFormExt = NULL; xfinfo->outXFormDir = NULL; xfinfo->paXFormDir = NULL; xfinfo->useOutXForm = FALSE; xfinfo->useInXForm = FALSE; xfinfo->usePaXForm = FALSE; xfinfo->xformTMF = NULL; xfinfo->inXForm = NULL; xfinfo->outXForm = NULL; xfinfo->paXForm = NULL; xfinfo->al_hset = NULL; xfinfo->alXFormExt = NULL; xfinfo->alXFormDir = NULL; CheckAdaptOptions();}/* Additional code to parse configs to for appropriate thresholds */static float GetSplitThresh(AdaptXForm *xform){ float thresh=0.0; if (xformSplitThresh > 0) { thresh = xformSplitThresh; } else { switch(xform->xformSet->xkind) { case MLLRMEAN: thresh = mllrMeanSplitThresh; break; case MLLRCOV: thresh = mllrCovSplitThresh; break; case CMLLR: thresh = cmllrSplitThresh; break; } } return thresh;}static AdaptKind GetAdaptKind(AdaptXForm *xform){ AdaptKind akind = BASE; if (xformAdaptKind != BASE) { akind = xformAdaptKind; } else { switch(xform->xformSet->xkind) { case MLLRMEAN: akind = mllrMeanAdaptKind; break; case MLLRCOV: akind = mllrCovAdaptKind; break; case CMLLR: akind = cmllrAdaptKind; break; } } return akind;}static RegTree* GetRegTree(HMMSet *hset, AdaptXForm *xform){ char* basename = NULL; char macroname[MAXSTRLEN]; if (xformRegTree != NULL) { basename = xformRegTree; } else { switch(xform->xformSet->xkind) { case MLLRMEAN: basename = mllrMeanRegTree; break; case MLLRCOV: basename = mllrCovRegTree; break; case CMLLR: basename = cmllrRegTree;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -