📄 herest.c
字号:
HError(2393,"UpdateWeights: Model %d[%s]: mix too big in %d.%d.%d %5.5f", px,HMMPhysName(hset,hmm),i,s,m,x); x = 1.0; } switch (hsKind){ case TIEDHS: ste->spdf.tpdf[m] = (x>MINMIX) ? x : 0.0; break; case DISCRETEHS: ste->spdf.dpdf[m]=(x>MINMIX) ? DProb2Short(x) : DLOGZERO; break; case PLAINHS: case SHAREDHS: me=ste->spdf.cpdf+m; me->weight = (x>MINMIX) ? x : 0.0; 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; case PLAINHS: case SHAREDHS: FloorMixes(hset,ste->spdf.cpdf+1,M,mixWeightFloor); break; } } }else HError(-2330,"UpdateWeights: Model %d[%s]: no use of mixtures in %d.%d", px,HMMPhysName(hset,hmm),i,s); ste->hook = NULL; } } }} /* UpdateMeans: use acc values to calc new estimate of means */void UpdateMeans(HMMSet *hset, int px, HLink hmm){ int i,s,m,k,M,N,S,vSize; float occim; MuAcc *ma; StateElem *se; StreamElem *ste; MixtureElem *me; Vector mean; N = hmm->numStates; se = hmm->svec+2; S = hset->swidth[0]; for (i=2; i<N; i++,se++){ ste = se->info->pdf+1; for (s=1;s<=S;s++,ste++){ vSize = hset->swidth[s]; me = ste->spdf.cpdf + 1; M = ste->nMix; for (m=1;m<=M;m++,me++) if (me->weight > MINMIX){ mean = me->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{ M = ste->nMix; HError(-2330,"UpdateMeans: Model %d[%s]: no use of mean %d.%d.%d", px,HMMPhysName(hset,hmm),i,s,m); } SetHook(mean,NULL); } } } }}/* UpdateTMMeans: use acc values to calc new estimate of means for TIEDHS */void UpdateTMMeans(HMMSet *hset){ int s,m,k,M,S,vSize; float occim; MuAcc *ma; MixPDF *mpdf; Vector mean; S = hset->swidth[0]; for (s=1;s<=S;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(-2330,"UpdateMeans: No use of mean %d in stream %d",m,s); SetHook(mean,NULL); } } }}/* UpdateVars: use acc values to calc new estimate of variances */void UpdateVars(HMMSet *hset, int px, HLink hmm){ int i,s,m,k,l,M,N,S,vSize; float occim,x,muDiffk,muDiffl; Vector minV; VaAcc *va; MuAcc *ma; StateElem *se; StreamElem *ste; MixtureElem *me; Vector mean; Covariance cov; Boolean mixFloored,shared; N = hmm->numStates; se = hmm->svec+2; S = hset->swidth[0]; for (i=2; i<N; i++,se++){ ste = se->info->pdf+1; for (s=1;s<=S;s++,ste++){ vSize = hset->swidth[s]; minV = vFloor[s]; me = ste->spdf.cpdf + 1; M = ste->nMix; for (m=1;m<=M;m++,me++) if (me->weight > MINMIX){ cov = me->mpdf->cov; va = (VaAcc *) GetHook(cov.var); mean = me->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 (me->mpdf->ckind==DIAGC) { 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]; nFloorVar++; 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]; nFloorVar++; mixFloored = TRUE; } cov.inv[k][l] = x; } } CovInvert(cov.inv,cov.inv); } } else{ MixtureElem *me2; me2 = ste->spdf.cpdf + 1; M = ste->nMix; HError(-2330,"UpdateVars: Model %d[%s]: no use of variance %d.%d.%d", px,HMMPhysName(hset,hmm),i,s,m); } if (mixFloored == TRUE) nFloorVarMix++; SetHook(cov.var,NULL); } } } }}/* UpdateTMVars: use acc values to calc new estimate of vars for TIEDHS */void UpdateTMVars(HMMSet *hset){ int s,m,k,l,M,S,vSize; float occim,x,muDiffk,muDiffl; Vector minV; VaAcc *va; MuAcc *ma; MixPDF *mpdf; Vector mean; Covariance cov; Boolean mixFloored,shared; S = hset->swidth[0]; for (s=1;s<=S;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) { 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]; nFloorVar++; 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]; nFloorVar++; mixFloored = TRUE; } cov.inv[k][l] = x; } } CovInvert(cov.inv,cov.inv); } } else HError(-2330,"UpdateTMVars: No use of var %d in stream %d",m,s); if (mixFloored == TRUE) nFloorVarMix++; SetHook(cov.var,NULL); } } }}static int fltcompare(const void *_i, const void *_j){ const float *i = (const float*)_i; const float *j = (const float*)_j; if (*i > *j) return (1); if (*i < *j) return (-1); return (0);}void FloorVars(HMMSet *hset1, int s){ HMMScanState hss1; int vsize; int i; if(!(hset1->hsKind==PLAINHS || hset1->hsKind==SHAREDHS)){ HError(1, "Percentile var flooring not supported for this kind of hmm set. (e.g. tied.) should be easy."); } else { float **varray; int M=0,m=0,floored=0; vsize = hset1->swidth[s]; NewHMMScan(hset1,&hss1); while(GoNextMix(&hss1,FALSE)){ M++; } EndHMMScan(&hss1); varray = New(&gstack, sizeof(float*) * (vsize+1)); for(i=1;i<=vsize;i++) varray[i] = New(&gstack, sizeof(float) * M); NewHMMScan(hset1,&hss1); while(GoNextMix(&hss1,FALSE)){ int k; if(hss1.mp->ckind != DIAGC ) HError(1, "FloorVars expects DIAGC covariances. "); for(k=1;k<=vsize;k++){ varray[k][m] = hss1.mp->cov.var[k]; } m++; } EndHMMScan(&hss1); for(i=1;i<=vsize;i++){ qsort((char *) varray[i], M, sizeof(float), fltcompare); } if(varFloorPercent <=0 || varFloorPercent >= 100) HError(1, "varFloorPercent should be <100 and >0.."); NewHMMScan(hset1,&hss1); while(GoNextMix(&hss1,FALSE)){ int k, Pos = (int)(varFloorPercent*0.01*M); for(k=1;k<=vsize;k++){ if(hss1.mp->cov.var[k] < varray[k][Pos]){ hss1.mp->cov.var[k] = varray[k][Pos]; floored++; } } } EndHMMScan(&hss1); printf("Floored %d (expected to floor %d)\n", floored, (int)( varFloorPercent * 0.01 * M * vsize)); } FixAllGConsts(hset1);}void MLUpdateModels(HMMSet *hset, UPDSet uFlags){ HSetKind hsKind; HMMScanState hss; HLink hmm; int px,n,maxM; hsKind = hset->hsKind; maxM = MaxMixInSet(hset); if (hsKind == TIEDHS){ /* TIEDHS - update mu & var once per HMMSet */ if (uFlags & UPVARS) UpdateTMVars(hset); if (uFlags & UPMEANS) UpdateTMMeans(hset); if (uFlags & (UPMEANS|UPVARS)) FixAllGConsts(hset); } NewHMMScan(hset,&hss); px=1; do { hmm = hss.hmm; n = (int)hmm->hook; if (n<minEgs && !(trace&T_UPD)) HError(-2331,"UpdateModels: %s[%d] copied: only %d egs\n", HMMPhysName(hset,hmm),px,n); if (trace&T_UPD) { if (n<minEgs) printf("Model %s[%d] copied: only %d examples\n", HMMPhysName(hset,hmm),px,n); else printf("Model %s[%d] to be updated with %d examples\n", HMMPhysName(hset,hmm),px,n); fflush(stdout); } if (n>=minEgs && n>0) { if (uFlags & UPTRANS) UpdateTrans(hset,px,hmm); if (maxM>1 && uFlags & UPMIXES) UpdateWeights(hset,px,hmm); if (hsKind != TIEDHS){ if (uFlags & UPVARS) UpdateVars(hset,px,hmm); if (uFlags & UPMEANS) UpdateMeans(hset,px,hmm); if (uFlags & (UPMEANS|UPVARS)) FixGConsts(hmm); } } px++; } while (GoNextHMM(&hss)); EndHMMScan(&hss); if (trace&T_TOP) { if (nFloorVar > 0) printf("Total %d floored variance elements in %d different mixes\n", nFloorVar,nFloorVarMix); fflush(stdout); }}/* UpdateModels: update all models and save them in newDir if set, new files have newExt if set */void UpdateModels(HMMSet *hset, ParmBuf pbuf2){ int maxM; static char str[100]; BufferInfo info2; if (trace&T_UPD){ printf("Starting Model Update\n"); fflush(stdout); } if (parMode == -1) { ForceDiagC(hset); /* invert the variances again */ ConvExpWt(hset); } maxM = MaxMixInSet(hset); if (uFlags & UPMAP) MAPUpdateModels(hset, uFlags); else { MLUpdateModels(hset, uFlags); } if(varFloorPercent){ int s; printf("Flooring all vars to the %f'th percentile of distribution... ", varFloorPercent); for(s=1;s<=hset->swidth[0];s++) FloorVars(hset,s); } if (trace&T_TOP){ if (mmfFn == NULL) printf("Saving hmm's to dir %s\n",(newDir==NULL)?"Current":newDir); else printf("Saving hmm's to MMF %s\n",mmfFn); fflush(stdout); } ClearSeenFlags(hset,CLR_ALL); if (twoDataFiles){ if (parMode == 0){ SetChannel("HPARM2"); nParm = GetConfig("HPARM2", TRUE, cParm, MAXGLOBS); if (GetConfStr(cParm,nParm,"TARGETKIND",str)) hset->pkind = Str2ParmKind(str); }else{ GetBufferInfo(pbuf2,&info2); hset->pkind = info2.tgtPK; } } SaveHMMSet(hset,newDir,newExt,NULL,saveBinary); if (trace&T_TOP) { printf("Reestimation complete - average log prob per frame = %e\n", totalPr/totalT); printf(" - total frames seen = %e\n", (double)totalT); }}/* ----------------------------------------------------------- *//* END: HERest.c *//* ----------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -