📄 hsmooth.c
字号:
void AttachWtAccLists(){ int ix,s,i; HMMScanState hss; HLink hmm; StateElem *se; StreamElem *ste; 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++){ ste->hook = wtStore[ix][i][s]; /* Note that this is known and tolerable memory leak */ } ix++; } while (GoNextHMM(&hss)); EndHMMScan(&hss);}/* -------------------------- Trace Support ----------------------- *//* PrintLog: print a log value */void PrintLog(LogDouble x){ if (x<LSMALL) printf(" LZERO"); else printf("%12.5f",x);}/* -------------------------- Initialisation ----------------------- */void Initialise(char *hmmListFn){ /* Stacks for global structures requiring memory allocation */ CreateHeap(&aSetStack,"ASetStore", MSTAK, 1, 0.0, 1000, 1000); CreateHeap(&sSetStack,"SSetStore", MSTAK, 1, 0.0, 1000, 1000); CreateHeap(&wsStack,"WsStore", MSTAK, 1, 0.0, 1000, 1000); CreateHeap(&labIdStack,"LabIdStore", MSTAK, 1, 0.0, 1000, 1000); CreateHeap(&wtAccStack,"WtAccStore", MSTAK, 1, 0.0, 1000, 1000); /* Load HMMs and init HMMSet related global variables */ if(MakeHMMSet( &hset, hmmListFn )<SUCCESS) HError(2429,"Initialise: MakeHMMSet failed"); if(LoadHMMSet( &hset,hmmDir,newExt)<SUCCESS) HError(2429,"Initialise: LoadHMMSet failed"); AttachAccs(&hset, &gstack,uFlags); ZeroAccs(&hset,uFlags); nPhyHmms = hset.numPhyHMM; nLogHmms = hset.numLogHMM; vSize = hset.vecSize; nStreams = hset.swidth[0]; maxMixes = MaxMixInSet(&hset); maxStates = MaxStatesInSet(&hset); hsKind = hset.hsKind; /* Store for mix weights accs from each input acc file */ CreateWtStore(&wtAccStack); if ((hsKind != TIEDHS) && (hsKind != DISCRETEHS)) HError(2421,"Initialise: HMM's must be full Tied Mixture or Discrete"); if (trace&T_TOP) { printf("HSmooth Updating: "); if (uFlags&UPTRANS) printf("Transitions "); if (uFlags&UPMEANS) printf("Means "); if (uFlags&UPVARS) printf("Variances "); if (uFlags&UPMIXES && maxMixes>1) printf("MixWeights "); printf("\n "); printf(" Max Steps: %d, Epsilon : %f, Max Mixes: %d\n", maxStep,epsilon,maxMixes); printf("%d Logical/%d Physical Models Loaded, VecSize=%d\n",nLogHmms,nPhyHmms,vSize); fflush(stdout); } SetVFloor( &hset, vFloor, minVar); aSet=(HLink *)New(&aSetStack, nPhyHmms*sizeof(HLink)); --aSet; sSet=(StreamElem **)New(&sSetStack, nPhyHmms*sizeof(StreamElem *)); --sSet; }/* ------------------- Statistics Reporting -------------------- *//* PrintStats: for given hmm */void PrintStats(FILE *f, int n, HLink hmm, int numEgs){ WtAcc *wa; char buf[MAXSTRLEN]; StateInfo *si; int i,N; N = hmm->numStates; ReWriteString(HMMPhysName(&hset,hmm),buf,DBL_QUOTE); fprintf(f,"%4d %14s %4d ",n,buf,numEgs); for (i=2;i<N;i++) { si = hmm->svec[i].info; wa = (WtAcc *)((si->pdf+1)->hook); fprintf(f," %10f",wa->occ); } fprintf(f,"\n");}/* StatReport: print statistics report */void StatReport(void){ HMMScanState hss; HLink hmm; FILE *f; int px; if ((f = fopen(statFN,"w")) == NULL){ HError(2311,"StatReport: Unable to open stats file %s",statFN); return; } NewHMMScan(&hset,&hss); px=1; do { hmm = hss.hmm; PrintStats(f,px,hmm,(int)hmm->hook); px++; } while (GoNextHMM(&hss)); EndHMMScan(&hss); fclose(f);}/* ----------------- Deleted Interpolation -------------------- *//* CreateWStore - create the global weight vectors */void CreateWStore(void){ long size; int i; size = (nBlk+1)*sizeof(Vector); wbar = (Vector *)New(&wsStack, size); wcd = (Vector *)New(&wsStack, size); for (i=0; i<=nBlk; i++){ wbar[i] = CreateVector(&wsStack, maxMixes); wcd[i] = CreateVector(&wsStack, maxMixes); }}/* CreateMonoList: set nPhones and create list of monophones */void CreateMonoList(void){ int i,j; Boolean found; LabId list[MAXMONOPHONES], id; char buf[255]; MLink q; nPhones = 0; for (i=0; i<MACHASHSIZE; i++) for (q=hset.mtab[i]; q!=NULL; q=q->next) if (q->type=='l'){ strcpy(buf,q->id->name); TriStrip(buf); id = GetLabId(buf,TRUE); found = FALSE; for (j=0; j<nPhones; j++) if (list[j] == id) { found = TRUE; break; } if (!found){ if (nPhones>=MAXMONOPHONES) HError(2422,"CreateMonoList: Too many monophones"); list[nPhones++] = id; } } monophones = (LabId *)New(&labIdStack, nPhones*sizeof(LabId)); for (i=0; i<nPhones; i++) monophones[i] = list[i]; --monophones;}/* LoadASet: set aSize, load the allophone set of x and return the number of states in each model (all allophones must have the same number of states) */int LoadASet(LabId x){ int i,N=0; HLink hmm; MLink q; LabId id; char *aid,buf[255]; aSize = 0; for (i=0; i<MACHASHSIZE; i++) for (q=hset.mtab[i]; q!=NULL; q=q->next) if (q->type=='l'){ aid = q->id->name; strcpy(buf,aid); TriStrip(buf); id = GetLabId(buf,FALSE); if (id==x){ if (trace&T_OPT) printf(" loading allophone %s\n",aid); hmm = (HLink)q->structure; if (hmm->numStates>0) { if (N==0) N = hmm->numStates; else if (N != hmm->numStates) HError(2423,"LoadASet: allophones must have same num states %d vs %d", N, hmm->numStates); hmm->numStates = -N; aSet[++aSize] = hmm; } } } for (i=1; i<=aSize; i++) aSet[i]->numStates = N; return N;}/* LoadSSet: load sSet with pointers to state i, stream s of each allophone in the aSet array */void LoadSSet(int i, int s){ int k; for (k=1; k<=aSize; k++) sSet[k] = aSet[k]->svec[i].info->pdf+s;}/* SumWtChain: sum chain of accs whose head is wa excluding dBlk, put result in v and return occ sum */float SumWtChain(WALink wa, Vector v, int dBlk, int M){ float occ = 0.0; Vector x; int blk=0,i; while (wa != NULL) { ++blk; if (blk != dBlk) { occ += wa->occ; x = wa->c; for (i=1; i<=M; i++) v[i] += x[i]; } wa = wa->next; } return occ;}/* CalcWBar: store context independent weights in wb from all blocks across all models excluding deleted block dblk */void CalcWBar(Vector wb, int dBlk, int M){ int i; WALink wa; float occ = 0.0; ZeroVector(wb); for (i=1; i<=aSize; i++){ wa = (WALink)sSet[i]->hook; occ += SumWtChain(wa,wb,dBlk,M); } if (occ==0.0) ZeroVector(wb); else for (i=1; i<=M; i++) wb[i] /= occ;}/* CalcWCd: store context dependent weights in wc using all blocks of stream ste except the deleted block dBlk */void CalcWCd(Vector wc, int dBlk, StreamElem *ste, int M){ WALink wa; float occ; int i; ZeroVector(wc); wa = (WALink)ste->hook; occ = SumWtChain(wa,wc,dBlk,M); if (occ==0.0) ZeroVector(wc); else for (i=1; i<=M; i++) wc[i] /= occ;}/* SmoothWtAcc: change 1st WtAcc to l*wcd[0] + (1.0-l)*wbar[0] */void SmoothWtAcc(StreamElem *ste, float l, int M){ int i; WALink wa; wa = (WALink)ste->hook; for (i=1; i<=M; i++) wa->c[i] = l*wcd[0][i] + (1.0-l)*wbar[0][i]; wa->occ = 1.0;}/* D: return derivative of log likelihood */float D(float l, WALink wa, int M){ int n,i; double sum = 0.0; double wni, wbni,y; Vector wn, wbn, x; for (n=1; n<=nBlk; n++){ x = wa->c; wn = wcd[n]; wbn = wbar[n]; for (i=1; i<=M; i++){ wni = wn[i]; wbni = wbn[i]; y = l*wni + (1.0-l)*wbni; if (y>0.0) sum += x[i] * ((wni - wbni) / y); } wa = wa->next; } return sum;}/* LambdaOpt: perform binary chop optimisation */float LambdaOpt(StreamElem *ste, int M){ float l=0.0, r=1.0, m=0.5, Dm; WALink wa; int n; wa = (WALink)ste->hook; if (D(0.0,wa,M) <= 0.0) return 0.0; if (D(1.0,wa,M) >= 0.0) return 1.0; for (n = 1; n<=maxStep; n++) { m = (l+r)/2.0; Dm = D(m,wa,M); if (trace&T_OPT) printf(" step %d: l=%.3f r=%.3f m=%.3f D(m)=%e\n",n,l,r,m,Dm); if (fabs(Dm) < epsilon) return m; if (Dm > 0 ) l = m; else r = m; } return m;}/* Interpolate: top level of deleted interpolation */void Interpolate(void){ LabId x; int i,N,p,s,b,j,M=0; float l;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -