📄 herest.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-2004 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: HERest.c: Embedded B-W ReEstimation *//* ----------------------------------------------------------- */char *herest_version = "!HVER!HERest: 3.3 [CUED 28/04/05]";char *herest_vc_id = "$Id: HERest.c,v 1.3 2005/07/22 10:17:13 mjfg Exp $";/* This program is used to perform a single reestimation of the parameters of a set of HMMs using Baum-Welch. Training data consists of one or more utterances each of which has a transcription in the form of a standard label file (segment boundaries are ignored). For each training utterance, a composite model is effectively synthesised by concatenating the phoneme models given by the transcription. Each phone model has the usual set of accumulators allocated to it, these are updated by performing a standard B-W pass over each training utterance using the composite model. This program supports arbitrary parameter tying and multiple data streams. Added in V1.4 - support for tee-Models ie HMMs with a non- zero transition from entry to exit states. In v2.2 most of the core functionality has been moved to the library module HFB*/#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"#include "HAdapt.h"#include "HMap.h"#include "HFB.h"/* Trace Flags */#define T_TOP 0001 /* Top level tracing */#define T_MAP 0002 /* logical/physical hmm map */#define T_UPD 0004 /* Model updates *//* possible values of updateMode */#define UPMODE_DUMP 1#define UPMODE_UPDATE 2#define UPMODE_BOTH 3/* Global Settings */static char * labDir = NULL; /* label (transcription) file directory */static char * labExt = "lab"; /* label file extension */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 UPDSet uFlags = (UPDSet) (UPMEANS|UPVARS|UPTRANS|UPMIXES); /* update flags */static int parMode = -1; /* enable one of the // modes */static Boolean stats = FALSE; /* enable statistics reports */static char * mmfFn = NULL; /* output MMF file, if any */static int trace = 0; /* Trace level */static Boolean saveBinary = FALSE; /* save output in binary */static Boolean ldBinary = TRUE; /* load/dump in binary */static FileFormat dff=UNDEFF; /* data file format */static FileFormat lff=UNDEFF; /* label file format */static int updateMode = UPMODE_UPDATE; /* dump summed accs, update models or do both? */static ConfParam *cParm[MAXGLOBS]; /* configuration parameters */static int nParm = 0; /* total num params */static Boolean al_hmmUsed = FALSE; /* Set for 2-model ReEstimation */static char al_hmmDir[MAXFNAMELEN]; /* dir to look for alignment hmm defs */static char al_hmmExt[MAXSTRLEN]; /* alignment hmm def file extension */static char al_hmmMMF[MAXFNAMELEN]; /* alignment hmm MMF */static char al_hmmLst[MAXFNAMELEN]; /* alignment hmm list */static char up_hmmMMF[MAXFNAMELEN]; /* alignment hmm list */static HMMSet al_hset ; /* Option 2nd set of models for alignment *//* Global Data Structures - valid for all training utterances */static LogDouble pruneInit = NOPRUNE; /* pruning threshold initially */static LogDouble pruneInc = 0.0; /* pruning threshold increment */static LogDouble pruneLim = NOPRUNE; /* pruning threshold limit */static float minFrwdP = NOPRUNE; /* mix prune threshold */static Boolean firstTime = TRUE; /* Flag used to enable creation of ot */static Boolean twoDataFiles = FALSE; /* Enables creation of ot2 for FB training using two data files */static int totalT=0; /* total number of frames in training data */static LogDouble totalPr=0; /* total log prob upto current utterance */static Vector vFloor[SMAX]; /* variance floor - default is all zero */static MemHeap hmmStack; /*For Storage of all dynamic structures created...*/static MemHeap uttStack;static MemHeap fbInfoStack;static MemHeap accStack;/* information about transforms */static XFInfo xfInfo;static int maxSpUtt = 0;static float varFloorPercent = 0;/* ------------------ Process Command Line -------------------------- */ /* SetConfParms: set conf parms relevant to HCompV */void SetConfParms(void){ int i; Boolean b; double f; char buf[MAXSTRLEN]; nParm = GetConfig("HEREST", TRUE, cParm, MAXGLOBS); if (nParm>0) { if (GetConfInt(cParm,nParm,"TRACE",&i)) trace = i; if (GetConfFlt(cParm,nParm,"VARFLOORPERCENTILE",&f)) varFloorPercent = f; if (GetConfBool(cParm,nParm,"SAVEBINARY",&b)) saveBinary = b; if (GetConfBool(cParm,nParm,"BINARYACCFORMAT",&b)) ldBinary = b; /* 2-model reestimation alignment model set */ if (GetConfStr(cParm,nParm,"ALIGNMODELMMF",buf)) { strcpy(al_hmmMMF,buf); al_hmmUsed = TRUE; } if (GetConfStr(cParm,nParm,"ALIGNHMMLIST",buf)) { strcpy(al_hmmLst,buf); al_hmmUsed = TRUE; } /* allow multiple individual model files */ if (GetConfStr(cParm,nParm,"ALIGNMODELDIR",buf)) { strcpy(al_hmmDir,buf); al_hmmUsed = TRUE; } if (GetConfStr(cParm,nParm,"ALIGNMODELEXT",buf)) { strcpy(al_hmmExt,buf); al_hmmUsed = TRUE; } if (GetConfStr(cParm,nParm,"ALIGNXFORMEXT",buf)) { xfInfo.alXFormExt = CopyString(&hmmStack,buf); } if (GetConfStr(cParm,nParm,"ALIGNXFORMDIR",buf)) { xfInfo.alXFormDir = CopyString(&hmmStack,buf); } if (GetConfStr(cParm,nParm,"INXFORMMASK",buf)) { xfInfo.inSpkrPat = CopyString(&hmmStack,buf); } if (GetConfStr(cParm,nParm,"PAXFORMMASK",buf)) { xfInfo.paSpkrPat = CopyString(&hmmStack,buf); } if (GetConfStr(cParm,nParm,"UPDATEMODE",buf)) { if (!strcmp (buf, "DUMP")) updateMode = UPMODE_DUMP; else if (!strcmp (buf, "UPDATE")) updateMode = UPMODE_UPDATE; else if (!strcmp (buf, "BOTH")) updateMode = UPMODE_BOTH; else HError(2319, "Unknown UPDATEMODE specified (must be DUMP, UPDATE or BOTH)"); } }}void ReportUsage(void){ printf("\nUSAGE: HERest [options] hmmList dataFiles...\n\n"); printf(" Option Default\n\n"); printf(" -a Use an input linear transform off\n"); printf(" -c f Mixture pruning threshold 10.0\n"); printf(" -d s dir to find hmm definitions current\n"); printf(" -h s set output speaker name pattern *.%%%%%%\n"); printf(" to s, optionally set input and parent patterns\n"); printf(" -l N set max files per speaker off\n"); printf(" -m N set min examples needed per model 3\n"); printf(" -o s extension for new hmm files as src\n"); printf(" -p N set parallel mode to N off\n"); printf(" -r Enable Single Pass Training... \n"); printf(" ...using two parameterisations off\n"); printf(" -s s print statistics to file s off\n"); printf(" -t f [i l] set pruning to f [inc limit] inf\n"); printf(" -u tmvwap update t)rans m)eans v)ars w)ghts tmvw\n"); printf(" a)daptation xform p)rior used \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"); printf(" -z s Save all xforms to TMF file s TMF\n"); PrintStdOpts("BEFGHIJKLMSTX"); 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; case 'a': uFlags = (UPDSet) (uFlags+UPXFORM); break; case 'p': uFlags = (UPDSet) (uFlags+UPMAP); break; default: HError(2320,"SetuFlags: Unknown update flag %c",*s); break; }}/* ScriptWord: return next word from script */char *ScriptWord(FILE *script, char *scriptBuf){ int ch,qch,i; i=0; ch=' '; while (isspace(ch)) ch = fgetc(script); if (ch==EOF) { scriptBuf=NULL; return NULL; } if (ch=='\'' || ch=='"'){ qch = ch; ch = fgetc(script); while (ch != qch && ch != EOF) { scriptBuf[i++] = ch; ch = fgetc(script); } if (ch==EOF) HError(5051,"ScriptWord: Closing quote missing in script file"); } else { do { scriptBuf[i++] = ch; ch = fgetc(script); }while (!isspace(ch) && ch != EOF); } scriptBuf[i] = '\0'; return scriptBuf;}void CheckUpdateSetUp(){ AdaptXForm *xf; xf = xfInfo.paXForm; if ((xfInfo.paXForm != NULL) && !(uFlags&UPXFORM)) { while (xf != NULL) { if (xf->xformSet->xkind != CMLLR)\ HError(999,"SAT only supported with CMLLR transforms"); xf = xf->parentXForm; } }}int main(int argc, char *argv[]){ char *datafn=NULL; char *datafn2=NULL; char *s; char *scriptFile; char datafn1[MAXSTRLEN]; char newFn[MAXSTRLEN]; FILE *f; UttInfo *utt; /* utterance information storage */ FBInfo *fbInfo; /* forward-backward information storage */ HMMSet hset; /* Set of HMMs to be re-estimated */ Source src; float tmpFlt; int tmpInt; int numUtt,spUtt=0; void Initialise(FBInfo *fbInfo, MemHeap *x, HMMSet *hset, char *hmmListFn); void DoForwardBackward(FBInfo *fbInfo, UttInfo *utt, char *datafn, char *datafn2); void UpdateModels(HMMSet *hset, ParmBuf pbuf2); void StatReport(HMMSet *hset); if(InitShell(argc,argv,herest_version,herest_vc_id)<SUCCESS) HError(2300,"HERest: InitShell failed"); InitMem(); InitMath(); InitSigP(); InitAudio(); InitWave(); InitVQ(); InitLabel(); InitModel(); if(InitParm()<SUCCESS) HError(2300,"HERest: InitParm failed"); InitTrain(); InitUtil(); InitFB(); InitAdapt(&xfInfo); InitMap(); if (!InfoPrinted() && NumArgs() == 0) ReportUsage(); if (NumArgs() == 0) Exit(0); al_hmmDir[0] = '\0'; al_hmmExt[0] = '\0'; al_hmmMMF[0] = '\0'; al_hmmLst[0] = '\0'; up_hmmMMF[0] = '\0'; CreateHeap(&hmmStack,"HmmStore", MSTAK, 1, 1.0, 50000, 500000); SetConfParms(); CreateHMMSet(&hset,&hmmStack,TRUE); CreateHeap(&uttStack, "uttStore", MSTAK, 1, 0.5, 100, 1000); utt = (UttInfo *) New(&uttStack, sizeof(UttInfo)); CreateHeap(&fbInfoStack, "FBInfoStore", MSTAK, 1, 0.5, 100 , 1000 ); fbInfo = (FBInfo *) New(&fbInfoStack, sizeof(FBInfo)); CreateHeap(&accStack, "accStore", MSTAK, 1, 1.0, 50000, 500000); while (NextArg() == SWITCHARG) { s = GetSwtArg(); if (strlen(s)!=1) HError(2319,"HERest: Bad switch %s; must be single letter",s); switch(s[0]){ case 'b': if (NextArg()!=STRINGARG) HError(2319,"HERest: script file expected"); scriptFile = GetStrArg(); break; case 'c': minFrwdP = GetChkedFlt(0.0,1000.0,s); break; case 'd': if (NextArg()!=STRINGARG) HError(2319,"HERest: HMM definition directory expected"); hmmDir = GetStrArg(); break; case 'm': minEgs = GetChkedInt(0,1000,s); break; case 'o': if (NextArg()!=STRINGARG) HError(2319,"HERest: HMM file extension expected"); newExt = GetStrArg(); break; case 'p': parMode = GetChkedInt(0,500,s); break; case 'r': twoDataFiles = TRUE; break; case 's': stats = TRUE; if (NextArg()!=STRINGARG) HError(2319,"HERest: Stats file name expected"); statFN = GetStrArg(); break; case 't': pruneInit = GetChkedFlt(0.0,1.0E20,s); if (NextArg()==FLOATARG || NextArg()==INTARG) { pruneInc = GetChkedFlt(0.0,1.0E20,s); pruneLim = GetChkedFlt(0.0,1.0E20,s); } else { pruneInc = 0.0; pruneLim = pruneInit ; } 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(2319,"HERest: HMM file extension expected"); hmmExt = GetStrArg(); break; case 'B': saveBinary=TRUE; break; case 'F': if (NextArg() != STRINGARG) HError(2319,"HERest: Data File format expected"); if((dff = Str2Format(GetStrArg())) == ALIEN) HError(-2389,"HERest: Warning ALIEN Data file format set"); break; case 'G': if (NextArg() != STRINGARG) HError(2319,"HERest: Label File format expected"); if((lff = Str2Format(GetStrArg())) == ALIEN) HError(-2389,"HERest: Warning ALIEN Label file format set"); break; case 'H': if (NextArg() != STRINGARG) HError(2319,"HERest: HMM macro file name expected"); strcpy(up_hmmMMF,GetStrArg()); AddMMF(&hset,up_hmmMMF); break; case 'I': if (NextArg() != STRINGARG) HError(2319,"HERest: MLF file name expected"); LoadMasterFile(GetStrArg()); break; case 'L': if (NextArg()!=STRINGARG) HError(2319,"HERest: Label file directory expected"); labDir = GetStrArg(); break; case 'M': if (NextArg()!=STRINGARG) HError(2319,"HERest: Output macro file directory expected"); newDir = GetStrArg(); break; case 'T': trace = GetChkedInt(0,0100000,s); break; case 'X': if (NextArg()!=STRINGARG) HError(2319,"HERest: Label file extension expected"); labExt = GetStrArg(); break; /* additional options for transform support */ case 'a': xfInfo.useInXForm = TRUE; break; case 'h': if (NextArg()!=STRINGARG) HError(1,"Speaker name pattern expected"); xfInfo.outSpkrPat = GetStrArg(); break; case 'l': maxSpUtt = GetChkedInt(0,0100000,s); break; case 'E': if (NextArg()!=STRINGARG) HError(2319,"HERest: parent transform directory expected"); xfInfo.usePaXForm = TRUE; xfInfo.paXFormDir = GetStrArg(); if (NextArg()==STRINGARG) xfInfo.paXFormExt = GetStrArg(); if (NextArg() != SWITCHARG) HError(2319,"HERest: cannot have -E as the last option"); break; case 'J':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -