📄 hadapt.c
字号:
vsize = (int *)bTriMat; for (i=1;i<=*vsize;i++) { tm = bTriMat[i]; ZeroTriMat(tm); } }static void CreateBaseTriMat(MemHeap *x, MixPDF *mp, AdaptXForm *xform, int class){ TriMat *tm; int vsize = VectorSize(mp->mean); IntVec blockSize = GetBlockSize(xform,class); RegAcc *regAcc, *ra; MixPDF *me; BaseClass *bclass; ILink i; int j, cntj, *vsp, b, bsize; regAcc = GetRegAcc(mp); if (xform->info->accBTriMat) { regAcc->bVector = CreateDVector(x,vsize); ZeroDVector(regAcc->bVector); regAcc->bDiagMat = CreateBlockTriMat(x,blockSize); ZeroBlockTriMat(regAcc->bDiagMat); tm = (TriMat *)New(x,sizeof(TriMat)*(vsize+1)); vsp = (int *)tm; *vsp = vsize; for (b=1,cntj=1;b<=IntVecSize(blockSize);b++) { bsize = blockSize[b]; for (j=1;j<=bsize;j++,cntj++) { tm[cntj] = CreateTriMat(x, bsize); ZeroTriMat(tm[cntj]); } } regAcc->bTriMat = tm; } else regAcc->bTriMat = NULL; bclass = xform->bclass; for (i=bclass->ilist[class]; i!=NULL; i=i->next) { if (xform->info->accBTriMat) { me = ((MixtureElem *)i->item)->mpdf; if( me != mp ) { ra = GetRegAcc(me); ra->bVector = regAcc->bVector; ra->bDiagMat = regAcc->bDiagMat; ra->bTriMat = regAcc->bTriMat; } } else regAcc->bTriMat = NULL; } }void SetBaseAccsTime(int t){ baseTriMatTime = t;}void UpdateAccCache(double Lr, Vector svec, MixPDF *mp){ AccCache *paac; TriMat m; int vsize = VectorSize(svec); Vector covar; int i, j, bl, bstart, nblock, bsize; paac = GetPAAccCache(mp); if ( paac != NULL ) { if ( paac->bTriMat[1][1][1] == 0 ) { nblock = (int)(paac->bTriMat[0]); for (bl=1,bstart=0;bl<=nblock;bl++) { m = paac->bTriMat[bl]; bsize = TriMatSize(m); for (i=1;i<=bsize;i++) { /* Fill the accumulate stores */ for (j=1; j<=i; j++) m[i][j] = svec[i+bstart] * svec[j+bstart]; } bstart += bsize; } } covar = mp->cov.var; for (i=1;i<=vsize;i++) { if (mp->ckind==INVDIAGC) paac->bVector[i] += covar[i]*Lr; else paac->bVector[i] += Lr/covar[i]; } }}void UpdateBaseAccs(Vector svec){ int i,j,b,k, bsize, nblock, bl; int cnt, cnti, cntj; TriMat tm, m; RegAcc *ra; DVector acc; BaseClass *bclass; MixPDF *mp; bclass = outXForm->bclass; for (b=1;b<=bclass->numClasses;b++) { mp = ((MixtureElem *)(bclass->ilist[b])->item)->mpdf; ra = GetRegAcc(mp); if ((ra->bTriMat != NULL) && (ra->bVector[1]>0)) { acc = ra->bVector; nblock = (int)(ra->bDiagMat[0]); for (bl=1,cnti=1;bl<=nblock;bl++) { m = ra->bDiagMat[bl]; bsize = TriMatSize(m); for (i=1;i<=bsize;i++,cnti++) { /* Fill the accumulate stores */ tm = ra->bTriMat[cnti]; for (j=1; j<=bsize; j++) for (k=1; k<=j; k++) tm[j][k] += m[j][k] * acc[cnti]; } } ZeroDVector(ra->bVector); } /* now update the outerproduct observation */ if (svec != NULL) { nblock = (int)(ra->bDiagMat[0]); for (bl=1, cnt=1; bl<=nblock;bl++){ bsize = TriMatSize(ra->bDiagMat[bl]); m = ra->bDiagMat[bl]; for (i=1, cnti=cnt; i<=bsize; i++,cnti++) { /* Fill the outer product */ for (j=1,cntj=cnt; j<=i; j++,cntj++) m[i][j] = svec[cnti]*svec[cntj]; } cnt +=bsize; } } }}void UpdateBaseAccsWithPaac(void){ int i,j,k, b, bsize, nblock, bl; int cnti; TriMat tm, m; RegAcc *ra; DVector acc; BaseClass *bclass; MixPDF *mp; AccCache *paac; bclass = outXForm->bclass; for (b=1;b<=bclass->numClasses;b++) { mp = ((MixtureElem *)(bclass->ilist[b])->item)->mpdf; ra = GetRegAcc(mp); if ( ra->bTriMat != NULL) { for (paac = headac; paac!= NULL; paac=paac->next) { if ( (paac->baseclass == b)&& (paac->bVector[1]>0) ){ acc = paac->bVector; nblock = (int)(ra->bDiagMat[0]); for (bl=1,cnti=1;bl<=nblock;bl++) { m = paac->bTriMat[bl]; bsize = TriMatSize(m); for (i=1;i<=bsize;i++,cnti++) { /* Fill the accumulate stores */ tm = ra->bTriMat[cnti]; for (j=1; j<=bsize; j++) for (k=1; k<=j; k++) tm[j][k] += m[j][k] * acc[cnti]; } } } } } } }void ResetAccCache(void){ AccCache *ac; if ( headac != NULL) { for (ac = headac; ac!= NULL; ac=ac->next) { ZeroDVector(ac->bVector); ZeroBlockTriMat(ac->bTriMat); } }}static void AccBaseTriMat(double Lr, Vector svec, MixPDF *mp, int t){ int vsize, i; /* TriMat m; */ Vector covar; RegAcc *regAcc; regAcc = GetRegAcc(mp); covar = mp->cov.var; vsize = VectorSize(svec); if (t != baseTriMatTime) { /* Check to see whether this is the very first frame */ if (headac == NULL ) UpdateBaseAccs(svec); else { UpdateBaseAccsWithPaac(); ResetAccCache(); } SetBaseAccsTime(t); } if (headac == NULL ) { for (i=1;i<=vsize;i++) { if (mp->ckind==INVDIAGC) regAcc->bVector[i] += covar[i]*Lr; else regAcc->bVector[i] += Lr/covar[i]; } } else UpdateAccCache( Lr, svec, mp);}static RegAcc *CreateRegAcc(MemHeap *x, MixPDF *mp, AdaptXForm *xform){ RegAcc *regAcc; int vsize = VectorSize(mp->mean); regAcc = (RegAcc *)New(x,sizeof(RegAcc)); regAcc->occ = 0; if (xform->info->accSum) { regAcc->spSum = CreateVector(x,vsize); ZeroVector(regAcc->spSum); } else regAcc->spSum = NULL; if (xform->info->accSumSq) { regAcc->spSumSq = CreateVector(x,vsize); ZeroVector(regAcc->spSumSq); } else regAcc->spSumSq = NULL; regAcc->bTriMat = NULL; return regAcc;}static void AttachRegAccs(HMMSet *hset, AdaptXForm *xform){ MixPDF *mp = NULL; int nRegAcc=0, b; BaseClass *bclass; ILink i; /* RegAccs stored on the Info structure */ if (!hset->attXFormInfo) AttachXFormInfo(hset); 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; ((XFormInfo *)(mp->info))->regAcc = (RegAcc *)CreateRegAcc(hset->hmem,mp,xform); nRegAcc++; } /* Use last component of the baseclass to access baseclass stats */ CreateBaseTriMat(hset->hmem,mp,xform,b); } if (trace&T_ACC) printf("Attached %d RegAcc structures\n",nRegAcc); hset->attRegAccs = TRUE;}/* --------------- handling the AccStruct structure ------------------ */static AccStruct *CreateAccStruct(MemHeap *x, AdaptXForm *xform, int vsize, IntVec blockSize){ AccStruct *accs; int dim,i,cnti; int b,bsize; accs = (AccStruct *)New(x,sizeof(AccStruct)); accs->occ = 0; accs->dim = vsize; accs->blockSize = blockSize; accs->K = NULL; accs->G = NULL; accs->D = NULL; /* Depending on the form of transform initialise appropriate structure elements */ accs->xkind = xform->xformSet->xkind; switch (accs->xkind) { case MLLRMEAN: accs->K = (DVector *)New(x,(vsize+1)*sizeof(DVector)); accs->G = (DMatrix *)New(x,(vsize+1)*sizeof(DMatrix)); for (b=1,cnti=1;b<=IntVecSize(blockSize);b++) { bsize = blockSize[b]; if (useBias) dim = bsize+1; else dim = bsize; for (i=1;i<=bsize;i++,cnti++) { accs->K[cnti] = CreateDVector(x,dim); ZeroDVector(accs->K[cnti]); accs->G[cnti] = CreateDMatrix(x,dim,dim); ZeroDMatrix(accs->G[cnti]); } } if (mllrDiagCov) { accs->D = CreateDVector(x,vsize); ZeroDVector(accs->D); } break; case MLLRCOV: accs->G = (DMatrix *)New(x,(vsize+1)*sizeof(DMatrix)); for (b=1,cnti=1;b<=IntVecSize(blockSize);b++) { bsize = blockSize[b]; for (i=1;i<=bsize;i++,cnti++) { accs->G[cnti] = CreateDMatrix(x,bsize,bsize); ZeroDMatrix(accs->G[cnti]); } } break; case CMLLR: accs->K = (DVector *)New(x,(vsize+1)*sizeof(DVector)); accs->G = (DMatrix *)New(x,(vsize+1)*sizeof(DMatrix)); for (b=1,cnti=1;b<=IntVecSize(blockSize);b++) { bsize = blockSize[b]; if (useBias) dim = bsize+1; else dim = bsize; for (i=1;i<=bsize;i++,cnti++) { accs->K[cnti] = CreateDVector(x,dim); ZeroDVector(accs->K[cnti]); accs->G[cnti] = CreateDMatrix(x,dim,dim); ZeroDMatrix(accs->G[cnti]); } } break; default : HError(999,"Transform kind not currently supported"); break; } return accs;}/*------------------------------------------------------------------------*//* Regression Tree Parsing *//*------------------------------------------------------------------------*/static float SetNodeOcc(RegNode *node, BaseClass *bclass){ int c; ILink i; MixPDF *mp=NULL; int dim,b; node->nodeOcc = 0; if (node->numChild>0) { for (c=1;c<=node->numChild;c++) { /* Check dimensionality of children is consistent */ node->nodeOcc += SetNodeOcc(node->child[c],bclass); dim = (node->child[c])->vsize; if (node->vsize>0) { if (dim != node->vsize) HError(999,"Inconsistent dimensions in baseclasses (%d %d)",dim,node->vsize); } else node->vsize = dim; } } else { 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; node->nodeOcc += GetRegAcc(mp)->occ; } /* Baseclass definition ensures that dimensions are correct within a baseclass */ dim = VectorSize(mp->mean); if (node->vsize>0) { if (dim != node->vsize) HError(999,"Inconsistent dimensions in baseclasses (%d %d)",dim,node->vsize); } else node->vsize = dim; } } return node->nodeOcc;}static Boolean ParseNode(RegNode *node, AdaptXForm *xform, RegTree *rtree, IntVec classes){ int b,c,size; Boolean genXForm; IntVec lclasses; static void GenXForm(RegNode *node, AdaptXForm *xform, IntVec classes); genXForm = FALSE; if (trace&T_TRE) printf("Node %d (%f)\n",node->nodeIndex,node->nodeOcc); if (node->nodeOcc > rtree->thresh) { size = IntVecSize(classes); lclasses = CreateIntVec(&gstack,IntVecSize(classes)); ZeroIntVec(lclasses); if (node->numChild>0) { /* Not a terminal node */ for (c=1;c<=node->numChild;c++) if (ParseNode(node->child[c], xform, rtree, lclasses)) genXForm = TRUE; /* any of the children need a xform generate it */ if (genXForm) GenXForm(node,xform,lclasses); } else { /* Generate xform for this node */ for (b=1;b<=IntVecSize(node->baseClasses);b++) lclasses[node->baseClasses[b]] = 1; GenXForm(node,xform,lclasses); } FreeIntVec(&gstack,lclasses); genXForm = FALSE; } else { if (node->numChild>0) { /* Not a terminal node */ for (c=1;c<=node->numChild;c++) ParseNode(node->child[c], xform, rtree, classes); } else { /* Mark baseclasses for adaptation */ for (b=1;b<=IntVecSize(node->baseClasses);b++) classes[node->baseClasses[b]] = 1; } genXForm = TRUE; } return genXForm;}static Boolean ParseTree(RegTree *rtree, AdaptXForm *xform){ int c; IntVec classes; float occ; /* First set the correct threshold for this tree */ rtree->thresh = GetSplitThresh(xform); occ = SetNodeOcc(rtree->root, rtree->bclass); if (!(rtree->valid)) { /* multiple streams being used */ /* the total number of observations will be given by the roots child */ /* should be approximately the same for all children */ occ = rtree->root->child[1]->nodeOcc; } if (occ<rtree->thresh) /* not enough data to generate transforms */ return FALSE; /* reset the number of transforms */ xform->xformSet->numXForms = 0; classes = CreateIntVec(&gstack,rtree->bclass->numClasses); if (rtree->valid) { /* dimensionality of all transforms the same */ ZeroIntVec(classes); ParseNode(rtree->root, xform, rtree, classes); } else { for (c=1;c<=rtree->root->numChild;c++) { ZeroIntVec(classes); ParseNode(rtree->root->child[c], xform, rtree, classes); } } FreeIntVec(&gstack,classes);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -