kaldi中的chain model详解

网友投稿 782 2022-05-30

chain model的结构

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

对应kaldi中的结构定义为:

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

kaldi中的chain model训练

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图。具体构建训练图的方法可参考:

Decoding-graph creation recipe (training time) kaldi-asr.org/doc/graph_recipe_train.html

有了训练图之后,我们就可以在上面解码,得到每个句子所有可能的对齐方式。kaldi中将所有可能的对齐用lattice这样的数据结构来保存,这样可以节省存储空间。得到的lattice(CompactLattice)的格式如下:

说明:

第一列和第二列是lattice结点的编号

第三列是word

接下来的两个数字(比如4.45809,3339.97)分别是语言模型概率和声学模型概率

接下来以”_“分隔的每个数字都是每一帧对应的transition-id。

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

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

二、分母fst的构建

1、构建phone级别的语言模型

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

说明:加粗的表示音频名字,音频名字后跟的数字表示每一帧对应的transition-id。

根据transition-id,我们可以得到每一帧对应的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中移除的原话:

常见的疑问

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),节省了存储空间。

实时语音识别 机器学习 深度学习 神经网络

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【云驻共创】如何使微服务更加便利
下一篇:Linux 和docker上的 SQL Server 的常见问题解答 (FAQ)
相关文章