/* UpVars: update variances, apply correction if covariance is not shared */ void UpVars(int i, int s, int m, int size, VaAcc *va, Vector oldMean, Vector newMean, Boolean shared, MixPDF *mp) { int j,k; float x,y,z; Vector floor; if (va->occ == 0.0) HError(2127,"UpVars: zero occ i=%d/s=%d/m=%d",i,s,m); floor=vFloor[s]; switch(mp->ckind){ case DIAGC: for (j=1; j<=size; j++){ x = (shared)?0.0:newMean[j]-oldMean[j]; z = va->cov.var[j]/va->occ - x*x; mp->cov.var[j] = (z<floor[j])?floor[j]:z; } FixDiagGConst(mp); break; case FULLC: for (j=1; j<=size; j++){ x = (shared)?0.0:newMean[j]-oldMean[j]; for (k=1; k<j; k++) { y = (shared)?0.0:newMean[k]-oldMean[k]; mp->cov.inv[j][k] = va->cov.inv[j][k]/va->occ - x*y; } z = va->cov.inv[j][j]/va->occ - x*x; mp->cov.inv[j][j] = (z<floor[j])?floor[j]:z; } FixFullGConst(mp,CovInvert(mp->cov.inv,mp->cov.inv)); break; default: HError(2124,"UpVars: bad cov kind %d",mp->ckind); } }
/* 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); } } } }
/* CalcCovs: calculate covariance of speech data */ void CalcCovs(void) { int x,y,s,V; float meanx,meany,varxy,n; Matrix fullMat; if (totalCount<2) HError(2021,"CalcCovs: Only %d speech frames accumulated",totalCount); if (trace&T_TOP) printf("%ld speech frames accumulated\n", totalCount); n = (float)totalCount; /* to prevent rounding to integer below */ for (s=1; s<=hset.swidth[0]; s++){ /* For each stream */ V = hset.swidth[s]; for (x=1; x<=V; x++) /* For each coefficient ... */ accs[s].meanSum[x] /= n; /* ... calculate mean */ for (x=1;x<=V;x++) { meanx = accs[s].meanSum[x]; /* ... and [co]variance */ if (fullcNeeded[s]) { for (y=1; y<=x; y++) { meany = accs[s].meanSum[y]; varxy = accs[s].squareSum.inv[x][y]/n - meanx*meany; accs[s].squareSum.inv[x][y] = (x != y || varxy > minVar) ? varxy : minVar; } } else { varxy = accs[s].squareSum.var[x]/n - meanx*meanx; accs[s].fixed.var[x] = (varxy > minVar) ? varxy :minVar; } } if (fullcNeeded[s]) { /* invert covariance matrix */ fullMat=CreateMatrix(&gstack,V,V); ZeroMatrix(fullMat); CovInvert(accs[s].squareSum.inv,fullMat); Mat2Tri(fullMat,accs[s].fixed.inv); FreeMatrix(&gstack,fullMat); } if (trace&T_COVS) { printf("Stream %d\n",s); if (meanUpdate) ShowVector(" Mean Vector ", accs[s].meanSum,12); if (fullcNeeded[s]) { ShowTriMat(" Covariance Matrix ",accs[s].squareSum.inv,12,12); } else ShowVector(" Variance Vector ", accs[s].fixed.var,12); } } }
/* track speakers */ if (UpdateSpkrStats(&hset,&xfInfo, datafn)) spUtt=0; /* Check to see whether set-up is valid */ CheckUpdateSetUp(); fbInfo->inXForm = xfInfo.inXForm; fbInfo->al_inXForm = xfInfo.al_inXForm; fbInfo->paXForm = xfInfo.paXForm; if ((maxSpUtt==0) || (spUtt<maxSpUtt)) DoForwardBackward(fbInfo, utt, datafn, datafn2) ; numUtt += 1; spUtt++; } } while (NumArgs()>0); if (uFlags&UPXFORM) {/* ensure final speaker correctly handled */ UpdateSpkrStats(&hset,&xfInfo, NULL); if (trace&T_TOP) { printf("Reestimation complete - average log prob per frame = %e (%d frames)\n", totalPr/totalT, totalT); } } else { if (parMode>0 || (parMode==0 && (updateMode&UPMODE_DUMP))){ MakeFN("HER$.acc",newDir,NULL,newFn); f=DumpAccs(&hset,newFn,uFlags,parMode); tmpFlt = (float)totalPr; WriteFloat(f,&tmpFlt,1,ldBinary); WriteInt(f,(int*)&totalT,1,ldBinary); fclose( f ); } if (parMode <= 0) { if (stats) { StatReport(&hset); } if (updateMode&UPMODE_UPDATE) UpdateModels(&hset,utt->pbuf2); } } ResetHeap(&uttStack); ResetHeap(&fbInfoStack); ResetHeap(&hmmStack);