📄 hsmooth.c
字号:
StreamElem *ste; CreateWStore(); CreateMonoList(); for (p=1; p<=nPhones; p++){ x = monophones[p]; if (trace&T_INT) printf("Smoothing phone %s [%d]\n",x->name,p); N = LoadASet(x); for (i=2; i<N; i++) { if (trace&T_INT) printf(" State %d\n",i); for (s=1; s<=nStreams; s++){ if (trace&T_INT) printf(" Stream %d\n",s); LoadSSet(i,s); switch(hsKind){ case TIEDHS: M = hset.tmRecs[s].nMix; break; case DISCRETEHS: M = sSet[1]->nMix; break; } CalcWBar(wbar[0],0,M); for (b=1; b<=nBlk; b++) CalcWBar(wbar[b],b,M); for (j=1; j<=aSize; j++){ ste = sSet[j]; CalcWCd(wcd[0],0,ste,M); for (b=1; b<=nBlk; b++) CalcWCd(wcd[b],b,ste,M); l = LambdaOpt(ste,M); SmoothWtAcc(ste,l,M); if (trace&T_INT) printf(" Model %s lambda = %f\n",HMMPhysName(&hset,aSet[j]),l); } } } }} /* --------------------------- Model Update --------------------- *//* UpdateTrans: use acc values to calc new estimate for transP */void UpdateTrans(HLink hmm){ int i,j,N; float x,occi; TrAcc *ta; MLink q; q=FindMacroStruct(&hset,'h',hmm); ta = (TrAcc *) GetHook(hmm->transP); if (ta==NULL) return; /* already done */ N = hmm->numStates; for (i=1;i<N;i++) { occi = ta->occ[i]; if (occi > 0.0) for (j=2;j<=N;j++) { x = ta->tran[i][j]/occi; hmm->transP[i][j] = (x>MINLARG)?log(x):LZERO; } else HError(-2424,"UpdateTrans: Model [%s]: no transitions out of state %d",q->id->name,i); } SetHook(hmm->transP,NULL);}/* FloorMixes: apply floor to given mix set */void FloorTMMixes(Vector mixes, int M,float floor){ float sum,fsum,scale,fltWt; int m; sum = fsum = 0.0; for (m=1; m<=M; m++) { fltWt = mixes[m]; if (fltWt>floor) sum += fltWt; else { fsum += floor; mixes[m] = floor; } } if (fsum>1.0) HError(2425,"FloorMixes: Floor sum too large"); if (fsum == 0.0) return; if (sum == 0.0) HError(2428,"FloorTMMixes: No mixture weights above floor"); scale = (1.0-fsum)/sum; for (m=1; m<=M; m++){ fltWt = mixes[m]; if (fltWt>floor) mixes[m] = fltWt*scale; }}/* FloorDProbs: apply floor to given discrete prob set */void FloorDProbs(ShortVec mixes, int M, float floor){ float sum,fsum,scale,fltWt; int m; sum = fsum = 0.0; for (m=1; m<=M; m++) { fltWt = Short2DProb(mixes[m]); if (fltWt>floor) sum += fltWt; else { fsum += floor; mixes[m] = DProb2Short(floor); } } if (fsum>1.0) HError(2327,"FloorDProbs: Floor sum too large"); if (fsum == 0.0) return; if (sum == 0.0) HError(2328,"FloorDProbs: No probabilities above floor"); scale = (1.0-fsum)/sum; for (m=1; m<=M; m++){ fltWt = Short2DProb(mixes[m]); if (fltWt>floor) mixes[m] = DProb2Short(fltWt*scale); }}/* UpdateWeights: use acc values to calc new estimate of mix weights */void UpdateWeights(HLink hmm){ int i,s,m,M=0,N; float x,occi; WALink wa; StateElem *se; StreamElem *ste; MLink q; q=FindMacroStruct(&hset,'h',hmm); N = hmm->numStates; se = hmm->svec+2; for (i=2; i<N; i++,se++){ ste = se->info->pdf+1; for (s=1;s<=nStreams; s++,ste++){ wa = (WALink)ste->hook; if (wa != NULL) { switch(hsKind){ case TIEDHS: M = hset.tmRecs[s].nMix; break; case DISCRETEHS: M = ste->nMix; break; } occi = wa->occ; if (occi>0) { for (m=1; m<=M; m++){ x = wa->c[m]/occi; if (x>1.0){ if (x>1.001) HError(-2490,"UpdateWeights: Model [%s]: mix too big in %d.%d.%d",q->id->name,i,s,m); x = 1.0; } switch (hsKind){ case TIEDHS: ste->spdf.tpdf[m] = (x>MINMIX) ? x : 0; break; case DISCRETEHS: ste->spdf.dpdf[m] = (x>MINMIX) ? DProb2Short(x) :DLOGZERO; break; } } if (mixWeightFloor>0.0){ switch (hsKind){ case DISCRETEHS: FloorDProbs(ste->spdf.dpdf,M,mixWeightFloor); break; case TIEDHS: FloorTMMixes(ste->spdf.tpdf,M,mixWeightFloor); break; } } }else HError(-2427,"UpdateWeights: Model [%s]: no use of mixtures in %d.%d",q->id->name,i,s); ste->hook = NULL; } } }} /* UpdateTMMeans: use acc values to calc new estimate of means */void UpdateTMMeans(void){ int s,m,k,M,vSize; float occim; MuAcc *ma; MixPDF *mpdf; Vector mean; for (s=1;s<=nStreams;s++){ vSize = hset.swidth[s]; M = hset.tmRecs[s].nMix; for (m=1;m<=M;m++){ mpdf = hset.tmRecs[s].mixes[m]; mean = mpdf->mean; ma = (MuAcc *) GetHook(mean); if (ma != NULL){ occim = ma->occ; if (occim > 0.0) for (k=1; k<=vSize; k++) mean[k] += ma->mu[k]/occim; else HError(-2427,"UpdateTMMeans: No use of mean %d in stream %d",m,s); SetHook(mean,NULL); } } }}/* UpdateTMVars: use acc values to calc new estimate of variances */void UpdateTMVars(void){ int s,m,k,l,M,vSize; float occim,x,muDiffk,muDiffl; Vector minV; VaAcc *va; MuAcc *ma; MixPDF *mpdf; Vector mean; Covariance cov; Boolean mixFloored,shared; for (s=1;s<=nStreams;s++){ vSize = hset.swidth[s]; minV = vFloor[s]; M = hset.tmRecs[s].nMix; for (m=1;m<=M;m++){ mpdf = hset.tmRecs[s].mixes[m]; cov = mpdf->cov; va = (VaAcc *) GetHook(cov.var); mean = mpdf->mean; ma = (MuAcc *) GetHook(mean); if (va != NULL){ occim = va->occ; mixFloored = FALSE; if (occim > 0.0){ shared=(GetUse(cov.var)>1 || ma==NULL || ma->occ<=0.0); if ((mpdf->ckind==DIAGC)||(mpdf->ckind==INVDIAGC)) for (k=1; k<=vSize; k++){ muDiffk=(shared)?0.0:ma->mu[k]/ma->occ; x = va->cov.var[k]/occim - muDiffk*muDiffk; if (x<minV[k]) { x = minV[k]; mixFloored = TRUE; } cov.var[k] = x; } else { /* FULLC */ for (k=1; k<=vSize; k++){ muDiffk=(shared)?0.0:ma->mu[k]/ma->occ; for (l=1; l<=k; l++){ muDiffl=(shared)?0.0:ma->mu[l]/ma->occ; x = va->cov.inv[k][l]/occim - muDiffk*muDiffl; if (k==l && x<minV[k]){ x = minV[k]; mixFloored = TRUE; } cov.inv[k][l] = x; } } CovInvert(cov.inv,cov.inv); } } else HError(-2427,"UpdateTMVars: No use of var %d in stream %d",m,s); SetHook(cov.var,NULL); } } }}/* ResetHeaps: Reset all heaps used for dynamic memory allocation */void ResetHeaps(void){ ResetHeap(&hmmStack); ResetHeap(&aSetStack); ResetHeap(&sSetStack); ResetHeap(&wsStack); ResetHeap(&labIdStack); ResetHeap(&wtAccStack); ResetHeap(&gstack);}/* UpdateModels: update all models and save them in newDir if set, new files have newExt if set */void UpdateModels(void){ int n; HLink hmm; HMMScanState hss; if (trace&T_INT){ printf("Starting Model Update\n"); fflush(stdout); } if (hsKind==TIEDHS){ if (uFlags & UPVARS) /* TIEDHS therefore only done once per HMMSet */ UpdateTMVars(); if (uFlags & UPMEANS) UpdateTMMeans(); if (uFlags & (UPMEANS|UPVARS)) FixAllGConsts(&hset); } NewHMMScan(&hset,&hss); do { hmm = hss.hmm; n = (int)hmm->hook; if (n<minEgs && !(trace&T_OPT)) HError(-2428,"%s copied: only %d egs\n",HMMPhysName(&hset,hmm),n); if (n>=minEgs) { if (uFlags & UPTRANS) UpdateTrans(hmm); if (maxMixes>1 && uFlags & UPMIXES) UpdateWeights(hmm); } if (trace&T_OPT) { if (n<minEgs) printf("Model %s copied: only %d examples\n", HMMPhysName(&hset,hmm),n); else printf("Model %s updated with %d examples\n", HMMPhysName(&hset,hmm),n); fflush(stdout); } } while (GoNextHMM(&hss)); EndHMMScan(&hss); if (trace&T_TOP){ printf("Saving hmm's to dir %s\n",(newDir==NULL)?"Current":newDir); fflush(stdout); } if(SaveHMMSet(&hset,newDir,newExt,NULL,saveBinary)<SUCCESS) HError(2411,"UpdateModels: SaveHMMSet failed"); ResetHeaps(); /* Clean Up */ if (trace&T_TOP) printf("Reestimation complete - average log prob per frame = %e\n", totalPr/(double)totalT);}/* ----------------------------------------------------------- *//* END: HSmooth.c *//* ----------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -