语音识别中的HMM-GMM模型:从一段语音说起

语音识别中的HMM-GMM模型:从一段语音说起

虽然现在端到端语音识别模型可以直接对后验概率建模,可以不需要HMM结构了。但实际上目前很多state-of-the-art模型还是以HMM结构为主,比如chain model。而且掌握HMM-GMM结构,对于深入理解语音识别过程是由有一定好处的。

但对于外行或者刚接触语音识别的人来说,要弄懂HMM-GMM结构还是要花不少时间的,特别是被一大推公式整懵了。语音识别任务有些特殊,比如语音识别中,标注只是针对整段音频的,而不是针对每一帧;语音识别是针对每个音素都建立一个HMM模型,而不是所有音素用一个HMM模型描述。

当时为了弄懂HMM-GMM,看了不少资料,但感觉都不适合很初级的学习者。于是就萌生了写一个通俗易懂版的HMM-GMM教程,从一个音频实例说起,给大家一个感性的认识,也着重讲下作为初学者可能会感同身受的问题,不涉及到具体公式。公式的推断会给出参考资料,后续大家在研究,相信有了感性的认识之后,对这些公式的理解就不成问题了。

我们从下面这段音频说起:

我们把上面2秒的音频分帧,以帧长100ms,帧移100ms为例进行切分,这样上面的音频就被我们分成20帧。(ps:这里主要是为了方便说明,正常情况下帧长是25ms,帧移是10ms)

一、得到这段音频的标注

这里的标注可以是两种:

1、音素级别的标注。这是训练HMM-GMM模型所需要的标注,也就是说可以直接拿来训练的数据。

2、字节别的标注。实际上我们更多时候拿到是的字级别的标注,因为音素级别的标注工作量很大。但我们可以通过发音词典,将字级别的标注转换成音素级别的标注。这种转换没办法消除多音字的影响,但实际上不会对结果产生太大影响(这一部分可以参考kaldi的compile-train-graphs过程:

Decoding-graph creation recipe (training time)kaldi-asr.org

假设上面这段音频的标注是”你好“,那么对应的发音就是”n i2 h ao3“这四个声韵母。这里为了方便说明,我们就是用声韵母作为建模单元(ps:实际应用中是使用音素作为建模单元)。

二、对”n“、”i2“、”h“、”ao3“这4个声韵母分别使用HMM-GMM建模,使用3状态建模,如下图

为了方面说明,我们给每个状态加了编号。从上图我们可以看到,对于HMM的发射概率,我们是使用高斯分布函数建模的。为了方便说明,这里我们使用单高斯分布函数(虽然上图写的是GMM)

理解自环很重要,比如④这个状态,因为有了自环,它可以出现多次,因此我们可以对任意长的音频建模,这也是连续语音识别的基础。

三、对”n“、”i2“、”h“、”ao3“对应的HMM-GMM模型进行训练,得到模型参数

这一步属于HMM三个问题中的学习问题,需要用到EM算法。在开始训练之前,我们需要明确每个HMM模型的参数、模型的输入和模型的输出。

  • HMM-GMM模型的参数

1、转移概率

2、发射概率:因为我们使用GMM对发射概率建模,所以实际参数就是高斯分布中的均值和方差(这也是初学者容易迷糊的一个地方)。

总结:模型参数就是转移概率、高斯分布的均值、方差

  • 模型的输入

输入:每帧信号的MFCC特征(也可以是fbank,plp等)。具体应用中,我们通常取39维的MFCC特征。这里为了方便说明,我们取2维的MFCC特征,也就是说输入的特征空间分布是这样的:

上图中,每个黑点对应某一帧信号的MFCC特征。我们需要使用这些特征值来更新GMM的参数,具体怎么更新后续会讲。

  • 模型的输出

输出:每一帧属于"n"、"i2"、"h"、"ao3"中的某一个状态(3状态)的概率。

同时,需要额外说明的是:虽然我们有了每段音频对应的标注,但实际上HMM-GMM模型的学习过程并不是”有监督的“。因为监督学习任务应该是:"对于每一个输入,都有对应的label"。而语音识别的任务比”传统的监督学习“复杂一点。因为我们拿到的标注是音素级别的。比如上面那段音频,它只告诉我们对应的标注是"n"、"i2"、"h"、"ao3",并没有告诉我们每一帧(即每一个输入)对应的label是啥?那么应该怎么训练呢,相信是很多初学者的困惑。

对于这种无监督的任务,我们EM算法来进行训练(更专业的术语叫嵌入式训练,embedding training。也就是说把“n”、“i2”、“h”、“ao3”对应的HMM模型嵌入到整段音频中进去训练,因为我们不知道音频的哪一段是对应“n”、“i2”、“h”、“ao3”。嵌入式训练本质还是EM算法的思想):

  • step1:初始化对齐。以上面的20秒音频为例,因为我们不知道每一帧对应哪个声韵母的某个状态,所以就均分。也就是说1-5帧对应"n",6-10帧对应"i2",11-15帧对应"h",16-20帧对应"ao3"。同时"n"又有三个状态,那么就把1-2帧分给状态①,3-4帧分给状态②,第5帧分给状态③。"i2"、"h"、"ao3"亦如此。这里每个状态只是用单高斯描述,如果是混合高斯,还需要进一步用k-means算法来对每个高斯分量初始化。

初始化完成后,该段音频对应的HMM模型如下:

  • step2:更新模型参数。

1、转移概率:通过上图,我们可以得到①->①的转移次数,①->②的转移次数等等。然后除以总的转移次数,就可以得到每种转移的概率,这是一个统计的过程,无他。

2、发射概率:即均值和方差。以状态①的均值和方差为例,由上图我们可以知道第1帧和第2帧对应状态①。假设第1帧的MFCC特征是(4,3),第2帧的MFCC特征的MFCC特征是(4,7)。那么状态①的均值就是(4,5),方差是(0,8)

  • step3:重新对齐。根据step2得到的参数,重新对音频进行状态级别的对齐。这一步区别于step1的初始化,step1的初始化我们是采用粗暴的均匀对齐,而这一步的对齐是根据step2的参数进行对齐的。这里的对齐方法有两种:a、硬对齐:采用维特比算法;b、软对齐:采用前后向算法。

经过重新对齐后,可能变成这样(第2帧已经不对应状态①了):

  • step4:重复step2和step3多次,直到收敛。

这一个过程就是EM算法。step1和step3对应E步,step2对应M步。

这一过程涉及到的公式可以参考爱丁堡的语音识别课件59.80.44.98/www.inf.ed.

到这里,我们就从宏观层面把语音识别的HMM-GMM建模过程讲完了。为了方便讲解,我们这里是用单音素为例。实际应用中,通常使用三音素,但过程几乎是一样的,只是三音素多了一步决策树聚类,具体可以参考我之前的博文:[kaldi中基于决策树的状态绑定](blog.csdn.net/asrgreek/)

欢迎转载,转载请注明出处,谢谢!

编辑于 2019-05-25

文章被以下专栏收录