⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hlat.c

📁 隐马尔科夫模型工具箱
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ----------------------------------------------------------- *//*                                                             *//*                          ___                                *//*                       |_| | |_/   SPEECH                    *//*                       | | | | \   RECOGNITION               *//*                       =========   SOFTWARE                  */ /*                                                             *//*                                                             *//* ----------------------------------------------------------- *//* developed at:                                               *//*                                                             *//*      Speech Vision and Robotics group                       *//*      Cambridge University Engineering Department            *//*      http://svr-www.eng.cam.ac.uk/                          *//*                                                             *//* author: Gunnar Evermann <ge204@eng.cam.ac.uk>               *//* ----------------------------------------------------------- *//*         Copyright:                                          *//*         2001-2002  Cambridge University                     *//*                    Engineering Department                   *//*                                                             *//*   Use of this software is governed by a License Agreement   *//*    ** See the file License for the Conditions of Use  **    *//*    **     This banner notice must not be removed      **    *//*                                                             *//* ----------------------------------------------------------- *//*       File: HLat.c:  Lattice Manipulation                   *//* ----------------------------------------------------------- *//*#### todo:     - implement lattice oracle WER calculation     - allow batch processing?*/char *hlat_version = "!HVER!HLat:   3.2 [CUED 09/12/02]";char *hlat_vc_id = "$Id: HLat.c,v 1.3 2002/12/19 16:37:11 ge204 Exp $";#include "HShell.h"#include "HMem.h"#include "HMath.h"#include "HWave.h"#include "HAudio.h"#include "HParm.h"#include "HLabel.h"#include "HModel.h"#include "HUtil.h"#include "HDict.h"#include "HNet.h"#include "HLM.h"#include "HLat.h"/* ----------------------------- Trace Flags ------------------------- */#define T_TOP  00001#define T_PRUN 00002#define T_FB   00004#define T_EXP  00010#define T_MEM  00020#define T_TRAN 00040static int trace=0;static ConfParam *cParm[MAXGLOBS];      /* config parameters */static int nParm = 0;/* --------------------------- Global Flags -------------------------- */static LabId startWord;         /* word at start of Lattice (!SENT_START) */static LabId endWord;           /* word at end of Lattice (!SENT_END) */static LabId startLMWord;       /* word at start in LM (<s>) */static LabId endLMWord;         /* word at end in LM (</s>) */static LabId nullWord;          /* null word in Lattices (!NULL) */static MemHeap slaHeap, slnHeap;/* MHEAPs for use in LatExpand() *//* --------------------------- Prototypes ---------------------------- */#ifndef NO_LAT_LMtypedef struct _SubLNode SubLNode;typedef struct _SubLArc SubLArc;struct _SubLNode {   union {      LMState lmstate;      LNode *newln;   } data;   SubLArc *foll;   SubLNode *next;};struct _SubLArc {   LogFloat lmprob;   SubLNode *end;   LArc *la;   SubLArc *next;};#endif/* --------------------------- Initialisation ---------------------- *//* EXPORT->InitLat: register module & set configuration parameters */void InitLat(void){   int i;   Register(hlat_version,hlat_vc_id);   nParm = GetConfig("HLAT", TRUE, cParm, MAXGLOBS);   if (nParm>0){      if (GetConfInt(cParm,nParm,"TRACE",&i)) trace = i;   }#ifndef NO_LAT_LM   CreateHeap (&slaHeap, "LatExpand arc heap", MHEAP, sizeof (SubLArc), 1.0, 1000, 128000);   CreateHeap (&slnHeap, "LatExpand node heap", MHEAP,sizeof (SubLNode), 1.0, 1000, 32000);#endif}/* --------------------------- Lattice processing ------------------- *//* LatCheck     check lattice for consistency: single start & end nodes; no cycles.*/void LatCheck (Lattice *lat){   int i, nStart, nEnd;   LNode *ln;   LNode **topOrder;   /* check for unique start and end nodes */   nStart = nEnd = 0;   for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln) {      if (!ln->pred)         ++nStart;      if (!ln->foll)         ++nEnd;   }   if (nStart != 1)      HError (8622, "HLat: lattice has %d start nodes (should be 1)", nStart);   if (nEnd != 1)      HError (8622, "HLat: lattice has %d end nodes (should be 1)", nEnd);   /* check wheter lat is a DAG ( <=> top order exists). */   topOrder = (LNode **) New (&gcheap, lat->nn * sizeof(LNode *));   if (!LatTopSort (lat, topOrder))      HError (8622, "HLat: lattice contains cylces");   Dispose (&gcheap, topOrder);}/* FixPronProbs     replace pronunciation probabilities in lattices with values taken from     the dictionary*/void FixPronProbs (Lattice *lat, Vocab *voc){   int i, v;   LNode *ln;   Pron pron;   LArc *la;   for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln) {      if (ln->word != voc->nullWord) {         if (ln->v > ln->word->nprons)            HError (8621, "FixPronprbs: lattice refers to non-existing pron");         pron = ln->word->pron;         for (v = 2; v <= ln->v; ++v)            pron = pron->next;         if (pron->pnum != ln->v)            HError (8621, "FixPronprbs: dict pron numbering invalid");                  for (la = ln->pred; la; la = la->parc)            la->prlike = pron->prob;      }      else {         for (la = ln->pred; la; la = la->parc)            la->prlike = 0.0;      }   }}/* LatStartNode     return lattice start node     ###GE: maybe store this in Lattice structure to save time?*/LNode *LatStartNode (Lattice *lat){   int i;   LNode *ln;   for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln)      if (!ln->pred)         return ln;   HError (8622, "HLat: lattice has no start node");   return NULL;         /* make compiler happy */}/* LatEndNode     return lattice end node     ###GE: maybe store this in Lattice structure to save time?*/LNode *LatEndNode (Lattice *lat){   int i;   LNode *ln;   for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln)      if (!ln->foll)         return ln;   HError (8622, "HLat: lattice has no end node");   return NULL;         /* make compiler happy */}/* helper function for LatTopSort()   number preceeding nodes depth first */void LatTopSortVisit (LNode *ln, int *time){   LArc *la;   ln->n = -2;          /* mark node as seen, but not numbered, yet (GRAY in CLR) */   for (la = ln->pred; la; la = la->parc)      if (la->start->n == -1)         LatTopSortVisit (la->start, time);      ++(*time);   ln->n = *time;}/* LatTopSort     sort lattice nodes in topological order     returns array of LNode pointers.     uses depth first traversal (in reverse (pred) direction)      based on [CLR:1990], p. 485 */Boolean LatTopSort (Lattice *lat, LNode **topOrder){   int time = -1;       /* new numbering will start at 0 */   int i;   LNode *ln;   LArc *la;   Boolean isDAG = TRUE;   for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln)      ln->n = -1;        /* mark node as unseen (WHITE in CLR) */   LatTopSortVisit (LatEndNode (lat), &time);      /* we should have seen all nodes */   assert (time+1 == lat->nn);    /* check topological order */   for (i = 0, la = lat->larcs; i < lat->na; ++i, ++la)      if (!(la->start->n < la->end->n)) {         isDAG = FALSE;         HError (-8622, "LatTopSort: Lattice contains cycles");          break;      }   for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln)      topOrder[ln->n] = ln;      /*#### GE: reset ln->n values? */   for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln)      ln->n = i;   return isDAG;}/* LatAttachInfo     allocate & attach an Info structre for each node*/void LatAttachInfo (MemHeap *heap, size_t size, Lattice *lat){   int i;   LNode *ln;      for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln)      ln->hook = (Ptr) New (heap, size);}/* LatDetachInfo     free Info structre for each node*/void LatDetachInfo (MemHeap *heap, Lattice *lat){   int i;   LNode *ln;      for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln)      Dispose (heap, ln->hook);}/* LatForwBackw     perform forward-backward algorithm on lattice and store scores in     FBInfo structre     choice of using sum (LATFB_SUM) or max (LATFB_MAX) of scores*/LogDouble LatForwBackw (Lattice *lat, LatFBType type){   int i;   LNode *ln;   LArc *la;   LNode **topOrder;   LogDouble score;   /* We assume that the FBinfo structures are already allocated. */   /* init */   for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln) {      LNodeFw (ln) = LNodeBw (ln) = LZERO;   }   LNodeFw (LatStartNode (lat)) = 0.0;   LNodeBw (LatEndNode (lat)) = 0.0;   /* find topological order of nodes */   topOrder = (LNode **) New (&gcheap, lat->nn * sizeof(LNode *));   if (!LatTopSort (lat, topOrder))      HError (8622, "LatForwBackw: cannot calculate forw/backw score on Lattice with cycles");          /* the processing in the forward and backward directions are really      almost the same. if the data structures had been done _slightly_      nicer this could be done in one loop. The only readable way now       would be defining a couple of macros... */   /* forward direction */   for (i = 0; i < lat->nn; ++i) {      ln = topOrder[i];      for (la = ln->foll; la; la = la->farc) {         assert (la->start == ln);                  score = LNodeFw (ln) + LArcTotLike (lat, la);         switch (type) {         case LATFB_SUM:            LNodeFw (la->end) = LAdd (LNodeFw (la->end), score);            break;         case LATFB_MAX:            if (score > LNodeFw (la->end))               LNodeFw (la->end) = score;            break;         default:            abort ();         }      }   }   /* backward direction */   for (i = lat->nn - 1; i >= 0; --i) {      ln = topOrder[i];      for (la = ln->pred; la; la = la->parc) {         assert (la->end == ln);                  score = LNodeBw (ln) + LArcTotLike (lat, la);         switch (type) {         case LATFB_SUM:            LNodeBw (la->start) = LAdd (LNodeBw (la->start), score);            break;         case LATFB_MAX:            if (score > LNodeBw (la->start))               LNodeBw (la->start) = score;            break;         default:            abort ();         }      }   }   if (trace & T_FB) {      printf ("forward prob:  %f\n", LNodeFw (topOrder[lat->nn - 1]));      printf ("backward prob: %f\n", LNodeBw (topOrder[0]));   }   score = LNodeBw (topOrder[0]);   Dispose (&gcheap, topOrder);   return score;}/* EXPORT->LatFindBest     find the N-best paths (i.e. lowest sum of LArcTotLike()s) and generate     Transcription.     ####GE: currently only N=1 is supported*/Transcription *LatFindBest (MemHeap *heap, Lattice *lat, int N){   int i;   LNode *ln;   LNode **topOrder;   LArc *la;   LogDouble score, ac, lm, pr, tot;   Word nullWord;   Pron pron;   Transcription *trans;   LabList *ll;   LLink lab;      if (N != 1)      HError (8690, "FindBest: only 1-best supported, yet.");   /* during the search ln->score will hold the score of the best      path to ln (i.e. lowest score). ln->hook will point to      the arc leading to the preceeding node in this path */   /* init fields */   for (i = 0, ln = lat->lnodes; i < lat->nn; ++i, ++ln) {      ln->score = LZERO;      ln->hook = NULL;   }   LatStartNode (lat)->score = 0.0;   /* find topological order of nodes */   topOrder = (LNode **) New (&gcheap, lat->nn * sizeof(LNode *));   if (!LatTopSort (lat, topOrder))      HError (8690, "LatFindBest: cannot find best path in Lattice with cycles");   assert (topOrder[0] == LatStartNode (lat));   /* traverse nodes in top order */   for (i = 0; i < lat->nn; ++i) {      ln = topOrder[i];            /* for all outgoing arcs: propagate scores forward */      for (la = ln->foll; la; la = la->farc) {         assert (la->start == ln);         score = la->start->score + LArcTotLike (lat, la);         if (score > la->end->score) {            la->end->score = score;            la->end->hook = (Ptr) la;         }      }   }   /* create traqnscription */   trans = CreateTranscription (heap);   ll = CreateLabelList (heap, 0);      nullWord = lat->voc->nullWord;   ac = lm = pr = tot = 0;   if (trace & T_TRAN)      printf ("1best trans (wordPron t ac lm pr tot): ");   /* backtrack from end node along best path and generate transcription */   ln = LatEndNode (lat);   la = (LArc *) ln->hook;   while (la) {      LabId outlab;      if (ln->word != nullWord) {         for (pron = ln->word->pron; pron; pron = pron->next)            if (pron->pnum == ln->v)                break;         if (pron)            outlab = pron->outSym;         else   /* if we can't find pronvar (e.g. wlist), fall back to word */            outlab = ln->word->wordName;         if (outlab) {            lab = CreateLabel (heap, ll->maxAuxLab);            lab->labid = outlab;            lab->start = la->start->time * 1.0e7;            lab->end = ln->time * 1.0e7;            lab->score = LArcTotLike (lat, la);                        lab->succ = ll->head->succ;            lab->pred = ll->head;            lab->succ->pred = lab->pred->succ = lab;         }      }      ac += la->aclike;      lm += la->lmlike;      pr += la->prlike;      tot += LArcTotLike (lat, la);      if (trace & T_TRAN)         printf ("(%s%d %.2f %.3f %.3f %.3f %.3f) ", ln->word->wordName->name, ln->v,                 ln->time, la->aclike, la->lmlike, la->prlike, LArcTotLike (lat, la));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -