HMM(Hidden Markov Model)详解——语音信号处理学习(三)(选修一)
参考文献:
Speech Recognition (Option) - HMM哔哩哔哩bilibili
2020 年 3月 新番 李宏毅 人类语言处理 独家笔记 HMM - 6 - 知乎 (zhihu.com)
隐马尔可夫(HMM)的解码问题+维特比算法 - 知乎 (zhihu.com)
本次省略所有引用论文
目录
一、介绍
二、建模单位 States
State 由来
转移概率与发射概率
三、Alignment
四、深度学习下的 HMM
方法一:Tandem
方法二:DNN-HMM Hybrid
五、DNN 中 State Classifier 的训练方式
注意,本篇继承语音信号处理学习(三)课程后,属于语音识别任务选修部分,共三个章节。
让我们穿越回14年前,看看那时的人们在没有神经网络的情况下是如何做语音辨识的。你会发现,当前的技术中有借用HMM的很多思想。
一、介绍
-
在过去,我们可以使用统计模型来做语音识别。给定输入语音序列 X,我们只需要找到最大概率的输出文字 Y 就可以了,也就是穷举所有可能的 Y,找到一个 Y* 使得 P(Y|X) 最大化。我们也把这个过程叫作解码(decode),公式如下:
-
穷举需要非常好的演算法,这个问题太复杂。好在我们可以使用贝叶斯定理对其进行变换,变换后的公式如下。由于 P(X) 与我们的解码任务是无关的,因为不会随着 Y 变化而变化。所以我们只需要保留分子部分即可。
-
变换后,我们将式子的前半部分 P(X|Y) 称为 Acoustic Model,后面这项 P(Y) 称为 Language Model。而前者所经常使用的就是 HMM。我们看到,如果需要使用 HMM,就必须搭配 LM 来进行使用。而常规的 E2E 模型是直接解未变行的式子的,表面上看上去好像不需要 LM,实际上 E2E 模型加上 LM 后表现往往会好很多,这个可以参考之后对 LM 的讲解。
二、建模单位 States
State 由来
-
在前面我们说过,语音识别模型中,目标 Y 是 Token 序列,然而,我们在 HMM 中会将目标 Token 序列转为 States 序列,用 S 来表示。State 是什么?它是由人定义的,比音素 Phoneme 还要小的单位。
-
我们使用 what do you think 句子来举例,使用 phoneme 作为 token 单位的话,分解结果如下。不过,由于每个因素都会受到前后因素的影响,所以相同的因素 uw 说不定实际上发音会不同。所以我们会更加细分,采用 Tri-phone 来作为 token 单位,即当前音素加上前面的和后面的音素。
-
而 State 就是比 Tri-phone 更小的单位,我们可以规定每个 Tri-phone 由 3 或者 5 个 state 构成。多少就取决于你所拥有的计算资源。而拆解出来的 State 也保留了发音顺序信息。
-
既然我们需要计算给定 States 时,声学特征序列 X 的几率,那我们就需要弄清楚 State 是怎么产生出声学特征的。其实很简单,假设我们一共有3个 State,而 X 有 6 个 Vector,那么我们首先进入第一个 State,产生一些向量,足够了以后进入下一个 State,以此类推,依次走完就结束了。
转移概率与发射概率
-
为了完成刚刚的过程,我们需要计算两个几率,一个是当前状态结束跳到下一个状态的几率,另一个就是当前状态生成对应声学特征的几率。二者我们分别称为 Transition Probability(转移概率) 和 Emission Probility(发射概率)。
-
Transition Probability:本次的 vector 是由状态 a 产生的,下一个 vector 是由状态 b 产生的概率。
-
Emission Probability:给定一个 State,产生某种 acoustic feature 的概率。我们认为,每一个状态所能发射的声学特征都有固定的概率分布,我们会用 GMM(Gaussian Mixture Model,高斯混合模型)来表示这个概率。
-
-
而发射概率的计算也间接说明了我们为什么需要如此小的单位 State 作为建模单位。因为我们要假设每个状态发射出来的分布稳定。如果单位太大,很有可能其发射的声学特征分布就会变来变去。比如如果使用字符来作为单位,那就会出现这种情况:c 这个字母它的发音不是固定的。它在很多时候是发"ke",但它在h后面就发音"ch"。这样就不适合拿来当作HMM的状态。
-
然而,发射概率也带来了一些问题,就是会有很多的 state。如果 phoneme 有30个,那么 Tri-phone 就会有 30×30×30个,一个 Tri-phone 又对应3个 state,最终的数量还得再乘一个 3。这就会可能出现这种情况,某一个 state 在整个语料库中只出现过一两次,那么就导致它的高斯混合分布很难计算。
-
针对这种情况,过去就出现了一项关键技术,即 Tied-state,它假设某些 State 的发音是一样的,因此它们会共用同一个高斯混合分布。这样就可以减少使用的高斯混合模型的数量,也可以让出现很少的难以计算分布的 state 和其他 state 共用分布。这就好比你有两个命名不一样的指针,都指向了同样的内存。
-
这样的技术发展到现在已经出现了最终形态:Subspace GMM。这其中,所有的State都共用同一个高斯混合模型。它实际上是一个高斯混合分布池(pool),里面有很多高斯混合分布。每一个State,就好比是一个网子,它去这个池子中捞几个高斯分布出来,当作自己要发射的高斯混合分布。所以每个State既有不同的高斯分布,又有相同的高斯分布。
不过,这项技术是2010年发表的,现在已经不怎么用了。当初发表的时候还是非常轰动的。有趣的是,Hinton 在同年也在该论坛上发表了一篇关于深度学习的 ASR 的论文。但当时大家的注意力都在前一篇论文上,Hinton 的研究并没有受到很多重视。原因在于,它的表现当时不如最顶尖(state of the art)的相关技术。
三、Alignment
-
假设我们已经知道了 Transition Probability 和 Emission Probability,然而我们还是计算不出来我们的目标概率 P(X|S),因为我们还缺少 Alignment。这是什么意思?就是我们还是不知道这些 vector 是对应到哪一个状态的。也就是说我们需要知道哪一个声学特征,是由哪一个状态产生的,才有办法用发射概率和转移概率去计算 P(X|S)。
-
假设我们有3个状态 abc,6个向量 x1~6,我们需要得到状态于向量的对齐方式 h(即状态序列),比如 aabbcc,也就是 x1 x2 由状态 a 产生,以此类推。知道了对齐方式,我们就可以用两个概率计算目标概率了。现实中,也正因为我们不知道 Alignment,这个信息是隐藏的,所以 HMM 中的 Hidden 命名就此诞生。不同的状态序列,计算出的概率也就会不一样。
-
那么我们是如何解决隐藏的 Alignment 信息问题的呢?我们选择穷举所有可能,把所有的状态序列的概率全都计算出来并加起来,最终的结果就是我们的目标概率 P(X|S)。这便是 HMM 在解码过程中在做的事情。当然,诸如 abccbc、abbbbb 这样的序列都是不算在内的,其原因是回跳和少状态。
但是!!!注意,本人在查询相关资料的时候发现,可能 HMM 在解码中真正做的事情是 “穷举” 所有可能,找到它产生与观测X的声学特征概率最大,最一致的对齐方式。这里的 “穷举” 一般是使用一些动态规划算法(比如 Viterbi 算法)来有效地计算最可能的状态序列,即给定声学特征序列时最可能的隐藏状态序列,以获得最大概率的解码结果。
不过我又看了一下,应该是对某一个状态序列,算他的概率的时候用的是所有对齐方式概率的加和,而要找概率最大的状态序列的时候,也就是解码生成结果时,使用的是动态规划算法。此说法有待考证。后续的结果:在学习 RNN-T 后,我认为 HMM 可能和 RNN-T 一样,在训练时是使用所有对齐方式的概率之和作为当前文本(token/state)的概率,而在训练时是采用概率最大的对齐方式的概率作为当前文本的概率。
参考资料:隐马尔可夫(HMM)的解码问题+维特比算法 - 知乎 (zhihu.com)
四、深度学习下的 HMM
方法一:Tandem
-
HMM中没有深度学习。当深度学习崛起的时候,人们就开始思考怎么把深度学习用进去。最早的想法都是基于HMM的变体。
-
第一个最常见的方法是Tandem。它在2009年就已经满街都是。它没有变动HMM的模型,而它的主要目的是给 HMM 提供质量更好的声学特征。怎么提供?之前的声学特征都是 MFCC,而 Tandem 则是训练一个基于深度神经网络的 State Classifier,它可以输入一个MFCC vector,来预测它属于哪一个状态的概率,输出就是其概率分布。我们将这个概率分布代替之前的声学特征,来作为 HMM 的新的输入。
-
当然,我们也并不一定要拿 State Classifier 的输出作为声学特征,也可以取最后一个隐层或者瓶颈层的输出。
方法二:DNN-HMM Hybrid
Discriminative training 和 Generative Training 是机器学习中两种不同的训练方法,通常用于分类和生成模型。
Discriminative Training:
定义:这种训练方法旨在学习数据的条件分布或决策边界,以便区分不同类别之间的差异。它主要关注于对输入数据进行标签分类的任务。这种方法专注于学习直接给出类别标签的条件概率分布,例如,在监督学习中学习从输入到标签的映射。
示例:常见的例子包括支持向量机(SVM)、逻辑回归和神经网络等。
Generative Training:
定义:这种训练方法专注于建模数据的生成分布,试图理解数据的产生方式。它不仅仅关注于分类任务,还试图模拟数据生成的过程。通过学习数据的分布模型,可以生成与原始数据相似的新数据。
示例:典型的例子是生成对抗网络(GANs)、变分自编码器(VAEs)和隐马尔可夫模型(HMM)等。
这两种方法在目标和应用上有所不同。Discriminative training 更多关注于数据分类问题,寻找边界或条件概率,使得能够对输入数据进行准确分类。而 Generative Training 则关注于学习数据的生成过程,以便能够生成与原始数据相似的新样本,同时也可以应用于分类任务。
-
原来的 HMM 中有个高斯混合模型,我们就想使用 DNN 来取代它。然而,高斯混合模型是给定一个 State,输出各声学特征的概率分布,也就是 P(x|a);刚刚讲的 State Classifier 却是给定一个声学特征向量,输出其属于各个状态的概率分布,也就是 P(a|x)。这二者似乎是相反的存在。
-
不过,我们还是可以根据贝叶斯定理对其进行变换,变换公式如下:P(a) 可以从训练资料里统计而出,P(a|x) 则就是 DNN 的输出,P(x) 咱们不管。这样做的最大好处就是对原来的公式改动很少,实现了模组化管理。
-
那么,为什么用 DNN 去计算 P(x|a) 要比高斯混合模型计算来的好呢?有的人认为,DNN 的训练过程是 Discriminative training,而原来的 HMM 则是 Generative Training,前者要更好。然而,事实上,虽然 HMM 是生成模型,但是它也可以使用 Discriminative training,并且也有很多人在 DNN 前做过相关研究了。也有人觉得他厉害之处在于 DNN 拥用有更多参数。但这小看了参数量也大起来时,GMM的表征能力,最终实际上 DNN 用的参数和 GMM-based HMM 使用的参数是差不多的。
-
实际上,这篇论文的贡献在,它让所有的给定观测计算当前可能状态概率,都共用了一个模型。而不是像GMM那样,每一个 State 都需要有它们自己的 GMM,有着不同的 mean 和 variance。所以它是一个非常厉害的以数据作为驱动的状态标注的方法。
-
那么,DNN 的效果如何呢?事实证明它非常强大。要知道,DNN 可以不是全连接层组成的那种网络,而是可以是任何类型的神经网络,比如 CNN,LSTM 等等。
五、DNN 中 State Classifier 的训练方式
-
那么我们如何去训练 State Classifier 呢?它的输入是一个声学特征,输出是它是某个状态的概率。我们训练这个之前,需要知道每个声学特征和状态之间的对应关系。但实际中的标注数据都是没对齐的,只有声学特征和对应的文本。
-
过去的做法是先训练一个 HMM-GMM,有了以后你就可以算出概率最大的 Alignment,有了对齐方式就可以去训练 State Classifier 了。
-
不过这样也会有人担心,HMM-GMM 不是说表现不好吗,用它的结果来训练 DNN 是不是不太好?那么我们也可以用刚刚训练好的第一代 DNN 再替换 HMM-GMM,给出新的对齐序列,再用它来对 DNN 进行迭代,这样可以一直循环训练下去,一直到你满意为止。
-
那这样做的结果咋样?很强!在2016年,微软就宣称,他们使用 DNN-HMM Hybrid 训练出来的模型结果已经可以与人类的能力相媲美,具体体现在人类的识别错误率和机器的识别错误率相当,而且人类识别错误率的计算是微软专门找专业听写人员进行测量的。
-
2017年,IBM 公司用同样的方法再次减少了识别的错误率,不过,这一次人类识别率又降低了一些(找的人更厉害)。事实上,语音识别的公认错误率指标大概在5%左右,就已经很强了。专业听写人员就在这个水平。因为正确答案也是人标注的,也存在5%左右的错误率。模型能达到5%算是极限了。很难再往上提升了。
-
实际生产中,因为要考虑到推断速度,端对端的深度学习模型并不多,除了谷歌的手机助理。大部分采用的都是混合模型。
-
那么如何提高正确率呢?大家都用的混合模型,能做的事情就是不断加深 DNN 的深度。比如在微软公开的资料中,他们训练了一个49层的残差神经网络。输出有9000个状态类别,输出是一个向量,用的是Softmax作归一化。