网站首页 > 开源技术 正文
三音素GMM与单音素GMM的主要差别在于决策树状态绑定,与GMM参数更新相关的原理、程序和类两者都是一样的。
在这个笔记中,我会首先介绍表示HMM的类HmmTopology和TransitionModel,然后介绍三音素GMM训练脚本train_deltas.sh用到的几个程序,这几个程序与单音素GMM的不同或者只在三音素GMM训练中出现。与GMM相关的其余部分请参考单音素GMM学习笔记。
HmmTipology
为什么要介绍HmmTopology(后简称HT)和TransitionModel(后简称TM)?前面我们几乎一直在讲GMM和决策树,那么HMM用什么表示?在Kaldi中用TM表示HMM,TM中包含一个HT对象,用来表示HMM拓扑结构。
在Kaldi数据准备阶段,Kaldi会在data/lang目录下自动生成表示HMM拓扑结构的文件topo,HT对象就保存topo中的信息。一是topo中都有哪些音素,保存在HT的数据成员phone_中;二是每个音素的HMM结构是什么,由HT的数据成员phone2idx_和entries_共同决定。我们用下面一个图来解构HmmTopology的数据成员。
TransitionModel
在单音素GMM初始化程序gmm-init-mono和三音素GMM初始化程序gmm-init-model中都会调用TM构造函数TransitionModel(const ContextDependencyInterface &ctx_dep,const HmmTopology &hmm_topo)来初始化TM。我们也就以此构造函数为切入口,来学习TransitionModel中各数据成员是怎么构造出来的。
我们先来看看TM都有哪些数据成员以及各自的作用:
HmmTopology topo_;
构造函数的调用过程如下两图所示:
下面我们对train_deltas.sh中与三音素GMM相关的几个程序逐个进行说明。
gmm-init-model
?示例:gmm-init-model tree treeacc topo 1.mdl
?作用:使用决策树tree和决策树统计量treeacc初始化GMM。
?流程:
1.读取tree, treeacc, topo。
2.用tree和topo初始化TransitionModel trans_model,trans_model中保存着每个音素和其每个状态对应的pdf-id的Tuple(实际为Triple).
3.调用InitAmGmm()初始化am_gmm;若提供old_tree_filename和old_model_filename,调用InitAmGmmFromOld()初始化am_gmm。在InitAmGmm()中,将stats划分到决策树的每个叶子上(对应一个pdf),用该pdf对应的stats的count_、x、x^2初始化该pdf对应的DiagGmm的参数weight_、means_invvars_、inv_vars_和gconsts_。
4.若指定参数--write-occs=1.occs,调用GetOccs()得到每个pdf对应的state occupancies(也就是该pdf对应的观测的数量,或者说该pdf对应的帧数),将state occupancies写到1.occs
5.将trans_model和am_gmm写到1.mdl,得到初始GMM模型。
gmm-mixup
?示例:gmm-mixup --mix-up=4000 1.mdl 1.occs 2.mdl
gmm-mixup --merge=2000 1.mdl 1.occs 2.mdl
?作用:用来增加GMM混合分量的个数,或合并GMM混合分量。
?流程:
1.从1.mdl里读取trans_model, am_gmm,从1.occs里读取occs。
2.若mixdown!=0,对am_gmm调用MergeByCount();若mixup!=0,对am_gmm调用SplitByCount()。
3.将trans_model和改变后的am_gmm写到1.mdl。
AmDiagGmm::SplitByCount()
根据occs,调用AmDiagGmm::GetSplitTargets()得到am_gmm中每个DiagGmm i应该增加到的混个分量个数targets[i]。GetSplitTargets()对观测数最多的pdf优先增加混合分量个数(使用优先队列实现)。对每个DiagGmm i,根据targets[i],调用DiagGmm::Split()增加该DiagGmm i的混合分量。Split()对混合分量中weights_最大的分量优先进行分割,将其权值对半分,一半留给自己一半分给新的分量,被分割分量的均值、方差相关参数直接复制给新分量,复制完后对新分量的均值、方差相关参数加一个随机的扰动。
convert-ali
由单音素GMM我们得到训练数据的对齐文件,但是单音素GMM中的TransitionModeltm1和三音素GMM中的TransitionModeltm2不同,两者的每个数据成员都不一样,所以要把用tm1的tid(transition-id)表示的对齐转换成tm2的tid表示的对齐。这就是convert-ali的作用。
要看懂convert-ali,首先要对TransitionModel理解得比较清楚。建议先搞明白TM再去看该程序的代码。
我个人觉得这里的核心在于:根据tid能知道当前是哪个音素的哪个HMM状态(知道tid和对应的TM,由id2state_知道t-state,由state2id和tid只能t-idx,由t-state索引tuple_知道tuple,tuple保存音素、HMM state-id,也就知道了这两者),而无论该特征向量所对应的tid编号怎么变化,该特征向量对应的音素和HMM状态都是不变的。
从旧的tid转换成新的tid的流程大致如下:
明白了上述流程之后,convert-ali的代码就容易看懂了,这里我不再讲述细节,只把自己当时学习的手写笔记草稿放在这里,希望能有一定启发。
由convert-ali得到基于新的TransitionModel的对齐后,后面的GMM参数更新就和单音素GMM一样,GMM参数更新就是对每一个GMM(也就是每一个pdf)更新相应的参数。由对齐序列(tid序列),我们就能找到属于每一个pdf的特征向量,用这些特征向量更新该pdf的每个分量的均值、方差和权值即可。
猜你喜欢
- 2024-10-11 kaldi合并HI-MIA唤醒recipe(pdf合并在线免费)
 - 2024-10-11 萌妹的最爱,又可爱又好喝的KALDI 限定低酒精水果味鸡尾酒
 - 2024-10-11 kaldi语音识别工具集(kaldi中文语音识别)
 - 2024-10-11 Vosk开源语音识别引擎kaldi的开发套件支持Asterisk
 - 2024-07-05 语音识别工具包Kaldi的学习和使用(二):安装前的准备
 - 2024-07-05 kaldi合并出门问问唤醒recipe(hello和hi的区别)
 - 2024-07-05 纯PyTorch语音工具包开源,Kaldi:我压力有点大
 - 2024-07-05 日本零食分享第二弹:KALDI(日本,零食)
 
欢迎 你 发表评论:
- 1590℃北京那些看上去很牛的车牌们!(北京厉害车牌)
 - 1107℃2025年度视频去水印软件TOP5对比:哪款最值得用
 - 683℃《我的世界》不同版本的差异 ——新手向
 - 595℃新疆话里的“虫子”
 - 516℃中兴光猫 Telnet下设置大全(中兴光猫命令大全)
 - 513℃蓝牙设备配对失败的系统性解决方案与技术解析
 - 509℃未备份电脑文件数据恢复的七种方法
 - 488℃工艺管道常用英文缩写 英汉对照
 
- 最近发表
 
- 标签列表
 - 
- jdk (81)
 - putty (66)
 - rufus (78)
 - 内网穿透 (89)
 - okhttp (70)
 - powertoys (74)
 - windowsterminal (81)
 - netcat (65)
 - ghostscript (65)
 - veracrypt (65)
 - asp.netcore (70)
 - wrk (67)
 - aspose.words (80)
 - itk (80)
 - ajaxfileupload.js (66)
 - sqlhelper (67)
 - express.js (67)
 - phpmailer (67)
 - xjar (70)
 - redisclient (78)
 - wakeonlan (66)
 - tinygo (85)
 - startbbs (72)
 - webftp (82)
 - vsvim (79)
 
 

本文暂时没有评论,来添加一个吧(●'◡'●)