📄 hadapt.c
字号:
if (rt->vSize != bSize*rt->nBlocks) HError(7425, "InitialiseRegTrans: Blocksize of %d incompatible with vector size %d\n", bSize, rt->vSize); /* get hold of the regression tree from the macro structure holding it! */ for (n=0,h=0; h<MACHASHSIZE; h++) { for (m=hset->mtab[h]; m!=NULL; m=m->next) if (m->type == 'r') break; if (m != NULL) break; } if (m != NULL) rtree = (RegTree *) m->structure; rt->hset = hset; if (hset->hmmSetId == NULL) HError(7421, "InitialiseRegClasses: MMF does not contain any identifier;\nUse HHEd to generate one\n"); if (rtree == NULL) HError(7422, "InitialiseRegClasses: MMF does not contain a regression class tree;\nUse HHEd to generate one\n"); /* only class kind available to set */ rt->classKind = ADPTTREE; rt->rtree = rtree; /* allocate further memory requirements to the tree */ AllocBaseMembers(rt); /* Now the regression classes are known, group the mixtures into linked lists for each regression class */ GroupRegMixes(hset, rt); AttachBaseformsToTree(rtree, rt); if (trace & T_RIO) { PrintTree(rtree, rt); }}/* EXPORT->InitialiseTransform: Initialise transforms storage and grouping of hmmset components to regression base class using linked lists */void InitialiseTransform( HMMSet *hset, MemHeap *x, RegTransInfo *rt, Boolean adapt ){ int vSize, bSize; TransformId *tId; HSetKind hsKind; int L; /* number of logical HMM's */ int P; /* number of physical HMM's */ /* set the block size and the regression class type */ /* if block size is not set; use config variable/default */ /* will be overriden by number of blocks in tmf if a tmf is read in */ if (rt->nBlocks == 0) rt->nBlocks = blocks; /* if regression class type is undefined; use config variable/default */ if (rt->classKind == ADPTUNDEF) rt->classKind = regClass; /* if regression transform type is undefined; use config variable/default */ if (rt->transKind == TRANSUNDEF) { if (initVar) rt->transKind = MEANVAR; else rt->transKind = MEANONLY; } /* if the occupation threshold is not set; use config/default */ if (rt->nodeOccThresh == 0.0) rt->nodeOccThresh = occThreshInit; rt->hmem = x; rt->transId = NULL; vSize = rt->vSize =(int)(hset->vecSize); if (rt->adptSil == TRI_UNDEF) rt->adptSil = (TriState) initAdptSil; /* set this for the time being */ /* rt->adptSil = TRUE; */ hsKind = hset->hsKind; P = hset->numPhyHMM; L = hset->numLogHMM; if (trace&T_TOP) { printf("System is "); switch (hsKind){ case PLAINHS: printf("PLAIN\n"); break; case SHAREDHS: printf("SHARED\n"); break; case TIEDHS: case DISCRETEHS: HError(7450, "HAdapt: Can only adapt PLAIN and SHARED systems"); printf("%d Logical/%d Physical Models Loaded, VecSize=%d\n", L,P,vSize); if (hset->numFiles>0) printf("%d MMF input files\n",hset->numFiles); } } /* create an internal heap used for the transform structures */ CreateHeap(&rt->transMem, "transMem", CHEAP, 1, 0.25, 0, 0); /* allocate space for SVD matrices and vector for bwd transforms */ svdMat1 = CreateDMatrix(rt->hmem, vSize, vSize); u1 = CreateDMatrix(rt->hmem, vSize, vSize); v1 = CreateDMatrix(rt->hmem, vSize, vSize); w1 = CreateDVector(rt->hmem, vSize); /* allocate space for blkZ & blkG */ bSize = vSize/(rt->nBlocks); blkZ = CreateDMatrix(rt->hmem, bSize, bSize+1); blkG = CreateDMatrix(rt->hmem, bSize+1, bSize+1); blku = CreateDMatrix(rt->hmem, bSize+1, bSize+1); blkv = CreateDMatrix(rt->hmem, bSize+1, bSize+1); blkw = CreateDVector(rt->hmem, bSize+1); /* allocate space for the transform information identifier */ tId = (TransformId *) New(x, sizeof(TransformId)); tId->uid = (char *) New(x, MAXSTRLEN); tId->name = (char *) New(x, MAXSTRLEN); tId->rcId = (char *) New(x, MAXSTRLEN); tId->chan = (char *) New(x, MAXSTRLEN); tId->desc = (char *) New(x, MAXSTRLEN); tId->uid[0] = 0; tId->name[0] = 0; tId->rcId[0] = 0; tId->chan[0] = 0; tId->desc[0] = 0; rt->transId = tId; /* attach hooks onto mix means for regression statistics accumulation */ AttachRegAccs(hset, rt->hmem, rt->transKind, rt->vSize); /* Load in the regression classes group the mixtures based on classes */ InitialiseRegClasses(hset, rt); if (trace & T_MEM) { printf("Basic transform initialisation done\n"); PrintHeapStats(rt->hmem); fflush(stdout); } /* allocate space for the regression statistics at the base class level, if adaptation is to take place */ /*if (adapt) for (i = 1; i <= rt->nBaseTransforms; i++) CreateBaseformAccStorage(rt->baseforms[i], rt);*/ /* Count of the number mixture components present at each node in tree */ GetNodeComps(rt->rtree, rt);}/* EXPORT->InitialiseAdapt: Initialise adaptation storage */void InitialiseAdapt(HMMSet *hset, MemHeap *x, RegTransInfo *rt ){ int i, vSize; vSize = rt->vSize; /* create an internal heap used for accumulating statistics at the MixPDF level */ CreateHeap(&rt->pdfStatsMem, "pdfMem", MHEAP, (vSize+1)*sizeof(float), 0.25, 500, 1000); /* allocate space for SVD matrices and vector */ svdMat = CreateDMatrix(rt->hmem, vSize+1, vSize+1); u = CreateDMatrix(rt->hmem, vSize+1, vSize+1); v = CreateDMatrix(rt->hmem, vSize+1, vSize+1); w = CreateDVector(rt->hmem, vSize+1); /* create temporary matrices to sum the regression level accumulates */ Wg = CreateMatrix(rt->hmem, vSize, vSize); Gg = (Matrix *) New(rt->hmem, vSize * sizeof(Matrix)); --Gg; for (i = 1; i <= vSize; i++) { Gg[i] = CreateMatrix(rt->hmem, vSize+1, vSize+1); ZeroMatrix(Gg[i]); } Zg = CreateMatrix(rt->hmem, vSize, vSize+1); Hg = CreateVector(rt->hmem, vSize); ZeroMatrix(Zg); ZeroVector(Hg); ZeroMatrix(Wg); /* allocate space for the regression statistics at the base class level if not already allocated */ for (i = 1; i <= rt->nBaseTransforms; i++) if (rt->baseforms[i]->Z == NULL) CreateBaseformAccStorage(rt->baseforms[i], rt); if (trace & T_MEM) { printf("Transform + adaptation initialisation done\n"); PrintHeapStats(rt->hmem); fflush(stdout); }}/* ----------------------------------------------------------------------*//* Accumulate and Clear Adaptation Statistics *//* ----------------------------------------------------------------------*//* EXPORT->AccAdaptFrame: Accumulate frame stats into specific mixture comp */void AccAdaptFrame(double Lr, Vector speechVec, MixPDF *mp, RegTransInfo *rt) { RegAcc *ra; int k; int vSize; vSize = VectorSize(speechVec); /* get hold of the regression stats hook */ ra = GetRegAcc(mp); if (ra != NULL) { if (ra->obsSum == NULL) CreateRegAccStorage(ra, rt); ra->occ += Lr; for (k = 1; k <= vSize; k++) { ra->obsSum[k] += Lr * speechVec[k]; if (rt->transKind & MEANVAR) ra->obsSqSum[k] += Lr * speechVec[k] * speechVec[k]; } } else HError(7431, "AccAdaptFrame: Problem adding a frame of reg accumulation at the component level"); }/* EXPORT->ClearRegCompStats: Clear for regression level accumulated stats */void ClearRegCompStats(HMMSet *hset, RegTransInfo *rt) { HMMScanState hss; RegAcc *ra; /* zero the occupation counts */ NewHMMScan(hset,&hss); do { while (GoNextState(&hss,TRUE)) { while (GoNextStream(&hss,TRUE)) { if (hss.isCont) /* PLAINHS or SHAREDHS */ while (GoNextMix(&hss,TRUE)) { ra = GetRegAcc(hss.mp); if (ra->obsSum != NULL) { ra->occ = 0.0; ra->obsSum = NULL; ra->obsSqSum = NULL; } } else HError(7450, "ClearRegCompStats: Only available for PLAIN or SHARED systems!"); } } } while (GoNextHMM(&hss)); EndHMMScan(&hss); /* reset the heap holding all the summed scaled speech vectors */ ResetHeap(&rt->pdfStatsMem);}/* EXPORT->ClearBaseClassStats: Clear for base class level accumulated stats */void ClearBaseClassStats(RegTransInfo *rt) { int i, j, vSize; BaseformAcc *b; vSize = rt->vSize; /* clear the base class stats */ for (i = 1; i <= rt->nBaseTransforms; i++) { b = rt->baseforms[i]; for (j = 1; j <= vSize; j++) { ZeroBlockTriMat(b->G[j]->a); ZeroVector(b->G[j]->b); } ZeroBlockMat(b->Z->a); ZeroVector(b->Z->b); ZeroVector(b->H); /* also need to clear the base node occupations for the dynamic tree */ b->occ = 0.0; }}/* ----------------------------------------------------------------------*//* Mean and Covariance Transformation Functions *//* ----------------------------------------------------------------------*//* ---------------------- TRANSFORM MEANS -------------------------------*/ /* Apply the mean tranformation to all components in this regression class */static void ApplyMeanClassTransform(HMMSet *hset, BaseformAcc *base, OffsetBMat *m, int nodeId) { int i, j, n, vSize; MixPDF *mp=NULL; int nTransformed = 0; SVector mean; BlockMatrix a; Vector b; vSize = VectorSize(base->pdfList[1]->mean); n = base->nComponents; /* apply mean transform to all means in base class that have not been seen */ for (j = 1; j <= n; j++) { mp = base->pdfList[j]; mean = mp->mean; if (!IsSeenV(mean)) { a = m->a; b = m->b; MultBlockMat_Vec(a, mean, mean); for (i = 1; i <= vSize; i++) mean[i] += b[i]; /* mark as seen */ TouchV(mean); nTransformed += 1; } } /* unmark all the means in this base class */ for (i = j; j <= n; j++) { mp = base->pdfList[j]; mean = mp->mean; if (IsSeenV(mean)) UntouchV(mean); } if (trace&T_TRA) { printf("There were %d transformations for regression node class %d\n", nTransformed, nodeId); fflush(stdout); }}/* apply mean tranform at node n to the regression sub-tree t */static void ApplyMeanTrans(RegTree *t, RegNode *n, RegTransInfo *rt) { short idx; if (t != NULL) { ApplyMeanTrans(t->left, n, rt); if (t->left == NULL) { /* terminal node -- corresponds to base class */ idx = t->nodeInfo->bases[1]; if (rt->adptSil || rt->baseforms[idx]->speechFlag) { if (trace&T_USE) { printf("Applying transform at nd %d to components at nd %d (%f)\n", n->nodeIndex, t->nodeInfo->nodeIndex, t->nodeInfo->nodeOcc); fflush(stdout); } ApplyMeanClassTransform(rt->hset, rt->baseforms[idx], n->WTrans, t->nodeInfo->nodeIndex); } } ApplyMeanTrans(t->right, n, rt); }}/* EXPORT->ApplyMeanTransforms: Apply the mean transform to regression classes */void ApplyMeanTransforms(RegTransInfo *rt, RegTree *t){ short idx; Boolean adaptSil; float nodeOccThresh; int vSize; RegNode *n; vSize = rt->vSize; nodeOccThresh = rt->nodeOccThresh; adaptSil = (Boolean) rt->adptSil; /* apply the transform, given the occupation count at each node if the child occupation count is above the the threshold then move down the tree, otherwise apply the current node's */ if (t != NULL) { ApplyMeanTransforms(rt, t->left); if (t->nodeInfo->nodeOcc > nodeOccThresh && t->nodeInfo->nodeComps > vSize) { n = t->nodeInfo; if (t->left != NULL) { if (CheckNodeOcc(t->left, NULL, rt)) ApplyMeanTrans(t->left, n, rt); if (CheckNodeOcc(NULL, t->right, rt)) ApplyMeanTrans(t->right, n, rt); } else { /* terminal node -- corresponds to base class */ idx = t->nodeInfo->bases[1]; if (adaptSil || rt->baseforms[idx]->speechFlag) { ApplyMeanClassTransform(rt->hset, rt->baseforms[idx], n->WTrans, n->nodeIndex); if (trace&T_USE) { printf("Applying transform at nd %d to comps at nd %d (%f)\n", n->nodeIndex, t->nodeInfo->nodeIndex, t->nodeInfo->nodeOcc); fflush(stdout); } } } } ApplyMeanTransforms(rt, t->right); }}/* ---------------------- TRANSFORM COVARIANCES -------------------------*//* apply the covariance tranformation to a regression class */static void ApplyCovarClassTransform(HMMSet *hset, BaseformAcc *base, Vector H, int nodeId) { int i, j, n, vSize; MixPDF *mp=NULL; int nTransformed = 0; float hi; SVector var; vSiz
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -