在解析ProcessObservation的代码过程中,遇到了些问题,比如tokenset和token的区别;
在词内的状态间传递时,token的值如何变化,以及整体的一个token pass模型。
/* The instances actually store tokens and links etc */
/* Instances are stored in creation/token propagation order to allow */
/* null/word/tee instances to be connected together and still do propagation */
/* in one pass. Only HMMs need extra tokens, others are 1 state */
struct _NetInst
{
struct _NetInst *link; /* Doubly linked list of instances, forward */
struct _NetInst *knil; /* Doubly linked list of instances, backward */
NetNode *node; /* Position of instance within network */
int flags; /* Flags, active ... */
TokenSet *state; /* TokenSet[0..N-2] in state [1..N-1] for hmm */
TokenSet *exit; /* TokenSet in exit state */
LogFloat wdlk; /* Max likelihood of t=0 path to word end node */
LogFloat max; /* Likelihood for pruning of instance */
Boolean pxd; /* External propagation done this frame */
Boolean ooo; /* Instance potentially out of order */
#ifdef SANITY
int ipos;
#endif
};
再次把这个结构体放在这里,希望每次都能理解得更深刻些。
NetInst对象是与NetNode一一对应的,每个NetNode都包含一个NetInst,当构建好了Network后,其NetNode之间的连接关系也确定了。当构建识别顺序时,各NetInst的关系也确定了。
在precinfo结构体中,有head和tail指向的双向链表,其中的节点就是NetInst,其顺序是关于图Network的节点NetNode的深度优先算法遍历的结果。
而每个NetInst除了包括上下文信息外(双链表的指向关系,前项、后项节点),还包括了模型内的状态信息。
在ProcessObservation中,首先就是处理初始值设置问题,然后依次经过pri的link链表。
现在理解解码的核心问题是,pri对象的head和tail所指向的双向链表的节点代表什么意义?它们是如何选择出来的?为什么选这些?后续的处理逻辑是怎么样的?这几个问题搞明白,语音识别过程大概就彻底得理解了。
-->调用StepInst1(inst->node)
-->判断node是hmm调用StepHMM1(node)
-->判断node是word调用StepWord1(node)
-->调用StepInst2(inst->node)