📄 hsmooth.c
字号:
/* ----------------------------------------------------------- *//* *//* ___ *//* |_| | |_/ SPEECH *//* | | | | \ RECOGNITION *//* ========= SOFTWARE */ /* *//* *//* ----------------------------------------------------------- *//* Copyright: Microsoft Corporation *//* 1995-2000 Redmond, Washington USA *//* http://www.microsoft.com *//* *//* 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: HSmooth.c: Perform Parameter Smoothing on a HMM Set *//* ----------------------------------------------------------- */char *hsmooth_version = "!HVER!HSmooth: 3.3 [CUED 28/04/05]";char *hsmooth_vc_id = "$Id: HSmooth.c,v 1.1.1.1 2005/05/12 10:52:55 jal58 Exp $";#include "HShell.h" /* HMM ToolKit Modules */#include "HMem.h"#include "HMath.h"#include "HSigP.h"#include "HAudio.h"#include "HWave.h"#include "HVQ.h"#include "HParm.h"#include "HLabel.h"#include "HModel.h"#include "HTrain.h"#include "HUtil.h"#define MAXMONOPHONES 500 /* max number of monophones in HMMSet *//* Trace Flags */#define T_TOP 0001 /* Top level tracing */#define T_INT 0002 /* Interpolation weights */#define T_OPT 0004 /* Optimisation algorithm details *//* -------------- Global Settings ------------------ *//* Command line controlled */static char * hmmDir = NULL; /* directory to look for hmm def files */static char * hmmExt = NULL; /* hmm def file extension */static char * newDir = NULL; /* directory to store new hmm def files */static char * newExt = NULL; /* extension of new reestimated hmm files */static char * statFN; /* stats file, if any */static float minVar = 0.0; /* minimum variance (diagonal only) */static float mixWeightFloor=0.0; /* Floor for mixture weights */static int minEgs = 3; /* min examples to train a model */static int maxStep = 16; /* max number of binary chops */static float epsilon = 0.0001; /* binary chop convergence criterion */static UPDSet uFlags = (UPDSet) (UPMEANS|UPVARS|UPTRANS|UPMIXES); /* update flags */static Boolean stats = FALSE; /* enable statistics reports */static Boolean saveBinary = FALSE; /* save output in binary */static Boolean ldBinary = TRUE; /* load in binary */static int trace = 0; /* Trace level */static int nBlk = 0; /* number of data blocks *//* HMMSet related */static HMMSet hset; /* Set of HMMs to be re-estimated */static int maxStates = 0; /* max states in any model */static int maxMixes = 0; /* max mixtures in any model */static int vSize; /* input vector size */static int nStreams; /* number of data streams */static HSetKind hsKind; /* kind of loaded hmm set */static int nLogHmms; /* number of logical HMM's */static int nPhyHmms; /* number of physical HMM's *//* Dynamic storage */static int aSize; /* size of current aSet */static HLink *aSet; /* array[1..aSize]of allophone */static StreamElem **sSet; /* array[1..aSize]of stream */static Vector *wbar; /* array[0..nBlk]of weight vector */static Vector *wcd; /* array[0..nBlk]of weight vector */static int nPhones; /* number of monophones */static LabId *monophones; /* array[1..nPhones]of LabId */static int totalT=0; /* total number of frames in training data */static LogDouble totalPr; /* total log prob of all training utterances */static Vector vFloor[SMAX]; /* variance floor - default is all zero *//* Configuration parameters */static ConfParam *cParm[MAXGLOBS];static int nParm = 0; /* total num params *//* Memory heaps */static MemHeap hmmStack; /*For Storage of dynamic data structures */static MemHeap aSetStack;static MemHeap sSetStack;static MemHeap wsStack;static MemHeap labIdStack;static MemHeap wtAccStack;/* -------------------------- Config Params ----------------------- *//* SetConfParms: set conf parms relevant to HSmooth */void SetConfParms(void){ int i; Boolean b; nParm = GetConfig("HSMOOTH", TRUE, cParm, MAXGLOBS); if (nParm>0) { if (GetConfInt(cParm,nParm,"TRACE",&i)) trace = i; if (GetConfBool(cParm,nParm,"SAVEBINARY",&b)) saveBinary = b; if (GetConfBool(cParm,nParm,"BINARYACCFORMAT",&b)) ldBinary = b; }}/* ------------------ Process Command Line -------------------------- */void ReportUsage(void){ printf("\nUSAGE: HSmooth [options] hmmList AccFiles...\n\n"); printf(" Option Default\n\n"); printf(" -b f set convergence epsilon 0.0001\n"); printf(" -c N max num steps in binary chop 16\n"); printf(" -d s dir to find hmm definitions current\n"); printf(" -m N set min examples needed per model 3\n"); printf(" -o s extension for new hmm files as src\n"); printf(" -s s print statistics to file s off\n"); printf(" -u tmvw Update t)rans m)eans v)ars w)ghts tmvw\n"); printf(" -v f Set minimum variance to f 0.0\n"); printf(" -w f Set mix weight floor to f*MINMIX 0.0\n"); printf(" -x s extension for hmm files none\n"); PrintStdOpts("BHMST"); printf("\n\n");}void SetuFlags(void){ char *s; s=GetStrArg(); uFlags=(UPDSet) 0; while (*s != '\0') switch (*s++) { case 't': uFlags = (UPDSet) (uFlags+UPTRANS); break; case 'm': uFlags = (UPDSet) (uFlags+UPMEANS); break; case 'v': uFlags = (UPDSet) (uFlags+UPVARS); break; case 'w': uFlags = (UPDSet) (uFlags+UPMIXES); break; default: HError(2420,"SetuFlags: Unknown update flag %c",*s); break; }}int main(int argc, char *argv[]){ Source src; int tmpInt; float tmpFlt; char *accfn, *s; void Initialise(char *hmmListFn); void Interpolate(void); void UpdateModels(void); void MakeWtAccLists(void); void AttachWtAccLists(void); void StatReport(void); if(InitShell(argc,argv,hsmooth_version,hsmooth_vc_id)<SUCCESS) HError(2400,"HSmooth: InitShell failed"); InitMem(); InitLabel(); InitMath(); InitSigP(); InitWave(); InitAudio(); InitVQ(); InitModel(); if(InitParm()<SUCCESS) HError(2400,"HSmooth: InitParm failed"); InitTrain(); InitUtil(); if (!InfoPrinted() && NumArgs() == 0) ReportUsage(); if (NumArgs() == 0) Exit(0); SetConfParms(); CreateHeap(&hmmStack,"HmmStore", MSTAK, 1, 1.0, 50000, 500000); CreateHMMSet(&hset,&hmmStack,TRUE); while (NextArg() == SWITCHARG) { s = GetSwtArg(); if (strlen(s)!=1) HError(2419,"HSmooth: Bad switch %s; must be single letter",s); switch(s[0]){ case 'b': epsilon = GetChkedFlt(0.0,1.0,s); break; case 'c': maxStep = GetChkedInt(1,1000,s); break; case 'd': if (NextArg()!=STRINGARG) HError(2419,"HSmooth: HMM definition directory expected"); hmmDir = GetStrArg(); break; case 'e': if (NextArg()!=STRINGARG) HError(2419,"HSmooth: HMM definition directory expected"); newDir = GetStrArg(); break; case 'm': minEgs = GetChkedInt(1,1000,s); break; case 'o': if (NextArg()!=STRINGARG) HError(2419,"HSmooth: HMM file extension expected"); newExt = GetStrArg(); break; case 's': stats = TRUE; if (NextArg()!=STRINGARG) HError(2419,"HSmooth: Stats file name expected"); statFN = GetStrArg(); break; case 'u': SetuFlags(); break; case 'v': minVar = GetChkedFlt(0.0,10.0,s); break; case 'w': mixWeightFloor = MINMIX * GetChkedFlt(0.0,10000.0,s); break; case 'x': if (NextArg()!=STRINGARG) HError(2419,"HSmooth: HMM file extension expected"); hmmExt = GetStrArg(); break; case 'B': saveBinary=TRUE; break; case 'H': if (NextArg() != STRINGARG) HError(2419,"HSmooth: HMM macro file name expected"); AddMMF(&hset,GetStrArg()); break; case 'M': if (NextArg()!=STRINGARG) HError(2419,"HSmooth: Output macro file directory expected"); newDir = GetStrArg(); break; case 'T': trace = GetChkedInt(0,0100000,s); break; default: HError(2419,"HSmooth: Unknown switch %s",s); } } if (NextArg() != STRINGARG) HError(2419,"HSmooth: file name of HMM list expected"); Initialise(GetStrArg()); do { if (NextArg()!=STRINGARG) HError(2419,"HSmooth: accumulator file name expected"); accfn = GetStrArg(); src=LoadAccs(&hset,accfn,uFlags); ReadFloat(&src,&tmpFlt,1,ldBinary); totalPr += (LogDouble)tmpFlt; ReadInt(&src,&tmpInt,1,ldBinary); totalT += tmpInt; CloseSource(&src); nBlk++; MakeWtAccLists(); } while (NumArgs()>0); AttachWtAccLists(); Interpolate(); if (stats) StatReport(); UpdateModels(); Exit(0); return (0); /* never reached -- make compiler happy */}/* ------------------------- Mix Weight Accs ---------------------- *//* ChWtAcc - Chainable weight accumulator */typedef struct _ChWtAcc *WALink;typedef struct _ChWtAcc{ /* attached to StreamElem */ Vector c; /* array[1..M] of mixture weight */ float occ; /* occ for states sharing this pdf */ long nInc; /* num times this acc incremented */ WALink next; /* chain for wt accs */} ChWtAcc;static WALink ***wtStore; /* array [1..nPhyHmms][2..nStates-1][1..nStreams] of WALink *//* CreateWtStore: Create store for linked lists of WALink, dimensions [1..nPhyHmms][2..nStates-1][1..nStreams] */void CreateWtStore(MemHeap *x){ int m,n,s; wtStore = (WALink ***) New(x,nPhyHmms*sizeof(WALink **)); wtStore--; for (m=1;m<=nPhyHmms;m++){ wtStore[m]=(WALink **) New(x,(maxStates-2)*sizeof(WALink *)); wtStore[m]-=2; for (n=2;n<maxStates;n++){ wtStore[m][n]=(WALink *)New(x,nStreams*sizeof(WALink)); wtStore[m][n]--; for (s=1;s<=nStreams;s++) wtStore[m][n][s] = NULL; } }}/* CreateChWtAcc: create an accumulator for mixture weights */WALink CreateChWtAcc(MemHeap *x, int M){ WALink wa; wa = (WALink) New(x,sizeof(ChWtAcc)); wa->c = CreateVector(x,M); ZeroVector(wa->c); wa->occ = 0.0; wa->nInc = 0; wa->next = NULL; return wa;}/* MakeWtAccLists: Copy info from WtAcc to WALink and add WALink to wtStore, Zero WtAcc afterwards */void MakeWtAccLists(){ int ix,n,s,i,nMix; HMMScanState hss; HLink hmm; WALink *w; StateElem *se; StreamElem *ste; WtAcc *wa; NewHMMScan(&hset,&hss); ix=1; do { hmm = hss.hmm; for (i=2,se = hmm->svec+2; i<hmm->numStates;i++,se++) for (s=1,ste = se->info->pdf+1; s<=nStreams; s++,ste++){ w = &(wtStore[ix][i][s]); n = 0; while (*w != NULL){ ++n; w = &((*w)->next); } nMix = (hset.hsKind==TIEDHS) ? hset.tmRecs[s].nMix : ste->nMix; (*w) = CreateChWtAcc(&wtAccStack, nMix); wa = (WtAcc *)ste->hook; CopyVector(wa->c,(*w)->c); (*w)->occ = wa->occ; wa->occ = 0; ZeroVector(wa->c); } ix++; } while (GoNextHMM(&hss)); EndHMMScan(&hss);}/* AttachWtAccLists: Replace WtAccs in HMMSet with lists of WALink */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -