📄 hadapt.c
字号:
else ivar = 1.0/var[k]; sum += ra->obsSqSum[k] * ivar; sum -= 2.0 * ra->obsSum[k] * mean[k] * ivar; sum += ra->occ * mean[k] * mean[k] * ivar; } sum += ra->occ * gconst; *frames += ra->occ; } } return sum;} /* CalcAuxilliary: Calculate the auxilliary function */static float CalcAuxilliary(RegTransInfo *rt) { float prob = 0.0; float frames = 0.0; int i; if (rt->transKind & MEANVAR) { for (i = 1; i <= rt->nBaseTransforms; i++) prob += CalcRegClassAuxilliary(rt->baseforms[i], &frames); printf("\n\tFinal auxilliary = %e, for %d frames\n", -0.5*prob/frames, (int) floor(frames + 0.5)); fflush(stdout); } else HError(-7420, "CalcAuxilliary: Only possible with mean & variance transforms\n"); return prob;}/*------------------------------------------------------------------------*//* Input / Output functions *//*------------------------------------------------------------------------*//* -------------------------- Lexical Scanner --------------------------- *//* --------------------- Mirrors HModel Format -------------------------- */#define MAXSYMLEN 40/* Verbose keywords for readable external MLLR transform format */static char *symMap[] = { "TRANSFORM", "MEAN_TR", "VARIANCE_TR", "BLOCK", "BIASOFFSET", "NODEOCC", "NODETHRESH", "NBLOCKS", "BASESTATS", "LHSACC", "RHSACC", "VARACC", "EOF", ""};/* Internal and binary keyword representation */typedef enum { TRANSFORM, MEAN_TR, VARIANCE_TR, BLOCK, BIASOFFSET, NODEOCC, NODETHRESH, NBLOCKS, BASESTATS, LHSACC, RHSACC, VARACC, EOFSYM, NULLSYM} Symbol;/* ---------------------------------------------------------------------- *//* PutSymbol: output symbol to f in ascii or binary form */static void PutSymbol(FILE *f, Symbol sym, Boolean binary){ if (binary){ fputc(':',f);fputc(sym,f); } else fprintf(f,"<%s>",symMap[sym]);}/* GetSymbol: read in a symbol in ascii or binary form */static Boolean GetSymbol(Source *src, Symbol *sym){ int i, c, imax; char buf[MAXSYMLEN]; Symbol s; while (isspace(c=GetCh(src))); /* Look for symbol */ if (c != '<' && c != ':') { if (c == EOF) { *sym=EOFSYM; return FALSE; } HError(7440, "GetSymbol: Symbol expected"); } i=0; imax = MAXSYMLEN-1; if (c=='<') { /* Read verbose symbol string into buf */ while ((c=GetCh(src)) != '>' && i<imax) buf[i++] = islower(c)?toupper(c):c; buf[i] = '\0'; if (c != '>') HError(7440,"GetSymbol: > missing in symbol"); for (s=TRANSFORM; s<=VARACC; s=(Symbol) (s+1)) /* Look symbol up in symMap */ if (strcmp(symMap[s],buf) == 0) { *sym = s; return FALSE; /* and return */ } } else { /* Read binary symbol into buf */ s = (Symbol) GetCh(src); if (s>=TRANSFORM && s<=VARACC) { *sym = s; return TRUE; /* and return */ } } return FALSE;}static void SaveNodeTransform(FILE *fp, RegTransInfo *rt, OffsetBMat *MTrans, Vector HTrans, short nodeId){ short n, i; short bSize; short size; Matrix m; size = (short) rt->vSize; bSize = size / rt->nBlocks; /* print the node id */ PutSymbol(fp, TRANSFORM, writeBin); WriteShort(fp, &nodeId, 1, writeBin); if (!writeBin) fputc('\n', fp); /* save the mean transformation */ PutSymbol(fp, MEAN_TR, writeBin); WriteShort(fp, &bSize, 1, writeBin); if (!writeBin) fputc('\n', fp); if (bSize * rt->nBlocks != size) HError(7440, "Illegal number of blocks! Vector size %d, blocksize %d!", size, rt->nBlocks); /* save the mean matrix transform */ for (n = 1; n <= rt->nBlocks; n++) { m = MTrans->a[n]; PutSymbol(fp, BLOCK, writeBin); WriteShort(fp, &n, 1, writeBin); if (!writeBin) fputc('\n', fp); for (i = 1; i <= bSize; i++) WriteVector(fp, m[i], writeBin); } /* save the mean bias vector */ PutSymbol(fp, BIASOFFSET, writeBin); WriteShort(fp, &size, 1, writeBin); if (!writeBin) fputc('\n', fp); WriteVector(fp, MTrans->b, writeBin); /* save the covariance transform vector */ if (rt->transKind & MEANVAR) { PutSymbol(fp, VARIANCE_TR, writeBin); WriteShort(fp, &size, 1, writeBin); if (!writeBin) fputc('\n', fp); WriteVector(fp, HTrans, writeBin); }}static void SaveTransforms(FILE *fp, RegTree *t, RegTransInfo *rt){ RegNode *n; if (t != NULL) { SaveTransforms(fp, t->left,rt); if ( t->nodeInfo->nodeOcc > rt->nodeOccThresh && t->nodeInfo->nodeComps > rt->vSize ) { n = t->nodeInfo; if (t->left != NULL) { if (CheckNodeOcc(t->left, t->right, rt)) SaveNodeTransform(fp, rt, n->WTrans, n->HTrans, n->nodeIndex); } else SaveNodeTransform(fp, rt, n->WTrans, n->HTrans, n->nodeIndex); } SaveTransforms(fp, t->right, rt); }}static void SaveNodeOcc(FILE *fp, RegTree *t){ RegNode *n; if (t != NULL) { SaveNodeOcc(fp, t->left); n = t->nodeInfo; PutSymbol(fp, NODEOCC, writeBin); WriteShort(fp, &(n->nodeIndex), 1, writeBin); WriteFloat(fp, &(n->nodeOcc), 1, writeBin); if (!writeBin) fputc('\n', fp); SaveNodeOcc(fp, t->right); }}/* SaveTransformSetHeader: Save the header information */void SaveTransformSetHeader(FILE *file, HMMSet *hset, RegTransInfo *rt, char *uid, char *uname, char *chan, char *desc, Boolean global, Boolean writeBin){ MLink m; int n, h; /* get hold of the regression tree macro identifier (if it exists) */ 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; } /* save the transform headers */ /* user id */ if (uid == NULL || strlen(uid) == 0) HError(7440, "SaveTransformSetHeader:Must specify a user id for the tmf header field <UID>!"); fprintf(file, "<UID> %s\n", uid); /* save full name if available */ if (uname == NULL || strlen(uname) == 0) fprintf(file, "<NAME> %s\n", undefined); else fprintf(file, "<NAME> %s\n", uname); /* mmf id */ fprintf(file, "<MMFID> %s\n", hset->hmmSetId==NULL?"Unset":hset->hmmSetId); /* regression class type identifier */ if (m == NULL || global) fprintf(file, "<RCID> global\n"); else fprintf(file, "<RCID> %s\n", m->id->name); /* channel/microphone type */ if (chan == NULL || strlen(chan) == 0) fprintf(file, "<CHAN> %s\n", undefined); else fprintf(file, "<CHAN> %s\n", chan); /* Store a general description field */ if (desc == NULL || strlen(desc) == 0) fprintf(file, "<DESC> %s\n", undefined); else fprintf(file, "<DESC> %s\n", desc); PutSymbol(file, NBLOCKS, writeBin); WriteShort(file, &(rt->nBlocks), 1, writeBin); if (!writeBin) fputc('\n', file); /* fprintf(file, "<NBLOCKS> %d\n", rt->nBlocks); */ PutSymbol(file, NODETHRESH, writeBin); WriteFloat(file, &rt->nodeOccThresh, 1, writeBin); if (!writeBin) fputc('\n', file);}/* EXPORT->SaveTransformSet: Save the transforms to a file */void SaveTransformSet(HMMSet *hset, RegTransInfo *rt, char *saveFile, char *transPath, char *uid, char *uname, char *chan, char *desc, Boolean saveStats, Boolean global, Boolean saveBinary){ FILE *file; RegTree *rtree; char tfile[256]; rtree = rt->rtree; writeBin |= saveBinary; /* create a transform file, made up of MMF name and a user's id */ MakeFN(saveFile, transPath, NULL, tfile); if ((file=fopen(tfile,"w"))==NULL) HError(7440, "SaveTransformsSet: Cannot save transform file %s", tfile); if (trace & T_TOP) { printf("Saving transforms to %s\n", tfile); } SaveTransformSetHeader(file, hset, rt, uid, uname, chan, desc, global, writeBin); SaveNodeOcc(file, rtree); if (global) SaveNodeTransform(file, rt, rt->rtree->nodeInfo->WTrans, rt->rtree->nodeInfo->HTrans, rt->rtree->nodeInfo->nodeIndex); else { /* always save a root node transform, so see if it will be produced by the SaveTransforms function -- if not then call SaveNodeTransform */ if (rt->rtree->left != NULL) { if (rt->rtree->left->nodeInfo->nodeOcc > rt->nodeOccThresh && rt->rtree->right->nodeInfo->nodeOcc > rt->nodeOccThresh && rt->rtree->left->nodeInfo->nodeComps >= rt->vSize && rt->rtree->right->nodeInfo->nodeComps >= rt->vSize) SaveNodeTransform(file, rt, rt->rtree->nodeInfo->WTrans, rt->rtree->nodeInfo->HTrans, rt->rtree->nodeInfo->nodeIndex); } SaveTransforms(file, rtree, rt); } if (saveStats) HError(-7440, "SaveTransformsSet: Saving adaptation statistics is not available!"); fclose(file);}static void GetMeanTransformSet(Source *src, RegNode *node, MemHeap *x, short vSize, short nBlocks, RegTransType transKind, Boolean binary){ int i, n; short bSize, bNum; BlockMatrix a; Matrix m = NULL; Symbol sym; if (!ReadShort(src, &bSize, 1, binary)) HError(7440, "GetMeanTransformSet: expected mean vector block size"); /* check that the transform has been created -- if not create! */ if (node->WTrans == NULL) CreateNodeTransform(node, x, transKind, (int) vSize, (int) nBlocks); a = node->WTrans->a; for (n = 1; n <= nBlocks; n++) { binary = GetSymbol(src, &sym); if (sym != BLOCK) HError(7440, "GetMeanTransformSet: expected BLOCK symbol\n"); if (!ReadShort(src, &bNum, 1, binary)) HError(7440, "GetMeanTransformSet: expected block number"); if (n == bNum) m = a[n]; else HError(7440, "GetMeanTransformSet: Expected the block %d", n); for (i = 1; i <= bSize; i++) { if (!ReadVector(src, m[i], binary)) HError(7440, "GetMeanTransformSet: Mean transform row %d expected", i+n*bSize); } }}static void GetBiasOffset(Source *src, RegNode *node, Boolean binary){ short size; Vector v; if (!ReadShort(src, &size, 1, binary)) HError(7440, "GetBiasOffset: expected bias offset size"); v = node->WTrans->b; if (!ReadVector(src, v, binary)) HError(7440, "GetBiasOffset: expected bias offset vector");}static void GetCovarTransformSet(Source *src, RegNode *node, Boolean useVar, Boolean binary){ int i; short size; Vector v, covar; if (!ReadShort(src, &size, 1, binary)) HError(7440, "GetCovarTransformSet: expected covariance transform vector size"); v = CreateVector(&gstack, size); covar = node->HTrans; if (!ReadVector(src, v, binary)) HError(7440, "GetCovarTransformSet: expected covariance transform vector"); if (useVar) for (i = 1; i <= size; i++) covar[i] = v[i]; FreeVector(&gstack, v);}static Boolean LoadTransforms(Source *src, RegTransInfo *rt, Symbol *s){ RegTree *t; RegNode *n; float tmp; Symbol sym; Boolean useVar=FALSE, varThere=FALSE; Boolean binary=FALSE; short nodeId, nblocks, bsize; /* load the number of blocks */ binary = GetSymbol(src, &sym); if (sym != NBLOCKS) { HError(7440, "LoadTransforms: expected NBLOCKS symbol, not %s", symMap[sym]); } if (!ReadShort(src, &nblocks, 1, binary)) HError(7440, "LoadTransforms: expected the number of blocks in block diagonal matrices"); /* check blockSize */ bsize = rt->vSize/nblocks; if (rt->vSize != bsize*nblocks) HError(7440, "LoadTransforms: Blocksize in tmf of %d incompatible with vector size %d\n", bsize, rt->vSize); if (nblocks != rt->nBlocks) HError(-7440, "LoadTransforms: Using no. of blocks specified in tmf (%d) which differs from the default, command-line or config setting!", nblocks); /* override any setting of number of blocks with number of blocks in tmf */ rt->nBlocks = nblocks ; /* Load the occupation threshold and the node occupation counts */ binary = GetSymbol(src, &sym); if (sym != NODETHRESH) HError(7440, "LoadTransforms: expected NODETHRESH symbol, not %s", symMap[sym]); /* if the occupation threshold is not set in the config file use saved one */ if (strcmp(rt->transId->rcId, "global") != 0) { if (!ReadFloat(src, &rt->nodeOccThresh, 1, binary)) HError(7440, "LoadTransforms: expected a node occ threshold value"); } else if (!ReadFloat(src, &tmp, 1, binary)) HError(7440, "LoadTransforms: expected a node occ threshold value"); binary = GetSymbol(src, &sym); while (sym == NODEOCC) { if (!ReadShort(src, &nodeId, 1, binary)) HError(7440, "LoadTransforms: expected a node index"); t = FindNode(rt->rtree, NULL, nodeId); if (t==NULL) HError(7430, "LoadTransforms: Can't find node %d in tree\n", nodeId); if (!ReadFloat(src, &(t->nodeInfo->nodeOcc), 1, binary)) HError(7440, "LoadTransforms: expected a node occ count for node %d", nodeId);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -