chain model的结构

chain model实际上是借鉴了CTC的思想,引入了blank用来吸收不确定的边界。但CTC只有一个blank,而chain model中每一个建模单元都有自己的blank。如下图所示:

对应kaldi中的结构定义为:

<Topology>
<TopologyEntry>
<ForPhones>
1 2 3 4 5 6 7 8 …
</ForPhones>
<State> 0 <ForwardPdfClass> 0 <SelfLoopPdfClass> 1 <Transition> 0 0.5 <Transition> 1 0.5 </State>
<State> 1 </State>
</TopologyEntry>
</Topology>

在kaldi中,把Sp和Sb看做同一个状态(都对应state 0),只是pdfclass不同。ForwardPdfClass表示Sp,SelfLoopPdfClass表示Sb。

kaldi中的chain model训练

chain model实际上也是一种序列鉴别性训练的方法,所以它也要构造分母fst和分子fst。
ps:这里不用分母词图(lattice)和分子词图(lattice)的表述,一、因为chain model(lattice free)不需要构建分母词图,而是用类似于HCLG这样的fst结构代替分母词图。二、同时chain model为了将每个句子分成一小块chunk,也会把分子lattice转换成分子fst(因为fst可以保留时间对齐信息,方便根据时间切分成块)

下面我们讲解chain model训练的关键步骤(为了系统性地说明,我们以aishell中的BAC009S0712W0300这个音频为例)

  • 一、为每个句子构建训练图,然后解码得到每个句子的可能对齐结果(lattice)
    这一步类似于构建解码用的HCLG,但解码用的HCLG是所有句子通用的。而我们这里构建的HCLG是根据每个句子的transcripts(转录文本)构建的,所以图会比较小,每个句子有自己的一个HCLG图。具体构建训练图的方法可参考:http://kaldi-asr.org/doc/graph_recipe_train.html
    有了训练图之后,我们就可以在上面解码,得到每个句子所有可能的对齐方式。
    kaldi中将所有可能的对齐用lattice这样的数据结构来保存,这样可以节省存储空间。得到的lattice(CompactLattice)的格式如下:

    说明:
    第一列和第二列是lattice结点的编号
    第三列是word
    接下来的两个数字(比如4.45809,3339.97)分别是语言模型概率和声学模型概率
    接下来以”_“分隔的每个数字都是每一帧对应的transition-id。

    为什么不是得到唯一的(最有可能的)对齐呢?kaldi文档中有解释:

    Instead of enforcing a particular pronunciation of the training data, we use as our reference a lattice of alternative pronunciations of the training data, generated by a lattice-generating decoding procedure using an utterance-specific graph as the decoding graph. This generates all alignments of pronunciations that were within a beam of the best-scoring pronunciation.(也就是说考虑了多种发音组合的情况,比如上图的“规划”这个发音,他可以是“gui gui hua <eps> <eps>”或”gui gui gui hua <eps>“等等)

    这一步构建的训练图在后面分母fst的构建和分子fst的构建中都会用到。

  • 二、分母fst的构建
    1、构建phone级别的语言模型
    构建语言模型必须要有语料,那么phone级别的语料从何而来呢?首先根据第一步的lattice(多种可能的对齐方式),我们进一步解码得到最有可能的对齐方式。kaldi中每个句子的最有可能的对齐方式写在ali文件中,格式如下:

    BAC009S0712W0300 2 1 1 1 1 1 1 1 1 1 1 1 1 1 6290 6289 6289 6289 3856 3855 3855 3855 4830 4829 4829 4829 4829 2886 2885 2885 2614 2613 2613 2856 2855 2855 2855 2855 2855 2855 2855 2608 2607 2607 2607 2456 2455 2455 2548 2547 2547 2862 2861 2861 2861 5936 5935 5935 5935 5935 5935 2340 2339 2339 2339 2592 2591 2591 2591 2591 2810 2809 2809 2809 2809 2809 1922 1921 1921 1921 5294 5293 5293 5293 3478 3477 3477 3840 3839 1078 1077 1077 1280 1279 1764 1763 1763 1763 1763 5294 5293 5293 5293 1954 1953 1953 1953 5150 5149 5149 5149 5149 5149 5149 5149 5149 5149 2 1 1 1 1 1 1 1 1 1 1 1 1

    说明:加粗的表示音频名字,音频名字后跟的数字表示每一帧对应的transition-id。
    根据transition-id,我们可以得到每一帧对应的phone,如下:

    BAC009S0712W0300 sil zh ong1 sh ix2 ii iu2 ii ie2 ii iu3 x iang1 ii ing4 g ui1 m o2 d e5 g ui1 h ua4 sil

    因此,我们就可以构建phone级别的语言模型。

    2、构建分母fst
    chain model的分母fst类似于解码时建立的HCLG图。但是chain model的语言模型是phone级别,所以构图时我们不需要发音词典了,其实构造的是HCP(P表示phone LM,HCP就是fst结构,所以叫分母fst)。为了限制HCP图的大小,我们使用4元phone LM。值得注意的是:不同的句子是共用同一个HCP图,这一点与传统的序列鉴别性训练不同,传统的序列鉴别性每个句子都有自己的分母lattice。

  • 三、分子fst的构建

    1、将第一步得到的以word为单位的lattice转换成以phone为单位的lattice。
    chain model是在phone-level上进行训练的,所以需要得到以phone为单位的对齐,如下图所示:

    2、构建分子fst:将phone-level的lattice转换成fst,同时将transiton-id转换成pdf-id
    lattice与fst的不同是,根据fst中编码了time-alignment信息,可以方便我们根据时间点切分整段音频。为什么要将transiton-id转换成pdf-id?因为声学模型是对pdf-id建模。

    说明:
    第一列和第二列是fst结点的编号
    第三列和第四列是pdf-id(输出和输出相同,实际上它是FSA)

    同时,在这一步,我们还会以3倍的步幅跳帧进行采样(至于为什么可以跳帧,在最下面的“常见疑问”模块会有我自己的理解)。从这个图我们可以看到跳帧采样的现象,理论上音素sil对应41帧(通过上上张phone leveld的图中sil对应的transition-id数可以得到),但现在13帧(通过上张图,1和218(1和218都对应到音素sil)连续出现的次数可以得到)。或许看上张图,你还有疑问,为什么pdf-id 218之间还有pdf-id 253呢?这是因为原来的对齐结果不一定是准确的(基于CD-HMM-GMM),kaldi中提供了–left-tolerance和–right-tolerance两个选项,以phone为单位,允许phone在原来的对齐结果基础上,向前延伸–left-tolerance帧和向后延伸-right-tolerance帧(通常是5帧)。

    到这一步,理论上每个句子的分子fst就构建完成了。

    4、将每个句子的分子fst分成多个小chunk,用于训练
    之所以将整个音频分成chunk,是为了加快训练速度和解码速度。因为fst中有时间对齐信息,所以我们很容易将整段fst分成一小块,如下图所示:

chain model和传统的序列鉴别性训练(MMI/MPE/sMBR)的区别

基于CD-DNN-HMM的序列鉴别性训练,需要以下几步:

  1. 训练一个基于CE(交叉熵)准则的CD-DNN-HMM模型作为种子模型,因为CD-DNN-HMM通常会优于CD-GMM-HMM。然后利用该种子模型,得到基于状态层面的强制对齐作为分子词图。
  2. 基于一元语言模型构建一个HCLG,然后在HCLG上解码得到每个句子的分母词图。之所以采用一元的语言模型,应该是为了使词图不会太大。

chain model虽然也是一种序列鉴别性训练,但它的训练流程比较简单:

  1. chain model不需要事先训练一个CE准则的DNN模型;而是直接使用CD-HMM-GMM模型得到每个句子的对齐结果,然后生成分子fst
  2. chain model不需要为每个句子构建分母fst,而是直接使用HCP图(P表示phone LM)。

同时,chain model是直接在phone级别上建模的。传统的序列鉴别性训练是在word-level上建模的。

chain model的优点:
1、解码速度更快。因为chain model采用拼帧降采样(每三帧取一帧)的方式,也就是说帧移变成了30ms,而不是10ms,所以帧率是传统神经网络声学模型的三分之一;
2、训练速度更快。不需要预先训练DNN模型,同时省去了分母lattice的生成。

chain model和CTC对比

这是Dan Povey在回答为什么将CTC脚本从kaldi中移除的原话:

Firstly, CTC was never in the master branch of Kaldi.
It’s dropped permanently, because the ‘chain’ models were always
better than CTC
. And I removed the branch because I don’t want to
answer questions about it (and because it’s a waste of their time
too). BTW, a presentation by Google here at Interspeech is saying something
similar, that a conventional model, discriminatively trained, with 1/3
the normal frame rate, beats CTC.

常见的疑问

1、为什么说chain model是lattice free?
答:之前的鉴别性训练是需要对每个音频解码得到分母词图(每个音频都有自己对应的词图)。而chain model的分母fst实际上是HCP(P表示发音词典的概率),也就是说所有音频共享同一个HCP图,不需要分别解码得到对应的lattice,所以叫lattice free。

2、为什么chain model可以采用跳帧降采样的方式训练和解码,而传统的HMM-GMM不行?
答:主要跟建模粒度有关。chain model中的每个phone只有一个state(不考虑blank),所以我们可以认为它的建模单元是phone。而传统的HMM-GMM的每个phone有3或5个state,所以传统的HMM-GMM实际上是对state建模。因为state的建模粒度比较小,采用跳帧的方式时,可能跳过了中间重要的几个state,从而影响识别结果。而phone的建模粒度较大,采用跳帧的方式通常不会跳过phone。

3、实际处理时(如kaldi),为什么要将句子分成多个小块(chunk)?
答:对于非循环模型和非chain模型的情况,分成chunk主要是考虑到我们训练时是利用上下文信息的,比如考虑了前10帧和后10帧,那么每个训练的example需要存储21帧特征,8个example需要存储168帧。如果我们将连续8帧做成一个chunk,那么我们只需要存储28帧(10+8+10),节省了存储空间。
对于循环模型或chain模型,主要是分成chunk能提高训练速度和解码速度,具体可以参考我之前的文章:https://blog.csdn.net/asrgreek/article/details/87884835

