📄 hadapt.c
字号:
if (xform->xformSet->numXForms == 0) return FALSE; else return TRUE;}/*------------------------------------------------------------------------*//* Accumulation of statistics from Tree *//*------------------------------------------------------------------------*//* Using stored information reset all the model parameters */static void ResetComp(MixPDF *mp){ MInfo *mi; mi = GetMInfo(mp); if ( mi != NULL) { /* Initial model parameters have been stored */ if (mi->mean != NULL) CopyVector(mi->mean,mp->mean); switch (mp->ckind) { case DIAGC: case INVDIAGC: if (mi->cov.var != NULL) { CopyVector(mi->cov.var,mp->cov.var); mp->gConst = mi->gConst; } break; default: HError(999,"ResetComp: bad ckind %d",mp->ckind); } } }static void Tri2DMat (DMatrix m1, DMatrix m2){ int i,j,nrows,ncols; nrows = NumDRows(m2); ncols = NumDCols(m2); if (nrows != ncols) HError(5270,"Tri2Mat: target matrix not square %d vs %d", nrows,ncols); /* if (ncols != TriMatSize(m1)) HError(5270,"Tri2Mat: sizes differ %d vs %d", TriMatSize(m1),ncols); */ if (ncols != NumDRows(m1)) HError(5270,"Tri2Mat: sizes differ %d vs %d", NumDRows(m1),ncols); for (i=1; i<=nrows; i++) for (j=1; j<=i; j++) { m2[i][j] = m1[i][j]; if (i!=j) m2[j][i] = m1[i][j]; }}static void AccCMLLRBaseStats(MixPDF *mp, AccStruct *accs){ /* update for the accumulates at the base level */ RegAcc *ra; int i,j,k; int cnti,b,bsize; TriMat tm; ra = GetRegAcc(mp); for (b=1,cnti=1;b<=IntVecSize(accs->blockSize);b++) { bsize = accs->blockSize[b]; for (i=1;i<=bsize;i++,cnti++) { tm = ra->bTriMat[cnti]; for (j=1;j<=bsize;j++) { for (k=1;k<=j;k++) { accs->G[cnti][j][k] += tm[j][k]; } } } }} static void AccCMLLRPDFStats(MixPDF *mp, AccStruct *accs){ RegAcc *ra; int i,j; float icov=0.0,scale; int cnt,cnti,cntj,b,bsize; Vector mean; Covariance cov; ra = GetRegAcc(mp); mean = mp->mean; cov = mp->cov; for (b=1,cnti=1,cnt=1;b<=IntVecSize(accs->blockSize);b++) { bsize = accs->blockSize[b]; for (i=1;i<=bsize;i++,cnti++) { switch(mp->ckind){ case INVDIAGC: icov = cov.var[cnti]; break; case DIAGC: icov = 1/cov.var[cnti]; break; default: HError(999,"AccMixPDFStats: bad ckind %d",mp->ckind); } scale = ra->occ * icov; for (j=1,cntj=cnt;j<=bsize;j++,cntj++) { accs->K[cnti][j] += ra->spSum[cntj] * mean[cnti] * icov; if (useBias) accs->G[cnti][bsize+1][j] += icov * ra->spSum[cntj]; } if (useBias) { accs->K[cnti][bsize+1] += scale * mean[cnti]; accs->G[cnti][bsize+1][bsize+1] += scale; } } cnt += bsize; }}static void AccMLLRPDFStats(MixPDF *mp, AccStruct *accs){ RegAcc *ra; int i,j,k; float icov=0.0,scale; int cnt,cnti,cntj,cntk,b,bsize; Vector mean; Covariance cov; ra = GetRegAcc(mp); mean = mp->mean; cov = mp->cov; for (b=1,cnti=1,cnt=1;b<=IntVecSize(accs->blockSize);b++) { bsize = accs->blockSize[b]; for (i=1;i<=bsize;i++,cnti++) { switch(mp->ckind){ case INVDIAGC: icov = cov.var[cnti]; break; case DIAGC: icov = 1/cov.var[cnti]; break; default: HError(999,"AccMixPDFStats: bad ckind %d",mp->ckind); } scale = ra->occ * icov; for (j=1,cntj=cnt;j<=bsize;j++,cntj++) { accs->K[cnti][j] += ra->spSum[cnti] * mean[cntj] * icov; for (k=1,cntk=cnt;k<=j;k++,cntk++) accs->G[cnti][j][k] += scale * mean[cntj] * mean[cntk]; if (useBias) accs->G[cnti][bsize+1][j] += scale * mean[cntj]; } if (useBias) { accs->K[cnti][bsize+1] += ra->spSum[cnti] *icov; accs->G[cnti][bsize+1][bsize+1] += scale; } if (mllrDiagCov) { accs->D[cnti] += icov * ra->spSumSq[cnti]; } } cnt += bsize; }}static void AccMLLRCOVPDFStats(MixPDF *mp, AccStruct *accs){ RegAcc *ra; int i,j,k; float icov=0.0,scale, c1, c2, c3; int cnt,cnti,cntj,cntk,b,bsize; Vector mean; Covariance cov; ra = GetRegAcc(mp); mean = mp->mean; cov = mp->cov; for (b=1,cnti=1,cnt=1;b<=IntVecSize(accs->blockSize);b++) { bsize = accs->blockSize[b]; for (i=1;i<=bsize;i++,cnti++) { switch(mp->ckind){ case INVDIAGC: icov = cov.var[cnti]; break; case DIAGC: icov = 1/cov.var[cnti]; break; default: HError(999,"AccMixPDFStats: bad ckind %d",mp->ckind); } scale = ra->occ * icov; for (j=1,cntj=cnt;j<=bsize;j++,cntj++) { for (k=1,cntk=cnt;k<=j;k++,cntk++) { c1 = scale * mean[cntj] * mean[cntk] ; c2 = ra->spSum[cntj] * mean[cntk] * icov; c3 = ra->spSum[cntk] * mean[cntj] * icov; accs->G[cnti][j][k] += (c1 - c2 -c3); } } } cnt += bsize; }}static void AccMixPDFStats(HMMSet *hset, MixPDF *mp, AccStruct *accs){ RegAcc *ra; ra = GetRegAcc(mp); if (ra->occ > minOccThresh) { accs->occ += ra->occ; if (((hset->parentXForm == NULL) && (hset->curXForm == NULL) ) || (hset->parentXForm == hset->curXForm)) { /* There's nothing to be done as model set the same */ } else if (hset->parentXForm == NULL) { /* xform to be built on original parameters */ ResetComp(mp); } else { /* xform to be built on a parent xform */ ApplyCompXForm(mp,hset->parentXForm); } switch (accs->xkind) { case MLLRMEAN: AccMLLRPDFStats(mp,accs); break; case MLLRCOV: AccMLLRCOVPDFStats(mp,accs); break; case CMLLR: AccCMLLRPDFStats(mp,accs); break; default : HError(999,"Transform kind not currently supported"); break; } }}static void AccBaseClassStats(MixPDF *mp, AccStruct *accs){ /* RegAcc *ra; */ /* Accumulate the statistics for the base classes. The parent transforms have been already sorted. */ switch (accs->xkind) { case MLLRCOV: case CMLLR: AccCMLLRBaseStats(mp,accs); break; default : HError(999,"Transform kind not currently supported"); break; }}static void AccNodeStats(RegNode *node, AccStruct *accs, AdaptXForm *xform, IntVec classes){ BaseClass *bclass; ILink i; int b,c; MixPDF *mp = NULL; if (node->numChild>0) { for (c=1;c<=node->numChild;c++) AccNodeStats(node->child[c],accs,xform,classes); } else { bclass = xform->bclass; for (b=1;b<=IntVecSize(node->baseClasses);b++) { for (i=bclass->ilist[node->baseClasses[b]]; i!=NULL; i=i->next) { mp = ((MixtureElem *)i->item)->mpdf; AccMixPDFStats(xform->hset,mp,accs); } /* Use last component of the baseclass to access baseclass stats */ if( AccAdaptBaseTriMat(xform) ) AccBaseClassStats(mp,accs); } }}/* Feature-Space adaptation */static void FixDet(LinXForm *xf){ int ind,nblock; double scale, bdet; float det; nblock = IntVecSize(xf->blockSize); if ( nblock == xf->vecSize) { det=0; for (ind=1;ind<=xf->vecSize;ind++) { scale = xf->xform[ind][1][1]; det += log(scale*scale); } xf->det = det; } else { det=0; for (ind=1;ind<=nblock;ind++) { bdet = MatDet(xf->xform[ind]); det += 2*log(fabs(bdet)); } xf->det = det; }}/*------------------------------------------------------------------------*//* Accummulator Cache for application of parent XForms *//*------------------------------------------------------------------------*/static AccCache *CreateAccCache(IntVec size, int b){ AccCache *ac; int vsize, bl; vsize = 0; for (bl=1;bl<=IntVecSize(size);bl++) vsize += size[bl]; ac = (AccCache *)New(&obcaStack,sizeof(AccCache)); ac->baseclass = b; ac->bVector = CreateDVector(&obcaStack,vsize); ZeroDVector(ac->bVector); ac->bTriMat = CreateBlockTriMat(&obcaStack,size); ZeroBlockTriMat(ac->bTriMat); ac->next = headac; headac = ac; return(ac);}static void SetAccCache(AdaptXForm *xform){ MixPDF *mp; BaseClass *bclass; int b; ILink i; AccCache **ac = NULL; int nxflevel = 0, nxfcomb = 1, numXf = 0, nxf, ind; int nCache = 0; AInfo *ai; AdaptXForm *xf; XFormSet *xformSet; HMMSet *hset; if ((xform != NULL) && (AccAdaptBaseTriMat(xform))) { hset = xform->hset; if (hset->parentXForm != NULL) { xform->parentXForm = hset->parentXForm; xform->parentXForm->nUse++; } else xform->parentXForm = NULL; nxflevel = 1; nxfcomb *= (xform->bclass->numClasses + 1); xf = xform->parentXForm; /* Count the number of levels and combinations */ while ( xf != NULL ) { if (AccAdaptBaseTriMat(xf)) { nxfcomb *= (xf->xformSet->numXForms + 1); nxflevel++; } xf = xf->parentXForm; } if (nxflevel>0) { ac = (AccCache **)New(&gstack,sizeof(AccCache *)*(nxfcomb)); for ( ind = 0; ind <= nxfcomb; ind++) ac[ind] = NULL; } bclass = xform->bclass; for (b = 1; b <= bclass->numClasses; b++) { for (i=bclass->ilist[b]; i!=NULL; i=i->next) { mp = ((MixtureElem *)i->item)->mpdf; if (nxflevel == 0) ((XFormInfo *)mp->info)->paac = NULL; else { ai = GetPAInfo(mp); nxf = xform->bclass->numClasses + 1; ind = b; xf = xform->parentXForm; while ( xf != NULL ){ xformSet = xf->xformSet; if (AccAdaptBaseTriMat(xf)) { if (HardAssign(xform)) numXf = xf->xformWgts.assign[ai->baseClass]; else HError(999,"Not currently supported"); ind += numXf * nxf; nxf *= (xformSet->numXForms + 1); } xf = xf->parentXForm; if ( xf != NULL ) ai = ai->next; } if (nxflevel > 0) { if (ind > 0) { /* support no transform has been generated */ if ( ac[ind] == NULL ) { ac[ind] = CreateAccCache(GetBlockSize(xform,b), b); nCache++; } } ((XFormInfo *)mp->info)->paac = ac[ind]; } } } } if (ac != NULL) Dispose(&gstack,ac); ac = NULL; } if (trace&T_TOP) printf("Created %d AccCaches (of %d possible)\n",nCache,nxfcomb);}/*------------------------------------------------------------------------*//* Observation Cache for application of feature-space transform *//*------------------------------------------------------------------------*/static ObsCache *CreateObsCache(int size){ ObsCache *oc; oc = (ObsCache *)New(&obcaStack,sizeof(ObsCache)); oc->time = -1; oc->obs = CreateVector(&obcaStack,size); ZeroVector(oc->obs); oc->det =0; oc->next = headoc; headoc = oc; return(oc);} static void SetObsCache(AdaptXForm *xform, Boolean parent){ MixPDF *mp; BaseClass *bclass; int b, size; ILink i; ObsCache **oc = NULL; int nxflevel = 0, nxfcomb = 1, numXf = 0, nxf, ind; int nCache = 0; AInfo *ai; AdaptXForm *xf; XFormSet *xformSet; if (xform != NULL) { xf = xform; /* Count the number of levels and combinations */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -