建议在csdn资源页中免费下载该学习笔记的PDF版进行阅读:)点击进入下载页面

Kaldi单音素GMM学习笔记

目录

  • Kaldi单音素GMM学习笔记

    • 原理
    • 脚本
    • 程序
      • gmm-init-mono
      • compile-train-graphs
      • align-equal-compiled
      • gmm-acc-stats-ali
      • gmm-sum-accs
      • gmm-est
      • DiagGmm
      • DiagGmmNormal
      • AmDiagGmm
      • AccumDiagGmm
      • AccumAmDiagGmm
      • TransitionModel

原理

学习资料:

  1. 统计学习方法–李航

    • 学习第九章《EM算法》,可跳过9.4节。弄明白EM算法在高斯混合模型(GMM)学习中的应用,搞明白几个公式。
    • 学习第十章《隐马尔可夫模型》。弄明白HMM这一套。
  2. 语音识别实践–俞栋,邓力
    • 学习第二章《混合高斯模型》。对上述GMM学习的补充。
    • 学习第十章《隐马尔可夫模型及其变体》。对上述HMM学习的补充。
  3. Speech and Language Processing—Daniel Jurafsky, James H. Martin.
    • 学习第九章《Automatic Speech Recognition》。(注:因为我大四的时候看过几遍本章,并看过一套HMM-GMM孤立词识别的matlab代码,对HMM-GMM有一定基础,所以本次学习时我只看了9.7节的Viterbi training部分)
  4. Ediburg-Course. (http://www.inf.ed.ac.uk/teaching/courses/asr/)
    • asr03-hmmgmm-handout.pdf

个人理解:
  论讲解的清晰度、条理性,李航的书更好一些。俞栋的书则更贴近语音,并且该书的公式推导简直清晰,一点都不含糊,比如前向后向公式的推导。
  EM算法之前看过几遍,总是似懂非懂。本次看EM算法,则是在我学习过《数理统计》这门课之后,因此在看EM算法的时候能加入参数估计、期望的一些背景知识去理解EM算法。主要有两点要搞清楚,第一点,EM算法其实就是在分布已知(概率密度函数的形式已知)、参数未知的情况下去估计未知参数。这样一来,估计GMM参数的EM算法的输入输出就较好理解了。第二点:EM算法是个迭代算法,最后是可以收敛到局部最优的。用上一轮计算出来的参数计算当前轮的一些值(比如带入高斯分布公式算概率),然后去得到新的参数值。
  在Kaldi中,单音素GMM的训练用的是Viterbi training,而不是Baum-Welch training。因此就不是用HMM Baum-Welch那几个公式去更新参数,也就不用计算前向概率、后向概率了。Kaldi中用的是EM算法用于GMM时的那三个参数更新公式,并且稍有改变。
  Baum-Welch算法更新参数时,因为要计算前向后向概率,很费时间,因此使用Viterbi Training作为Baum-Welch算法的近似。在Baum-Welch算法中,计算前向后向概率时,要用到所有的状态路径,在Viterbi训练中,用Viterbi路径代替对所有状态路径的累积。
  在Viterbi训练中,先根据上一轮的模型参数对语音特征数据进行对齐,得到每一帧的特征所对应的HMM状态(在kaldi中是transition-id),也就是forced alignment。Forced alignment的结果是对应于特征序列的状态序列。
  举个例子:
    当前的特征序列是o1, o2, o3, o4, o5, o6, o7.(每一帧的特征是39维MFCC)
    对应的状态序列是7, 8, 8, 8, 9, 9, 10.(每个数字代表一个HMM state)
  知道了特征序列和其对应的状态序列,我们就可以通过简单的数数来更新HMM的参数——转移概率矩阵A。根据对齐结果,统计每一个HMM状态总共出现了多少次(可以从transition-id得到HMM state-id),统计该状态的每一个转移出现了多少次(一般只有两个转移,转移到自身和转移到下一状态),用每一个转移的出现次数除以该状态的出现次数就得到了转移概率。HMM参数就是这样更新的。
  首先应该明白,在单音素GMM训练中,每一个HMM状态有一个对应的GMM概率密度函数(pdf),所以有多少个HMM状态,就有多少个GMM,也就有多少组GMM参数。在知道了特征序列和对齐序列后,找出某一个HMM状态对应的所有观测(比如状态8对应的o2, o3, o4,在kaldi中则是找到某一transition-id对应的所有观测),也就得到了该状态对应的GMM所对应的所有观测。知道了该GMM对应的所有观测、该GMM的当前参数,就可以根据GMM参数更新公式更新GMM参数了,比如知道了状态8对应的观测o2, o3, o4。Kaldi中所用的GMM参数更新公式如下图所示。

脚本

kaldi的github分支kaldi-5.0里,egs/wsj/s5/steps路径下的train_mono.sh。

Usage: steps/train_mono.sh [options] <data-dir> <lang-dir>
e.g.: steps/train_mono.sh data/train.1k data/lang exp/mono<exp-dir>
  1. 初始化单音素模型。调用gmm-init-mono,生成0.mdl、tree。
  2. 编译训练时的图。调用compile-train-graph生成text中每句抄本对应的fst,存放在fsts.JOB.gz中。
  3. 第一次对齐数据。调用align-equal-stats-ali生成对齐状态序列,通过管道传递给gmm-acc-stats-ali,得到更新参数时用到的统计量。
  4. 第一次更新模型参数。调用gmm-est更新模型参数。
  5. 进入训练模型的主循环:在指定的对齐轮数,使用gmm-align-compiled对齐特征数据,得到新的对齐状态序列;每一轮都调用gmm-acc-stats-ali计算更新模型参数所用到的统计量,然后调用gmm-est更新模型参数,并且在每一轮中增加GMM的分量个数。

程序

gmm-init-mono

  • 作用:初始化单音素GMM。
Usage: gmm-init-mono <topology-in> <dim> <model-out> <tree-out>
e.g.: gmm-init-mono topo 39 mono.mdl mono.tree
  1. 计算所有特征数据每一维特征的全局均值、方差
  2. 读取topo文件,创建共享音素列表(根据$lang/phones/sets.int),根据共享音素列表创建ctx_dep(相当于tree)
  3. 每一组共享音素的一个状态对应一个Pdf。对每一个状态,创建只有一个分量的GMM,该GMM的均值初始化为全局均值、方差初始化为全局方差。(实际上,此时表示GMM的类是DiagGmm,该对象根据多维高斯分布的公式和对角协方差矩阵的特殊性,为了方便计算,直接保存的参数并不是均值、方差,而是方差的逆(实际就是方差矩阵每个元素求倒数)、均值×方差的逆,还提前计算并保存了公式中的常数部分(.mdl文件GMM部分的<GCONSTS>
  4. 根据ctx_dep和topo创建转移模型。将转移模型、GMM声学模型写到0.mdl
  5. 将ctx_dep写到tree.

compile-train-graphs

Usage: compile-train-graphs [options] <tree-in> <model-in> <lexicon-fst-in> <transcriptions-rspecifier> <graphs-wspecifier>
e.g.: compile-train-graphs tree 1.mdl lex.fst ark:train.tra ark:graphs.fsts

  该程序的输出是ark格式的graphs.fsts(存为exp/mono/fst.JOB.gz),包含train.tra中的每个utt-id的FST,FST由无转移概率的HCLG组成。
  暂时不用扣WFST相关的细节,只要明白这一步对于整个训练过程用什么用就可以了,后面专攻WFST部分代码的时候可以把每个阶段与WFST相关的部分串起来。
  生成与音频特征对齐的HMM状态序列时要用到每句话的FST。

align-equal-compiled

Usage: align-equal-compiled <graphs-rspecifier> <features-rspecifier> <alignments-wspecifier>
e.g.: align-equal-compiled 1.fsts scp:train.scp ark:equal.ali

  对每一句话,根据这句话的特征和这句话的fst,生成对应的对齐状态序列。

gmm-acc-stats-ali

  • 作用:Accumulate stats for GMM training.
Usage: gmm-acc-stats-ali [options] <model-in> <feature-rspecifier> <alignments-rspecifier> <stats-out>
e.g.: gmm-acc-stats-ali 1.mdl scp:train.scp ark:1.ali 1.acc;

对于每一帧的特征和其对齐(transition-id):

  • 对于转移模型(TM),累积tid出现的次数;
  • 对于AM,由tid得到pdf-id,也就是找到对应该pdf-id的DiagGmm对象,更新与该DiagGmm对象相关的AccumDiagGmm的参数,也就是计算得到三个GMM参数更新公式的分子部分(包括每一混合分量的后验(occupancy_中保存∑nj=1γ^jk\sum_{j=1}^n \hat{\gamma}_{jk})、每一分量的后验乘以当前帧的特征(mean_accumulator_中保存∑nj=1γ^jkyj\sum_{j=1}^n \hat{\gamma}_{jk}y_j,MxD维)、每一分量的后验乘以 当前帧的特征每一维的平方(variance_accumulator_中保存∑nj=1γ^jky2j\sum_{j=1}^n \hat{\gamma}_{jk}y_{j}^2,MxD维))

处理完所有数据后,将TM和AM的累积量写到一个文件中:x.JOB.acc中

gmm-sum-accs

gmm-acc-stats-ali生成的累计量分散在JOB个文件中,该程序将分散的对应同一trans-id、pdf-id的累计量合并在一起。

gmm-est

  • 作用:Do Maximum Likelihood re-estimation of GMM-based acoustic model.
Usage:  gmm-est [options] <model-in> <stats-in> <model-out>
e.g.: gmm-est 1.mdl 1.acc 2.mdl

主要分两部分,一部分更新TransitionModel,一部分更新GMM。

  • 更新转移模型:根据gmm-acc-stats-ali统计的tid出现的次数,做一个除法就可以更新转移概率矩阵A。
  • 更新GMM:gmm-acc-stats-ali已经得到了三个GMM参数更新公式的分子部分,方差累积量只需要减去更新后的均值的平方即可得到正确的方差更新公式。分母部分也已几乎得到,做一个简单的除法就可以更新GMM的分量概率、均值、方差。调用MleAmDiagGmmUpdate()更新GMM的参数,然后在该函数里调用MleDiaGmmUpdate()更新每一个GMM的参数,然后在后一个函数里更新每一个分量的参数。

DiagGmm

保存一个GMM的参数,包括分量权值weights_、均值、方差、每一分量高斯分布里的常量部分取log后的数值gconsts_。注意均值和方差为了方便计算,保存的并不是原原本本的均值、方差,而是方差每一元素求倒数后的inv_vars_、均值乘以inv_vars_后的means_invvars_。

DiagGmmNormal

对应于DiagGmm的标准形式的GMM,保存一个GMM原原本本的参数:分量权重weights_,均值means_,方差vars_。

AmDiagGmm

保存所有的GMM。

AccumDiagGmm

对应于DiagGmm,保存参数更新时所需的累积量:
Num_comp_:混合分量个数M
Dim_:特征维数
Occupancy_:M个元素,每一个元素是∑nj=1γ^jk\sum_{j=1}^n \hat{\gamma}_{jk}
Mean_accumulator_:MxD维,每一行是∑nj=1γ^jkyj\sum_{j=1}^n \hat{\gamma}_{jk}y_{j}
Variance_accumulator_:MxD维,每一行是∑nj=1γ^jky2j\sum_{j=1}^n \hat{\gamma}_{jk}y_{j}^2

AccumAmDiagGmm

对应于AmDiagGmm,保存所有的AccumDiagGmm。

TransitionModel

保存HMM拓扑,log转移概率,transition-id、transition-state、triplets(phone, hmm-state, forward-pdf)等之间的映射。


作者:许开拓
日期:写于2017-03-16~03-17
联系方式:540262601@qq.com

Kaldi单音素GMM学习笔记相关推荐

  1. Kaldi三音素GMM学习笔记

    建议在csdn资源页中免费下载该学习笔记的PDF版进行阅读:)点击进入下载页面 Kaldi三音素GMM学习笔记 三音素GMM与单音素GMM的主要差别在于决策树状态绑定,与GMM参数更新相关的原理.程序 ...

  2. Kaldi决策树状态绑定学习笔记(一)

    建议在csdn资源页中免费下载该学习笔记的PDF版进行阅读:)点击进入下载页面 Kaldi决策树状态绑定学习笔记(一) --如何累积相关统计量? 目录 Kaldi决策树状态绑定学习笔记一 如何累积相关 ...

  3. Kaldi 单音素模型训练流程与总结

    文章目录 脚本 原理 总体的流程介绍: 流程 1.初始化单音素模型 1.1gmm-init-mono.cc 1.2compile-train-graphs.cc 2.训练单音素模型 2.1align- ...

  4. kaldi单音素模型训练 - train_mono.sh脚本解读

    提示:本文适合kaldi的初学者,但最好有过运行kaldi的经验,并且大概了解EM算法.本文比较细致地对train_mono.sh脚本进行了解读,包括其源码,输入输出,以及对输出文件的内容都有详细的解 ...

  5. oracle update单引号,Oracle学习笔记:update的字段中包括单引号

    平时update的时候直接更改字段内的值,例如: update table_temp set name = 'Hider' where id = 100; 但更新后的值中包括单引号,则不能按以上方式进 ...

  6. php 表单变量,PHP学习笔记——访问表单变量

    在使用PHP开发Web应用时,最常见的需求就是使用一个表单(Form)收集用户提交的数据.在PHP中,通过Form表单获取用户提交的数据非常的容易,但是在细节上也存在细微的差别,这一点依赖于你使用的P ...

  7. 单片机入门学习单片通信协议学习笔记....更新中

    单片机各类通信协议 --来自于bilbil金善愚老 一.1-wire单总线 概述: 采用单根信号线既传输时钟又传输数据且数据传输是双向的.(单总线器件芯片有编制唯一的序列号(芯片通信地址)) 适用范围 ...

  8. 单例设计模式-学习笔记

     单例模式介绍和使用场景: 保证java应用程序中,一个类Class只有一个实例在,使用单例模式好处在于可以节省内存,节约资源,对于一般频繁创建和销毁对象的可以使用单例模式. 单例模式的几种实现方式: ...

  9. BUI 单页路由 学习笔记

    创建单页工程 使用buijs命令行构建. 目前 >>我<< 只通过这种方式 使用 buijs命令行 创建demo成功过,其他暂无成功! 创建demo工程: # 创建目录 $ m ...

最新文章

  1. 不要将时间浪费到编写完美代码上
  2. 拆解 Linux 网络包发送过程
  3. 【IDEA】干掉注释自动在行首
  4. Codeforces 173E Camping Groups 线段树
  5. 如何理解张量tensor
  6. 实现简单的ImageLoader
  7. Linux查看端口被那个进程占用
  8. Picasso源码的简单解析(二)
  9. java vips 算法_[Java] 22G传智播客java JavaEE+物联云计算 就业班(非基础班) 视频...
  10. jpeg格式转pdf格式的简单方法
  11. 计算机应用基础165791,人大网大计算机应用基础试题答案解析.doc
  12. Excel基础(01)认识excel
  13. 如何正确判断USB等接口的接线顺序
  14. 写给二线城市【Python工程师】的成长指南
  15. LINUX JDK 安装与环境变量设置
  16. html/css--flex布局
  17. 【机器学习】之 主成分分析PCA
  18. 虚拟机的三种网络模式
  19. PostgreSQL数据库之国际化语言支持学习总结
  20. 计算机毕业设计开题报告基于SpringBoot的校淘二手网站

热门文章

  1. 517day(sql2)
  2. 三周年!hoho~~
  3. System.getProperty()
  4. 380v pcb 接线端子_pcb接线端子类型
  5. 倒计时小程序桌面显示_【新版本更新!】小程序可以添加到电脑桌面啦,随点随学,备考更轻松!...
  6. 为什么移动Web应用程序很慢(译)
  7. three.js实现3d球体树状结构布局——添加入场、出场、点击放大等动画
  8. java判断按钮已选择的值_如何获取buttonGroup的选定单选按钮的值 - java
  9. 首发Yolov8涨点神器:华为诺亚2023极简的神经网络模型 VanillaNet---VanillaBlock助力检测,实现暴力涨点
  10. 【愚公系列】2023年06月 网络安全(交通银行杯)-IDC密码破解