4、chain model的建模单元?
答:chain model使用biphone作为基本的建模单元,而不是我们经常用的triphone。Dan Povey在2016年的interspeech演讲中提到,实验发现biphone的效果稍微好于triphone。同时解码速度更快了,因为phone的数量减少了。

kaldi中的chain model(LFMMI)详解相关推荐

  1. Linux中/proc目录下文件详解

    Linux中/proc目录下文件详解(一) 声明:可以自由转载本文,但请务必保留本文的完整性. 作者:张子坚 email:zhangzijian@163.com 说明:本文所涉及示例均在fedora ...

  2. python平方数迭代器_对python中的高效迭代器函数详解

    python中内置的库中有个itertools,可以满足我们在编程中绝大多数需要迭代的场合,当然也可以自己造轮子,但是有现成的好用的轮子不妨也学习一下,看哪个用的顺手~ 首先还是要先import一下: ...

  3. python迭代器创建序列_Python 中迭代器与生成器实例详解

    Python 中迭代器与生成器实例详解 本文通过针对不同应用场景及其解决方案的方式,总结了Python中迭代器与生成器的一些相关知识,具体如下: 1.手动遍历迭代器 应用场景:想遍历一个可迭代对象中的 ...

  4. PyTorch中的torch.nn.Parameter() 详解

    PyTorch中的torch.nn.Parameter() 详解 今天来聊一下PyTorch中的torch.nn.Parameter()这个函数,笔者第一次见的时候也是大概能理解函数的用途,但是具体实 ...

  5. java实现for文件删除_Java 添加、删除、替换、格式化Word中的文本的步骤详解(基于Spire.Cloud.SDK for Java)...

    Spire.Cloud.SDK for Java提供了TextRangesApi接口可通过addTextRange()添加文本.deleteTextRange()删除文本.updateTextRang ...

  6. Linux中/proc目录下文件详解 /proc/devices文件 /proc/modules文件

    http://blog.chinaunix.net/uid-10449864-id-2956854.html 原来对linux系统中的/proc目录不是很了解,只知道可以查看cpu,内存等相关的信息, ...

  7. linux在当前目录下创建pic目录,Linux中/proc目录下文件详解

    文章转自: Linux中/proc目录下文件详解(一) ------------------------------------------------------------------------ ...

  8. 【深度学习】扩散模型(Diffusion Model)详解

    [深度学习]扩散模型(Diffusion Model)详解 文章目录 [深度学习]扩散模型(Diffusion Model)详解 1. 介绍 2. 具体方法 2.1 扩散过程 2.2 逆扩散过程 2. ...

  9. linux中iptables配置文件及命令详解详解

    linux中iptables配置文件及命令详解详解 2018年05月04日 14:23:41 hxpjava1 阅读数 956 linux中iptables配置文件及命令详解详解 iptables配置 ...

最新文章

  1. 阿拉德之怒显示服务器错误,阿拉德之怒网络异常怎么办 安装失败怎么办
  2. TensorFlow 人脸识别实验 ImportError: No module named 'sklearn.model_selection'
  3. spring boot 之session的总结
  4. pycharm 如何设置文件头信息?信息模板 头文件 coding: utf-8
  5. python3 Django框架报错(备忘录)
  6. Java并发编程—为什么wait/notify操作要先获取到锁?
  7. “阿里巴巴小程序繁星计划”:20亿扶持200万小程序开发者和100万商家
  8. 每日一题(C语言基础篇)2
  9. matlab lti全响应,《LTI系统的响应——实验报告》.doc
  10. 任正非:未来是云时代,华为也要转向云战略
  11. java求立方体表面积和体积_设计一个立方体类BOX,它能计算并输出立方体的体积和表面积...
  12. [SQL]SQL server 常用代码
  13. SEM竞价推广,如何选择关键词?
  14. 【KITTI】KITTI数据集简介(四) — 标定校准数据calib
  15. 在移动通信中如何测试5G网络?
  16. python调用bash shell脚本
  17. JavaScript-修炼之路第二层
  18. 去除IE自带的输入框清除按钮
  19. 关于const A* f(const A* pSrc,A* const pDst,int v=2,...) const throw();
  20. java初始化加载类_Java 类的加载和初始化

热门文章

  1. oracle dml是什么,Oracle之DML语句
  2. NPR——卡通渲染(三)
  3. python 各种包下载大全网址
  4. hibernate HQL语句
  5. 第22天 Binary Tree 235、701、450
  6. 亲民时尚的格式转换工具——炫酷乐转码先生使用感悟
  7. 如何写好科研论文 撰写技巧(六)
  8. 修改mysql字符集为utf8mb4
  9. 微信小程序 navbar
  10. 国产心:小米澎湃S2处理器正式量产