HERest介绍
HTK嵌入式训练主要由HERest来完成,它实现的功能有ML、MAP、Semi-Tied、HLDA、MLLR、CMLLR等,考虑到训练数据量的问题,HERest还支持并行训练,这里介绍最基本的也是最重要的ML训练过程(基于最大似然准则),并且假设HMM是连续的。
一. 数据结构
** HMM Definition相关的数据结构
HMMSet //HMM Sets信息
MLink //Macro信息
HLink //HMMDef信息,包含transition matrix
StateElem //多个状态信息
StateInfo //单个状态信息,包含多流信息
StreamElem //单流信息
MixtureVector //共同体,多个混合分量信息
MixtureElem //单个混合分量信息,包含mixture weight
MixPDF //单个高斯模型参数信息,包含mean vector和covariance matrix or vector
** Accumulators相关的数据结构
TrAcc //transP的累积量,存放在transP的hook中
WtAcc //weight的累积量,存放在StreamElem的hook中
MuAcc //mean的累积量,存放在mean vector的hook中
VaAcc //var的累积量,存放在covariance matrix or vector的hook中
SVector的sv[0]前有两个(void *)大小的内存hook、use,hook是一个指针,use表明这个vector的使用情况,SMatrix类似于SVector,也有use和hook
** Forward-Backward相关的数据结构
FBInfo //存储up和al两种hset并有一个指向AlphaBeta的指针
AlphaBeta //存储当前句子的Q个子词模型以及alpha-beta、occ值
PruneInfo //存储beam、taper相关信息
** MLF相关的数据结构
MLFEntry //存储entry的信息,如果非general,则使用hash
MLFDef //the actual def
ImmDef //存储entry在MLF中的偏移量
** Transcription相关的数据结构
UttInfo //structure for the utterance information
Transcription //当前句子的标注信息
LLink //Information for each label
ParmBuf //当前句子的特征
二. 初始化
** 模型初始化
模型初始化包括读取MMF文件、分配累积量所需空间并初始化、FBInfo初始化以及计算每个模型的最小时长。
1. Initialise()
//模型初始化函数
2. MakeHMMSet(HMMSet *hset, char *fname)
//从mlist中读取phnset来分配hset中mtab[hashval]的内存,如果逻辑模型和物理模型名称相同则mtab[hashval]链表长度是二,第一个Macro类型为'l',第二个Macro类型为'h',并且两个Macro同时指向一个HLink。如果逻辑模型和物理模型名称不相同则mtab[hashval]的链表长度是1,Macro类型为'l'
2. LoadHMMSet(HMMSet *hset, char *hmmDir, char *hmmExt)
//从MMF中按Macro类型取模型参数存入mtab[hashval]中,对于一些共享的Macro比如共享状态、transP也读入按hashval存入mtab中,如果某个phnset包含共享状态,则其mtab[hashval]会指向这个共享的Macro,这些共享的Macro在MMF文件的最前面因此会最先被读入
2. AttachAccs(HMMSet *hset, MemHeap *x, UPDSet uFlags)
//分配uFlags对应的所有累积量的内存
2. ZeroAccs(HMMSet *hset, UPDSet uFlags)
//累积量置零
2. InitialiseForBack()
//Initialise the forward backward memory stacks and make initialisations
3. SetMinDurs(HMMSet *hset)
//根据transP计算每个模型的最小时长,并将其值(单位为帧)存在transP的hook中的minDur中
** 标注、特征初始化及读取
1. LoadMasterFile(char *fname)
//读取MLF文件中的entry信息到全局的mlfHead和mlfTail中,信息还包括entry在整个文件中的偏移量,方便读取标注内容
1. InitUttInfo( UttInfo *utt, Boolean twoFiles )
//Initialise the utterance memory requirements
1. LoadLabs(UttInfo *utt, FileFormat lff, char * datafn, char *labDir, char *labExt)
//装入标注信息,根据datafn从mlfHead中读取其对应的标注内容在MLF文件中的偏移量,再调用LoadHTKLabels()
1. LoadData(HMMSet *hset, UttInfo *utt, FileFormat dff, char * datafn, char * datafn2)
//装入观察序列,存入utt->pbuf->data.main中,变换成targetkind的特征按float字节顺序存储
三. 前后向算法
代码中先进行后向算法StepBack()再进行前向算法StepForward()并进行累计器的更新。
StepBack()的主要过程如下
1. 设置剪枝信息
2. 初始化AlphaBeta数据结构CreateInsts()
3. 设置后向锥SetBeamTaper()
4. 计算后向概率lbeta=SetBeta()
四. ML模型更新