📄 hinit.c
字号:
/* ----------------------------------------------------------- *//* *//* ___ *//* |_| | |_/ SPEECH *//* | | | | \ RECOGNITION *//* ========= SOFTWARE */ /* *//* *//* ----------------------------------------------------------- *//* developed at: *//* *//* Speech Vision and Robotics group *//* Cambridge University Engineering Department *//* http://svr-www.eng.cam.ac.uk/ *//* *//* Entropic Cambridge Research Laboratory *//* (now part of Microsoft) *//* *//* ----------------------------------------------------------- *//* Copyright: Microsoft Corporation *//* 1995-2000 Redmond, Washington USA *//* http://www.microsoft.com *//* *//* 2002 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: HInit.c: HMM initialisation program *//* ----------------------------------------------------------- */char *hinit_version = "!HVER!HInit: 3.3 [CUED 28/04/05]";char *hinit_vc_id = "$Id: HInit.c,v 1.1.1.1 2005/05/12 10:52:53 jal58 Exp $";/* This program is used to initialise (or tune) a single hidden Markov model using a segmental K-means algorithm. Only means, variances, mixture weights and transition probs can be estimated, stream weights are left unchanged.*//* Trace Flags */ #define T_TOP 0001 /* Top level tracing */#define T_LD0 0002 /* File Loading */#define T_LD1 0004 /* + segments within each file */#define T_UNI 0010 /* Uniform segmentation */#define T_VIT 0020 /* Detailed Viterbi Alignment */#define T_ALN 0040 /* State Alignment */#define T_MIX 0100 /* Mixture Component Alignment */#define T_CNT 0200 /* Count Updating */#define T_OBP 0400 /* Trace output probs */#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 "HUtil.h"#include "HTrain.h"/* Global Settings */static char * segLab = NULL; /* segment label if any */static LabId segId = NULL; /* and its id */static char * labDir = NULL; /* label file directory */static char * labExt = "lab"; /* label file extension */static int maxIter = 20; /* max iterations in param estimation */static float epsilon = 1.0E-4; /* convergence criterion */static float minVar = 1.0E-2; /* minimum variance */static float mixWeightFloor=0.0; /*Floor for mixture/discrete prob weights*/static int minSeg = 3; /* min segments to train a model */static Boolean newModel = TRUE; /* enable initial uniform segmentation */static Boolean saveBinary = FALSE; /* save output in binary */static Boolean firstTime = TRUE; /* Flag used to enable InitSegStore */static FileFormat dff=UNDEFF; /* data file format */static FileFormat lff=UNDEFF; /* label file format */static char *hmmfn; /* HMM definition file name (& part dir)*/static char *outfn=NULL; /* output HMM file name (name only) */static char *outDir=NULL; /* HMM output directory */static UPDSet uFlags = (UPDSet) (UPMEANS|UPVARS|UPMIXES|UPTRANS); /* update flags */static int trace = 0; /* Trace level */static ConfParam *cParm[MAXGLOBS]; /* configuration parameters */static int nParm = 0; /* total num params */static Vector vFloor[SMAX]; /* variance floor - default is all zero *//* Major Data Structures plus related global vars*/static HMMSet hset; /* The current unitary hmm set */static MLink macroLink; /* Access to macro in HMMSet */static HLink hmmLink; /* link to the hmm itself */static int maxMixInS[SMAX]; /* array[1..swidth[0]] of max mixes */static int nStates; /* number of states in hmm */static int nStreams; /* number of streams in hmm */static SegStore segStore; /* Storage for data segments */static MemHeap segmentStack; /* Used by segStore */static MemHeap sequenceStack; /* For storage of sequences */static MemHeap clustSetStack; /* For storage of cluster sets */static MemHeap transStack; /* For storage of transcription */static MemHeap traceBackStack; /* For storage of traceBack info */static MemHeap bufferStack; /* For storage of buffer */static ParmBuf pbuf; /* Currently input parm buffer *//* Storage for Viterbi Decoding */static Vector thisP,lastP; /* Columns of log probabilities */static short **traceBack; /* array[1..segLen][2..numStates-1] */ /* ---------------- Process Conf File & Command Line ----------------- *//* SetConfParms: set conf parms relevant to HInit */void SetConfParms(void){ int i; nParm = GetConfig("HINIT", TRUE, cParm, MAXGLOBS); if (nParm>0) { if (GetConfInt(cParm,nParm,"TRACE",&i)) trace = i; }}void ReportUsage(void){ printf("\nUSAGE: HInit [options] hmmFile trainFiles...\n\n"); printf(" Option Default\n\n"); printf(" -e f Set convergence factor epsilon 1.0E-4\n"); printf(" -i N Set max iterations to N 20\n"); printf(" -l s Set segment label to s none\n"); printf(" -m N Set min segments needed 3\n"); printf(" -n Update hmm (suppress uniform seg) off\n"); printf(" -o fn Store new hmm def in fn (name only) outDir/srcfn\n"); printf(" -u mvwt Update m)eans v)ars w)ghts t)rans mvwt\n"); printf(" -v f Set minimum variance to f 1.0E-2\n"); printf(" -w f set mix wt/disc prob floor to f 0.0\n"); PrintStdOpts("BFGHILMX"); printf("\n\n");}/* ------------------------- Set Update Flags ------------------------- */void SetuFlags(void){ char *s; s=GetStrArg(); uFlags=(UPDSet) 0; while (*s != '\0') switch (*s++) { case 'm': uFlags = (UPDSet) (uFlags+UPMEANS); break; case 'v': uFlags = (UPDSet) (uFlags+UPVARS); break; case 'w': uFlags = (UPDSet) (uFlags+UPMIXES); break; case 't': uFlags = (UPDSet) (uFlags+UPTRANS); break; default: HError(2120,"SetuFlags: Unknown update flag %c",*s); break; }}int main(int argc, char *argv[]){ char *datafn, *s; int nSeg; void Initialise(void); void LoadFile(char *fn); void EstimateModel(void); void SaveModel(char *outfn); if(InitShell(argc,argv,hinit_version,hinit_vc_id)<SUCCESS) HError(2100,"HInit: InitShell failed"); InitMem(); InitLabel(); InitMath(); InitSigP(); InitWave(); InitAudio(); InitVQ(); InitModel(); if(InitParm()<SUCCESS) HError(2100,"HInit: InitParm failed"); InitTrain(); InitUtil(); if (!InfoPrinted() && NumArgs() == 0) ReportUsage(); if (NumArgs() == 0) Exit(0); SetConfParms(); CreateHMMSet(&hset,&gstack,FALSE); while (NextArg() == SWITCHARG) { s = GetSwtArg(); if (strlen(s)!=1) HError(2119,"HInit: Bad switch %s; must be single letter",s); switch(s[0]){ case 'e': epsilon = GetChkedFlt(0.0,1.0,s); break; case 'i': maxIter = GetChkedInt(0,100,s); break; case 'l': if (NextArg() != STRINGARG) HError(2119,"HInit: Segment label expected"); segLab = GetStrArg(); break; case 'm': minSeg = GetChkedInt(1,1000,s); break; case 'n': newModel = FALSE; break; case 'o': outfn = 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 'B': saveBinary = TRUE; break; case 'F': if (NextArg() != STRINGARG) HError(2119,"HInit: Data File format expected"); if((dff = Str2Format(GetStrArg())) == ALIEN) HError(-2189,"HInit: Warning ALIEN Data file format set"); break; case 'G': if (NextArg() != STRINGARG) HError(2119,"HInit: Label File format expected"); if((lff = Str2Format(GetStrArg())) == ALIEN) HError(-2189,"HInit: Warning ALIEN Label file format set"); break; case 'H': if (NextArg() != STRINGARG) HError(2119,"HInit: HMM macro file name expected"); AddMMF(&hset,GetStrArg()); break; case 'I': if (NextArg() != STRINGARG) HError(2119,"HInit: MLF file name expected"); LoadMasterFile(GetStrArg()); break; case 'L': if (NextArg()!=STRINGARG) HError(2119,"HInit: Label file directory expected"); labDir = GetStrArg(); break; case 'M': if (NextArg()!=STRINGARG) HError(2119,"HInit: Output macro file directory expected"); outDir = GetStrArg(); break; case 'T': if (NextArg() != INTARG) HError(2119,"HInit: Trace value expected"); trace = GetChkedInt(0,01777,s); break; case 'X': if (NextArg()!=STRINGARG) HError(2119,"HInit: Label file extension expected"); labExt = GetStrArg(); break; default: HError(2119,"HInit: Unknown switch %s",s); } } if (NextArg()!=STRINGARG) HError(2119,"HInit: source HMM file name expected"); hmmfn = GetStrArg(); Initialise(); do { if (NextArg()!=STRINGARG) HError(2119,"HInit: training data file name expected"); datafn = GetStrArg(); LoadFile(datafn); } while (NumArgs()>0); nSeg = NumSegs(segStore); if (nSeg < minSeg) HError(2121,"HInit: Too Few Observation Sequences [%d]",nSeg); if (trace&T_TOP) { printf("%d Observation Sequences Loaded\n",nSeg); fflush(stdout); } EstimateModel(); SaveModel(outfn); if (trace&T_TOP) printf("Output written to directory %s\n", outDir==NULL?"current":outDir); Exit(0); return (0); /* never reached -- make compiler happy */}/* ------------------------ Initialisation ----------------------- *//* PrintInitialInfo: print a header of program settings */void PrintInitialInfo(void){ if (newModel) printf("Initialising "); else printf("Updating "); printf("HMM %s . . . \n",hmmfn); PrintHMMProfile(stdout, hmmLink); printf(" SegLab : %s\n",(segLab==NULL)?"NONE":segLab); printf(" maxIter : %d\n",maxIter); printf(" epsilon : %f\n",epsilon); printf(" minSeg : %d\n",minSeg); printf(" Updating : "); if (uFlags&UPMEANS) printf("Means "); if (uFlags&UPVARS) printf("Variances "); if (uFlags&UPMIXES) printf("MixWeights/DProbs "); if (uFlags&UPTRANS) printf("TransProbs"); printf("\n\n"); printf(" - system is "); switch (hset.hsKind){ case PLAINHS: printf("PLAIN\n"); break; case SHAREDHS: printf("SHARED\n"); break; case TIEDHS: printf("TIED\n"); break; case DISCRETEHS: printf("DISCRETE\n"); break; } fflush(stdout);}/* Initialise: load hmm and initialise global data structures */void Initialise(void){ LabId hmmId; char base[MAXSTRLEN]; char path[MAXSTRLEN]; char ext[MAXSTRLEN]; int s; /* Stacks for global structures requiring memory allocation */ CreateHeap(&segmentStack,"SegStore", MSTAK, 1, 0.0, 100000, LONG_MAX); CreateHeap(&sequenceStack,"SeqStore", MSTAK, 1, 0.0, 1000, 1000); CreateHeap(&clustSetStack,"ClustSetStore", MSTAK, 1, 0.0, 1000, 1000); CreateHeap(&transStack,"TransStore", MSTAK, 1, 0.0, 1000, 1000); CreateHeap(&traceBackStack,"TraceBackStore", MSTAK, 1, 0.0, 1000, 1000); CreateHeap(&bufferStack,"BufferStore", MSTAK, 1, 0.0, 1000, 1000); /* Load HMM def */ if(MakeOneHMM( &hset, BaseOf(hmmfn,base))<SUCCESS) HError(2128,"Initialise: MakeOneHMM failed"); if(LoadHMMSet( &hset,PathOf(hmmfn,path),ExtnOf(hmmfn,ext))<SUCCESS) HError(2128,"Initialise: LoadHMMSet failed"); SetParmHMMSet(&hset); if ((hset.hsKind==DISCRETEHS)||(hset.hsKind==TIEDHS)) uFlags = (UPDSet) (uFlags & (~(UPMEANS|UPVARS))); AttachAccs(&hset, &gstack, uFlags); /* Get a pointer to the physical HMM and set related globals */ hmmId = GetLabId(base,FALSE); macroLink = FindMacroName(&hset,'h',hmmId); hmmLink = (HLink)macroLink->structure; nStates = hmmLink->numStates; nStreams = hset.swidth[0]; for(s=1; s<=nStreams; s++) maxMixInS[s] = MaxMixInS(hmmLink, s); SetVFloor( &hset, vFloor, minVar); if(segLab != NULL) segId = GetLabId(segLab,TRUE); if(trace>0) PrintInitialInfo(); thisP = CreateVector(&gstack,nStates); lastP = CreateVector(&gstack,nStates);}/* InitSegStore : Initialise segStore for particular observation */void InitSegStore(BufferInfo *info){ Observation obs; Boolean eSep; SetStreamWidths(info->tgtPK,info->tgtVecSize,hset.swidth,&eSep); obs = MakeObservation(&gstack,hset.swidth,info->tgtPK, hset.hsKind==DISCRETEHS,eSep); segStore = CreateSegStore(&segmentStack,obs,10); firstTime = FALSE;}/* ------------------------ Data Loading ----------------------- *//* CheckData: check data file consistent with HMM definition */void CheckData(char *fn, BufferInfo info) { char tpk[80]; char mpk[80]; if (info.tgtPK != hset.pkind) HError(2150,"CheckData: Parameterisation in %s[%s] is incompatible with hmm %s[%s]", fn,ParmKind2Str(info.tgtPK,tpk),hmmfn,ParmKind2Str(hset.pkind,mpk)); if (info.tgtVecSize!=hset.vecSize) HError(2150,"CheckData: Vector size in %s[%d] is incompatible with hmm %s[%d]", fn,info.tgtVecSize,hmmfn,hset.vecSize);}/* LoadFile: load whole file or segments into segStore */void LoadFile(char *fn){ BufferInfo info; char labfn[80]; Transcription *trans; long segStIdx,segEnIdx; static int segIdx=1; /* Between call handle on latest seg in segStore */ static int prevSegIdx=1; HTime tStart, tEnd; int i,k,s,ncas,nObs=0,segLen; LLink p; Observation obs; if((pbuf=OpenBuffer(&bufferStack, fn, 10, dff, FALSE_dup, FALSE_dup))==NULL) HError(2150,"LoadFile: Config parameters invalid"); GetBufferInfo(pbuf,&info); CheckData(fn,info); if (firstTime) InitSegStore(&info); if (segId == NULL) { /* load whole parameter file */ nObs = ObsInBuffer(pbuf); tStart = 0.0; tEnd = (info.tgtSampRate * nObs); LoadSegment(segStore, tStart, tEnd, pbuf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -