📄 hadapt.c
字号:
while ( xf != NULL ) { if ((xf->xformSet->xkind == CMLLR)||(xf->xformSet->xkind == MLLRCOV)) { nxfcomb *= (xf->xformSet->numXForms + 1); nxflevel++; } xf = xf->parentXForm; } if (nxflevel>0) { oc = (ObsCache **)New(&gstack,sizeof(ObsCache *)*(nxfcomb)); for ( ind = 0; ind <= nxfcomb; ind++) { oc[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) { if (parent) { ((XFormInfo *)mp->info)->paoc = NULL; } else ((XFormInfo *)mp->info)->oc = NULL; } else { if (parent) ai = GetPAInfo(mp); else ai = GetAInfo(mp); xf = xform; nxf = 1; ind = 0; while ( xf != NULL ){ xformSet = xf->xformSet; if ((xformSet->xkind == CMLLR)||(xformSet->xkind == MLLRCOV)) { 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; ai = ai->next; } if (nxflevel > 0) { if (ind > 0) { /* support no transform has been generated */ size = VectorSize(mp->mean); if ( oc[ind] == NULL ) { oc[ind] = CreateObsCache(size); nCache++; } } if (parent) ((XFormInfo *)mp->info)->paoc = oc[ind]; else ((XFormInfo *)mp->info)->oc = oc[ind]; } } } } if (oc != NULL) Dispose(&gstack,oc); oc = NULL; } if (trace&T_TOP) printf("Created %d ObsCaches (of %d possible)\n",nCache,nxfcomb);}static void UpdateObsCache( ObsCache *oc, Vector svec, LogFloat det, int t) { if (oc != NULL ) { if (t != oc->time) { oc->time = t; CopyVector(svec, oc->obs); oc->det = det; } }}void ResetObsCache(void){ ObsCache *oc; if ( headoc != NULL) { for (oc = headoc; oc!= NULL; oc=oc->next) { oc->time = -1; ZeroVector(oc->obs); oc->det = 0; } }}/*------------------------------------------------------------------------*//* Adaptation Application *//*------------------------------------------------------------------------*/static void ApplyXForm2Vector(LinXForm *linXForm, Vector mean){ Vector vec, bias; int size,b,bsize; Matrix A; float tmp; int i,j; int cnt,cnti,cntj; /* Check dimensions */ size = linXForm->vecSize; if (size != VectorSize(mean)) HError(999,"Transform dimension (%d) does not match mean dimension (%d)", size,VectorSize(mean)); vec = CreateVector(&gstack,size); CopyVector(mean,vec); ZeroVector(mean); /* Transform mean */ for (b=1,cnti=1,cnt=1;b<=IntVecSize(linXForm->blockSize);b++) { bsize = linXForm->blockSize[b]; A = linXForm->xform[b]; for (i=1;i<=bsize;i++,cnti++) { tmp = 0; for (j=1,cntj=cnt;j<=bsize;j++,cntj++) tmp += A[i][j] * vec[cntj]; mean[cnti] = tmp; } cnt += bsize; } /* Apply bias if required */ bias = linXForm->bias; if (bias != NULL) { for (i=1;i<=size;i++) mean[i] += bias[i]; } FreeVector(&gstack,vec);}/* Feature-Space adaptation */static Vector CompFXForm(MixPDF *mp, Vector svec, AdaptXForm *xform, AInfo *ai, LogFloat *det){ Vector vec; XFormSet *xformSet; int numXf = 0; if (ai->next != NULL) { /* There's a parent transform */ vec = CompFXForm(mp,svec,xform->parentXForm,ai->next,det); } else { *det = 0; vec = svec; } /* Check the kind of the adaptation */ if ((xform->akind != BASE) && (xform->akind != TREE)) HError(999,"Only BASE and TREE adaptation currently supported"); if (HardAssign(xform)) numXf = xform->xformWgts.assign[ai->baseClass]; else HError(999,"Not currently supported"); /* Apply linear transformations to the parameters */ if (numXf > 0) { /* Allows support when no transforms have been generated */ xformSet = xform->xformSet; switch (xformSet->xkind) { case CMLLR: ApplyXForm2Vector(xformSet->xforms[numXf],svec); *det += 0.5* (xformSet->xforms[numXf]->det); break; case MLLRCOV: ApplyXForm2Vector(xformSet->xforms[numXf],svec); *det += 0.5* (xformSet->xforms[numXf]->det); break; default: /* nothing is done */ break; } /* No other options currently supported */ } else { /* no transforms equates to an identity transform */ svec = vec; } return svec;}/* Model space adaptation */static void CompXForm(MixPDF *mp, AdaptXForm *xform, AInfo *ai){ XFormSet *xformSet; int numXf, i; int size = VectorSize(mp->mean); Vector cov = CreateVector(&gstack,size); if (ai->next != NULL) { /* There's a parent transform */ CompXForm(mp,xform->parentXForm,ai->next); } else { /* set up model parameters for adptation */ ResetComp(mp); } /* Check the kind of the adaptation */ if ((xform->akind != BASE) && (xform->akind != TREE)) HError(999,"Only BASE and TREE adaptation currently supported"); numXf = xform->xformWgts.assign[ai->baseClass]; /* Apply linear transformations to the parameters */ if (numXf > 0) { /* Allows support when no transforms have been generated */ xformSet = xform->xformSet; switch (xformSet->xkind) { case MLLRMEAN: ApplyXForm2Vector(xformSet->xforms[numXf],mp->mean); break; case MLLRCOV: ApplyXForm2Vector(xformSet->xforms[numXf],mp->mean); break; case MLLRVAR: switch(mp->ckind){ case DIAGC: ApplyXForm2Vector(xformSet->xforms[numXf], mp->cov.var); FixDiagGConst(mp); break; case INVDIAGC: for (i=1;i<=size;i++) cov[i] = 1/mp->cov.var[i]; ApplyXForm2Vector(xformSet->xforms[numXf], cov); for (i=1;i<=size;i++) mp->cov.var[i] = 1/cov[i]; FixInvDiagGConst(mp); break; default: HError(999,"AccMixPDFStats: bad ckind %d",mp->ckind); } break; default: /* nothing is done */ break; } /* No other options currently supported */ } FreeVector(&gstack, cov);}/*------------------------------------------------------------------------*//* Transform Initialisation and Estimation *//*------------------------------------------------------------------------*/static LinXForm *CreateLinXForm(MemHeap *x,int vsize,IntVec blockSize){ LinXForm *xf; int b,bsize,size; xf = (LinXForm *)New(x,sizeof(LinXForm)); xf->det = 0; xf->nUse = 0; xf->vecSize = vsize; xf->blockSize = blockSize; xf->xform = (SMatrix *)New(x,(IntVecSize(blockSize)+1)*sizeof(Matrix)); size = 0; for (b=1;b<=IntVecSize(blockSize);b++) { bsize = blockSize[b]; xf->xform[b] = CreateSMatrix(x,bsize,bsize); size += bsize; } if (size != vsize) HError(999,"Incompatable xform sizes %d and %d (block)",vsize,size); if (useBias) xf->bias = CreateSVector(x,size); else xf->bias = NULL; return xf;}static void EstMLLRDiagCovXForm(AccStruct *accs, LinXForm *xf, LinXForm *dxf){ int b, cnti,dim, bsize; int i,j,k; double tmu, tvar; DVector tvec; Matrix A; DMatrix G; for (b=1,cnti=1;b<=IntVecSize(accs->blockSize);b++) { if ((enableBlockAdapt == NULL) || (enableBlockAdapt[b] == 1)) { bsize = accs->blockSize[b]; if (xf->bias == NULL) dim = bsize; else dim = bsize+1; A = xf->xform[b]; tvec = CreateDVector(&gstack,dim); G = CreateDMatrix(&gstack,dim,dim); for (i=1;i<=bsize;i++,cnti++) { tmu = 0; tvar = 0; ZeroDVector(tvec); Tri2DMat(accs->G[cnti],G); for (j=1;j<=bsize;j++) { tmu += A[i][j] * accs->K[cnti][j]; for (k=1;k<=bsize;k++) tvec[j] += G[j][k] * A[i][k]; if (xf->bias != NULL) tvec[j] += G[j][dim] * xf->bias[cnti]; } if (xf->bias != NULL) { for (k=1;k<=bsize;k++) tvec[dim] += G[dim][k] * A[i][k]; tvec[dim] += xf->bias[cnti] * G[dim][dim]; } for (j=1;j<=bsize;j++) tvar += A[i][j] * tvec[j]; if (xf->bias != NULL) { tmu += xf->bias[cnti] * accs->K[cnti][dim]; tvar += xf->bias[cnti] * tvec[dim]; } dxf->xform[cnti][1][1] = (accs->D[cnti] - 2*tmu + tvar)/accs->occ; } FreeDVector(&gstack,tvec); } else { bsize = accs->blockSize[b]; for (i=1;i<=bsize;i++,cnti++) { dxf->xform[cnti][1][1] = 1.0; } } }}static void EstMLLRMeanXForm(AccStruct *accs, LinXForm *xf){ DMatrix invG,u,v; DVector w; SMatrix A; SVector bias; int i,j,k,dim; int cnti,b,bsize; Boolean uBias; bias = xf->bias; if (bias==NULL) uBias = FALSE; else uBias = TRUE; for (b=1,cnti=1;b<=IntVecSize(accs->blockSize);b++) { if ((enableBlockAdapt == NULL) || (enableBlockAdapt[b] == 1)) { bsize = accs->blockSize[b]; if (uBias) dim = bsize+1; else dim = bsize; /* set up the matrices for the inversion */ invG = CreateDMatrix(&gstack,dim,dim); u = CreateDMatrix(&gstack, dim, dim); v = CreateDMatrix(&gstack, dim, dim); w = CreateDVector(&gstack, dim); /* and the transforms to be estimated */ A = xf->xform[b]; ZeroMatrix(A); for (i=1;i<=bsize;i++,cnti++) { Tri2DMat(accs->G[cnti],invG); InvSVD(invG, u, w, v, invG); for (j=1;j<=bsize;j++) for (k=1;k<=dim;k++) A[i][j] += invG[j][k] * accs->K[cnti][k]; if (uBias) { bias[cnti]=0; for (k=1;k<=dim;k++) bias[cnti] += invG[dim][k] * accs->K[cnti][k]; } } FreeDMatrix(&gstack,invG); } else { bsize = accs->blockSize[b]; A = xf->xform[b]; ZeroMatrix(A); for (i=1;i<=bsize;i++,cnti++) { A[i][i] = 1.0; if (uBias) bias[cnti] = 0.0; } } }}static double GetAlphaLike(double a, double b, double c, double alpha){ return (-c*log(fabs(alpha*a+b))-(alpha*alpha*a)/2);}static double GetAlpha(DMatrix invgmat,DVector kmat,double occ, DVector cofact){ int bsize, dim, i ,j; DVector tvec; double a, b, c, tmp; double alpha1, alpha2, like1, like2; bsize= DVectorSize(cofact); dim = DVectorSize(kmat); tvec = CreateDVector(&gstack,dim); ZeroDVector(tvec); for (i=1;i<=dim;i++) for (j=1;j<=bsize;j++) tvec[i] += cofact[j]*invgmat[i][j]; /* Now set up the quadratic equation */ a=0;b=0;c=-occ; for (i=1;i<=bsize;i++) { a += tvec[i]*cofact[i]; b += tvec[i] * kmat[i]; } if(bsize != dim) b += tvec[dim] * kmat[dim]; /* Must by definition be real */ tmp = (b*b-4*a*c); if (tmp<0) { HError(-1,"WARNING: accumulates incorrect (%f < 0) - resetting",tmp); tmp=0; } tmp = sqrt(tmp); /* Now get the possible values of alpha */ alpha1 = (-b+tmp)/(2*a); alpha2 = (-b-tmp)/(2*a); like1 = GetAlphaLike(a,b,c,alpha1); like2 = GetAlphaLike(a,b,c,alpha2); if (like2>like1) return alpha2; else return alpha1;}static double GetRowLike(DMatrix gmat,DVector kmat, DVector cofact, double occ, DVector w){ double rowLike, det; int i, j, size,size2; DVector tvec; DMatrix tmat; size = DVectorSize(w); size2 = DVectorSize(cofact); tvec = CreateDVector(&gstack,size); tmat = CreateDMatrix(&gstack,size,size); Tri2DMat(gmat,tmat); ZeroDVector(tvec); for (i=1;i<=size;i++) for (j=1;j<=size;j++) tvec[i] += w[j]*tmat[i][j]; rowLike = 0; for (i=1;i<=size;i++) rowLike += (tvec[i] - 2*kmat[i])*w[i]; det=0; for (i=1;i<=size2;i++) det += cofact[i]*w[i]; rowLike = log(fabs(det))*occ - rowLike/2; FreeDVector(&gstack,tvec); return rowLike;}static void InitCMLLRXForm(AccStruct *accs, DVector W, DVector bias){ DMatrix invG,u,v,lG; int i,k,dim,ldim; int cnt, cnti,b,bsize; Boolean uBias; double alpha,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -