摘要 | Abstract

        这是一篇对语音识别中的一种热门技术——GMM/DNN-HMM混合系统原理的透彻介绍。

        当前网上对HMM类语音识别模型的讲解要么过于简单缺乏深度,要么知识点过于细化零碎分散。而本文旨在为语音识别方面知识储备较少的读者,从头开始深入解读GMM-HMM模型和DNN-HMM模型。

        在本文里,我们:

  1. 讨论了语音识别里的两个重要概念:声学模型和语言模型,
  2. 介绍了语音和文本的数据预处理技术,
  3. GMM-HMM模型的训练、预测方法和统计学意义,及在此基础上,
  4. DNN-HMM模型的构建。

        以下是本文目录

摘要 | Abstract

1.前言 | Introduction

2.问题描述 | Problem Statement

3.相关研究 | Related Work

4.方法 | Method

4.1.声学模型与语言模型

4.2.声学模型的构建:GMM-HMM之训练

4.2.1.预处理语音:音频分帧与特征提取

4.2.2.预处理文本:音素、三音和状态

4.2.2.1.音素(phoneme)

 4.2.2.2.三音子(tri-phone)

4.2.2.3.状态(state)

4.2.2.4.捆绑状态(tied-state)

4.2.3.GMM-HMM模型之训练

4.2.3.1.GMM模型

4.2.3.2.HMM模型

4.2.3.3.GMM-HMM与声学模型的关系

4.2.3.4.GMM-HMM模型之训练

4.2.3.5.将Viterbi算法用于隐序列更新(文本对齐)

4.2.3.5.1.将最大化声学模型概率问题转化为最短路径问题

4.2.3.5.2.Viterbi算法解最短路径问题

4.2.4. 小结

4.3. 语音的解码:GMM-HMM模型之预测

4.3.1.将找隐序列以最大化联合概率问题转化为最短路径问题

4.4.深度学习的力量:DNN-HMM模型

5.结语 | Epilogue

参考资料


1.前言 | Introduction

        近期想深入了解语音识别(ASR)中隐马尔可夫模型(HMM)和深度神经网络-隐马尔可夫(DNN-HMM)混合模型,但是尽管网络上有许多关于DNN-HMM的介绍,如李宏毅教授的《深度学习人类语言处理》[1],一些博主的语音识别系列文章[2],斯坦福大学HMM课件[3]。但是这些材料要么不够细致完备,要么对初学者来说过于复杂深奥(尤以HMM部分的琳琅满目的概率公式为首)。

        因此,笔者在阅读了大量相关资料后希望用深入浅出的方式为大家系统地介绍DNN-HMM混合模型。本文旨在为零基础者从头解析使用DNN-HMM混合方法的语音识别系统的底层原理

        笔者希望让仅仅具备本科概率论基础的人也能读懂,如果你符合这个条件但仍觉得理解起来困难,你可以留下你的疑惑,以帮助我们改进文章。

        

2.问题描述 | Problem Statement

        我们直入主题,语音识别模型是这样一个模型,它将一串语音信号X(如一个仅包含语音的.wav音频文件)作为模型的输入,目的在于输出一个与之最为匹配的文字内容\hat{Y}(为了简化问题,本文只考虑英文场景,其它语言原理基本类似)。其中,当我们说“最为匹配”的时候,我们主要考虑的是“最有可能”的,亦即,语音识别模型希望在给定X时,给出\hat{Y},使得:

\hat{Y}=argmax_{Y}\{P(Y|X)\}

上式意味着,我们要找使得P(Y|X)最大的Y,记作\hat{Y}
        要解决这个问题,一个最直观的办法就是穷举所有可能的Y,然后比一比他们的概率P(Y|X),再选出最大的那一个。显然这个想法是不现实的,因为所有可能的Y也许是一个无穷的集合。再者,就算能够缩小范围,枚举出大量比较可能的候选Y,又如何比较概率P(Y|X)的大小呢?因而枚举法似乎不是好的选择。

        HMM类的方法则选择使用贝叶斯理论对概率进行处理,这我们在后面会详细说明。在此之前,笔者想为大家简单讲讲其它的更清晰的解决思路。

3.相关研究 | Related Work

        得益于今日神经网络技术的快速发展,熟悉深度学习的我们很容易联想到,似乎只要利用大量的音频以及对应的文本标注进行训练,不需要额外的人工处理应该也能做到很好的泛化能力(即拿到新的语音信号时可以准确地给出真实的文字答案)吧?

        答案是:确实有,这种办法被称为Listen Attend, and Spell,简称LAS[4]。它使用一个深度学习模型,直接用声音信号和人工标记的文字训练,在推理时听到新的声音信号就能给出它认为最匹配的文字内容。由于直接输入音频信号X就能推理出其中的文字\hat{Y},LAS被归为端到端(End to End)模型。

        不得不说,LAS这种方法确实是最符合(机器学习研究者的)直觉的,就像其它任何的机器学习任务(如图像识别)一样,训练和推理再好理解不过了。

        除了即将要介绍的HMM类模型,LAS、Transformer[5],还有CTC[6],RNN-T[7]等。这些内容不是本文的重点,就不一一介绍了。

        尽管LAS等端到端模型操作非常简单无脑,但是在过去的很长一段时间内,这些堪称暴力的方法并没有想象中的那么强。至少在2020年时,商业语音识别系统的主力军还是咱们今天文章的主角DNN-HMM[1],同时DNN-HMM模型也是第一个被宣称达到人类同级别语音识别水平的模型[8]。接下来我们就要展开介绍HMM类模型:GMM-HMM系统和DNN-HMM混合系统。

4.方法 | Method

        前文提到,语音识别的任务可以简化为概率问题——在给定X时,给出\hat{Y},使得:

\hat{Y}=argmax_{Y}\{P(Y|X)\}

由于不好直接求得P(Y|X)以进行比较,但在HMM系统中,我们可以对人说话的发音方式建模(这部分在后文会详细介绍),进而容易得到的是P(X|Y)。故我们引入贝叶斯公式将上式反转,即作以下变型:

\hat{Y}=argmax_{Y}\{P(Y|X)\}=argmax_{Y}\{\frac{P(X|Y)P(Y)}{P(X)}\}

其中由于去掉分母P(X)不影响分式的大小比较,上式又等价于求:

\hat{Y}=argmax_{Y}\{P(X|Y)P(Y)) \}

       这其中,我们P(X|Y)声学模型(Acoustic Model),称P(Y)语言模型(Language Model)。(对,就是Chat GPT一类的语言模型)

        这样,我们就将不容易估计的概率转变成容易估计的概率。接下来我们简要解释声学模型和语言模型的含义,以及为什么说他们容易估计。

4.1.声学模型与语言模型

        首先是声学模型P(X|Y),按字面意思理解,它就是给定文字内容Y,其对应发音结果为音频X的概率。这个过程是一个正向的过程,是较好估计的。举一个不那么恰当的例子,如在中文里,文字“朝阳”对应的发声结果中,发出类似于“cháo yáng”或者“zhāo yáng”的概率是比较大的,但发出任何其它的声音的概率都是比较小的。笔者认为,这也是该概率被称为“声学模型”的原因,因为它描述的是“念”某一文字发出某一声音的概率,即某文字的“发声概率”。

        以上的例子只是为了简要说明“声学模型”的内涵而并不具有严谨性,对于某一文字内容对应应该发出什么声音,应考虑更全面更深入的因素,而通过拼音的方式进行描述是抽象而模糊的。事实上,HMM正是声学模型,其提出者将文字的发音过程简化作一个隐马尔可夫模型。这部分内容我们会在后文详细介绍,在此不多赘述。

        至于语言模型P(Y),则是用于描述某一文字Y出现的概率,也代表其出现的合理性。如在英文里的经典例子,“识别语音”的英文“recognize speech”和“毁坏一个好沙滩”的英文“wreck a nice beach”的发音是一模一样的。但是,由于后者的词语搭配缺乏合理性(也可理解为在大量的各类文字材料中后者出现的频率小得多),其概率P(Y)也小得多,故在二者的声学模型取值相同(因为发音完全一样)的情况下,“recognize speech”是具有更高可能的识别结果。在实践中,我们会统计各词语在各种语境(上下文环境)中出现的频率,作为语言模型使用。时常,这样的统计还不足够令人满意,我们也会从逻辑的角度出发对目标材料进行合理扩展。另外,作为评判文字出现合理性的语言模型,成果缔造了Chat GPT这类能生成很多“合理”对话的聊天机器人。由于语言模型不是行文的重点,我们推荐有兴趣的读者查阅语言模型的其它相关材料,不再拓展阐述。

        值得一提的是,即便是对于LAS之类的端到端模型,也即没有使用贝叶斯公式变换出P(Y)这一式子,而是直接求解原问题\hat{Y}=argmax_{Y}\{P(Y|X)\}的模型,也会引入语言模型P(Y),即LAS等模型在实际上会求解\hat{Y}=argmax_{Y}\{P(Y|X)P(Y)\}。尽管这一表达式缺乏逻辑,但在实践中却能起到可观的效果,其原因可能在于这些模型本身不能很好地估计P(Y|X),因而来自语言模型的修正可以生效[1]。

        回到语音识别的问题上来,我们的目标是找到使得声学模型P(X|Y)和语言模型P(Y)相乘最大的Y。换一个角度理解:语言模型可以基于声学模型所生成的词组的合理性对语音识别结果进行重打分(rescoring),以帮助改进识别质量。

4.2.声学模型的构建:GMM-HMM之训练

        前文已经提到,在搭建声学模型P(X|Y)的过程中,我们引入了HMM模型,其原因在于可以将发声的过程看作是是隐马尔可夫过程。但是在深入分析HMM相关内容之前,为了叙述逻辑的通畅,我们还是先从P(X|Y)这一式子讲起。

        当我们想进一步探讨P(X|Y)这一式子时,第一个难题立马扑面而来:文本先不提,这个音频也太复杂了点。须知,在概率论里面,我们最喜欢的就是(1)意义明确的、(2)情况可能有限且尽量少的问题(如明天是否下雨这个问题就很好估计,因为情况少而且每种情况有明确的意义)。

        但是作为音频的语音信号,即便是在进行数字采样(在这里,我们假定读者已经了解音频数字采样的知识)后,每分钟的语音也至少有:

(1信道) x (8,000赫兹采样率) x (2 ^ 16种信号强度)= 524,288,000 种可能情况

        再加上音频的每一个数值只是代表信号在那个时间点的强度(振幅),没有什么实际的参考意义,因为不能直接和文字信息对应上。

        综上,我们需要一种降维+特征提取的手段,这就是音频分帧和特征提取。

4.2.1.预处理语音:音频分帧与特征提取

        特征提取的目的是降维和赋予数据意义,而分帧则是特征提取的前提。音频分帧就是将音频X切片,分为一小段一小段的内容,一个小段就是一帧(frame)。分好后再对每一帧分别进行特征提取。

        在实践中,我们通常会每10ms取一个帧,一个帧的长度是25ms。当然这意味着相邻的帧之间会有重叠。

图1 对语音信号进行分帧,图源[1]

       

        对于每个分好的帧,(对8k赫兹采样率来说)具有25ms x 8,000Hz=200个采样点,我们对这些采样点进行特征提取。需要提取什么特征呢?有一点很重要的启发就是:人对声音的音高是非常敏感的。因此,我们可以在音高上做文章,用傅里叶变换把每一帧中各个音高的能量表达出来。当然,这还不够,由于人耳在声音提取上是有偏好的,即对不同音高的灵敏度不同,于是人们依据经验设计了一种考虑这个因素的特征表示方法:梅尔倒频谱系数(MFCC)。

        在这里,我们不介绍MFCC的具体提取流程,只说明其结果是:将每一帧的音频内容转换为一个39维的向量,这39位数字,代表了39个人耳非常敏感的频段上的强度。

图2 音频信号分帧与MFCC特征提取过程,图源[9]
图3 音频信号MFCC特征提取结果,图源[9]

        于是,通过MFCC,我们就达到了降维(200+维至39维)和特征提取(39个人耳敏感频段强度)的效果。同时,我们也就将语音信号X分解成了T个帧,每个帧使用39维向量x_{i}i\in 1,2,...,T 表示,即:

X=x_{1}x_{2}...x_{T}

        当然,除了MFCC以外,还有其它的特征提取方式,但其性质与MFCC无本质区别。

4.2.2.预处理文本:音素、三音和状态

        因为每一个语音帧足够的短(25ms),我们可以近似认为每个帧内最多只能发出一个独立的音,而由于文本中每一个最小单元(如中文的字和英文的字母)和发音的最小单位很多时候都不是一一对应的,可以存在一对多关系(如一个汉字由声母+韵母组成)和多对一关系(如“China”中的ch两个字母是一个完整的音)。

4.2.2.1.音素(phoneme)

        所以当我们在讨论文字的发音概率P(X|Y)时,我们最希望使用一个个完整的音,而非单纯的文本中的最小单位(token),来对应语音信号中的各帧中的内容。而这里我们讲的“一个完整的音”,在语言学里有个专有名词,叫做“音素”(phoneme)。事实上,我们中学学的英文音标中的元音辅音就是音素。

图4 音标表,图源[10]

        于是我们需要引入文本的预处理,将文本拆分成独立的音素,再去和音频内容作对应、求概率。在拆分音素的过程中,是需要查表(音标表/拼音表等)完成的。

图5 一个英文句子的音素拆分[1]
 4.2.2.2.三音子(tri-phone)

      然而在实践中人们发现,使用音素与音频内容对应时常还不够精准,因为即便音标表告诉了我们每个音素单独的发音,但是考虑音素与音素相组合时产生的变化。当前后相接的音素不同时,相同的音素也可能发出不同的声音。要考虑这个问题,我们引入了细化版本的音素——三音子(tri-phone)它表示的是一个音素在前后接不同音素时的发音。请注意划线句子的宾语——三音子是“一个音素”的发音,因而是更为细分的音素,其范围比音素小。表示方法为:

[前音素]-[当前音素]+[后音素]

图6 三音的划分,图源[1]
4.2.2.3.状态(state)

        事实上,拆分成三音子后还是不够精细。通常还需要再将每一个三音子在时间层面上拆分成3个阶段。即一个三音子是由3个发音阶段组成的,这些部分被称为状态(state)。表示方法为:

[前音素]-[当前音素]+[后音素] [i]

其中i取1、2或3。

图6 状态的拆分,图源[1]

        如此这般,我们才能够将一段文本内容拆分成微小的部分(就是状态state),使得每一个微小的部分,不论在任何文本环境下,发音都一样。这就是4.2.2.小节的最终目标。但经过了三次拆分,我们遇到了新的问题。

4.2.2.4.捆绑状态(tied-state)

        新的问题是,这样分状态实在太多了,粗略计算:英文音素48种[10],能够两两组合的约30-40种[1],粗略估计35种,三音就是35的3次方个,再乘以3个状态,总共是

35\times35\times35\times3=128,625

种状态。

        要知道,对于每一个状态我们都需要把握它发音的情况如何(通俗地说就是大概发什么音),就要基于大量的统计材料去观测。而如此多的状态数量,给我们的统计观测带来了巨大的挑战。因此,我们还要再把这么多的状态中发音类似的状态给捆绑(tie)起来变成一类对象,叫做捆绑状态(tied-state)。在实践中,这个捆绑的可以由语言学逻辑推理完成,也可以用观察大量材料统计归纳的方法完成。经过这样的筛选后,最后捆绑状态大概在小1万个的水平。

        经过本小节的多次处理,我们终于将文本变成了一个个发音各自独立的小单位,其全名叫“捆绑的三音状态”,英文“tied tri-phone states”。但为了书写方便,以下我们将其简写作“状态”,请勿混淆。

        此时,文本Y可以写作一系列状态组合成的序列s_{1}s_{2}...s_{N},其中s_{i}\in 所有状态集合S,即

Y=s_{1}s_{2}...s_{N}

4.2.3.GMM-HMM模型之训练

        在4.2.1.和4.2.2.两个小节中,我们已经成功将声学模型P(X|Y)中的XY分别拆解成了帧的特征向量序列X=x_{1}x_{2}...x_{T}和状态序列Y=s_{1}s_{2}...s_{N}。于是可以对声学模型转化:

P(X|Y)=P(x_{1}x_{2}...x_{T}|s_{1}s_{2}...s_{N})

        接下来要做的事是,对P(x_{1}x_{2}...x_{T}|s_{1}s_{2}...s_{N})进行建模,也就是弄清楚给定X=x_{1}x_{2}...x_{T}Y=s_{1}s_{2}...s_{N}后,这个函数究竟是怎么求的。这里我们就要引入GMM和HMM这两个模型了。

4.2.3.1.GMM模型

        首先是GMM,GMM全称是高斯混合模型(Gaussian Mixture Model),这个高斯就是高斯分布(正态分布)里面的高斯。高斯模型讲的是同一类别的东西倾向于长得差不多(服从高斯分布),而高斯混合模型讲的是很多分属于几个类别的东西混在一起,难以分辨类别,但其中每一类别内的东西长得差不多(服从这个类别的高斯分布)。

        GMM的应用场景是:有若干对象,我们不知道对象各自所属的类别,也不知道各类别的高斯分布参数,只知道对象的特征和有几个类别,然后最终目标是实现这堆东西的聚类并给出类别的高斯分布参数。例如:直到一些学生的身高,其中有男有女,但不知道谁是男的谁是女的,假设男女身高各自服从一个高斯分布,要求哪些身高是男的,哪些身高是女的,还有两个高斯分布的参数(均值和方差)。

        这个问题的具体求解过程请参考其它资料如[11]。请注意,尽管我们在这里不讲述GMM的求解过程,但是这个问题的解决思想(EM算法)会在后面讲的GMM-HMM求解过程中体现。

        语音识别中引入高斯模型的意义在于:同一个状态(state)在不同发声者、不同场景下,所发出的声音是类似的,被认为是服从同一个高斯分布的,而要判定一些帧的语音信号各属于哪个状态,就需要用到GMM,因为GMM能给出一个状态s_t产生某一语音帧x_t的概率P(x_t|s_t)我们称这个概率P(x_t|s_t)发射概率(Emmision Probability)。提示:如果使用MFCC对语音帧进行特征提取,那么高斯分布就有39组均值和方差。

        但是,到目前为止GMM还不能开始训练,我们需要把每一个帧都赋予一个状态,而在P(x_{1}x_{2}...x_{T}|s_{1}s_{2}...s_{N})中,帧数T通常大于状态数N,而。这就需要HMM作用了。

4.2.3.2.HMM模型

        HMM全称隐马尔可夫模型(Hidden Markov Model)。先讲马尔可夫模型,它表示一个对象在每个时刻都能处于某个状态,而对象在下一个时刻的状态由且仅由当前时刻的状态而决定。隐马尔可夫模型则在此基础上增加一个条件——对象的状态是不可见的(隐的),但是每个状态都会依一个概率分布产生某个可以观测的表现。比如两个骰子A和B,A有1234点数的四个面,B有123456点数的六个面。投骰子的时候不知道投的是哪个,只知道点数。这里面A/B就是状态,点数就是表现。

        不难看出,如果把语音里面的状态看作下一个状态仅由当前状态决定的马尔可夫模型,那么整个声学模型部分就是一个HMM,(音素)状态就是HMM中的(隐藏的)状态,语音帧就是HMM中观测到的表现

        在HMM中,有两个重要的参数,1)当前状态向下一状态转移时的概率,2)每个状态的各种表现的概率分布。沿用前文中的符号,1)可以写作P(s_{t+1}=j|s_t=i),即已知某一时刻t时状态为i,那么下一时刻为状态j的概率,这被称为转移概率 (Transmission Probability)。2)则是4.2.3.1.中提到的发射概率P(x_t=o|s_t=i),即已知时刻t时状态为i,那么对应(观测到)的语音帧为o的概率。

        注意,转移概率还应包括初始概率P(s_1),即第一个隐状态为各个状态的概率。

图7 HMM模型示意图,图源[12]

        我们说,只要能够得到发射概率和转移概率,那么就能完成新的信号的语音识别。其具体做法我们将在4.3.节中展示。现在,我们将展示如何估计这两个概率。

4.2.3.3.GMM-HMM与声学模型的关系

       要合理估测发射概率和转移概率,首先肯定是要找到大量的语音信号和相对应的文字内容标注。找到合适的发射概率和转移概率函数,使得文字生成对应的语音的概率P(X|Y)最大。

        回顾声学模型P(X|Y)=P(x_{1}x_{2}...x_{T}|s_{1}s_{2}...s_{N}),我们发现一段对应的语音和文本的帧数T和状态数N并不一致。因此在开始训练之前,还先要做文本的对齐,把状态序列分配到语音帧上去(这是因为大多数时候语音样本和对应的文本标注只给到句子级别,难以确定各音素/状态发声的具体时间点和长短)

        我们假定每个语音帧x_t都对应一个隐状态h_th_t的取值是可能的音素状态s_n,其中s_n \in {s_1, s_2, s_3, ..., s_N},而t的取值为1T。由于T>N,要使长度为N文本状态序列Y=s_{1}s_{2}...s_{N} “铺满”长度为T的隐状态序列h_{1}h_{2}...h_{T},存在多种可能的方式(如可以把任何一个状态s_n在当前位置复制T-N次,其它状态不变)。而假设总共有K种可能,其中第k种可能的隐状态序列记作h_{k_{1}}h_{k_{2}}...h_{k_{T}},声学模型即可化为:

\begin{aligned} P(X|Y)&=P(x_{1}x_{2}...x_{T}|s_{1}s_{2}...s_{N})\\&=\sum_{k=1}^{K}P(x_{1}x_{2}...x_{T}|h_{k_{1}}h_{k_{2}}...h_{k_{T}})P(h_{k_{1}}h_{k_{2}}...h_{k_{T}}|s_{1}s_{2}...s_{N}) \end{aligned}

        其中P(x_{1}x_{2}...x_{T}|h_{k_{1}}h_{k_{2}}...h_{k_{T}})由GMM发射概率联乘给出,而P(h_{k_{1}}h_{k_{2}}...h_{k_{T}}|s_{1}s_{2}...s_{N})由HMM转移概率计算。至此,我们就将GMM-HMM模型与声学模型划上了等号。

        请注意,直到这一步我们才说明了为什么HMM类模型是声学模型P(X|Y)而非直接对P(Y|X)建模。而作为对笔者入门语音识别帮助最大的参考资料的[1]和许多其它材料均未提及HMM是P(X|Y)的真正原因。这也是笔者写这篇文章的主要原因,希望此处的解析能对感兴趣的读者提供帮助。

4.2.3.4.GMM-HMM模型之训练

        在做GMM和HMM训练的时候,我们希望确定使如下概率最大的发射概率和转移概率(GMM-HMM模型参数),即求:

argmax_{\Theta}\{\sum_{k=1}^{K}P(x_{1}x_{2}...x_{T}|h_{k_{1}}h_{k_{2}}...h_{k_{T}})P(h_{k_{1}}h_{k_{2}}...h_{k_{T}}|s_{1}s_{2}...s_{N})\}

其中,\Theta为GMM-HMM模型参数的集合。

        但在实际操作中,枚举所有的隐序列尽管是可能的,但一定是繁琐的。所以我们作以下近似,将求和变为最大值,即求:

argmax_{\Theta}\{\max_{k}P(x_{1}x_{2}...x_{T}|h_{k_{1}}h_{k_{2}}...h_{k_{T}})P(h_{k_{1}}h_{k_{2}}...h_{k_{T}}|s_{1}s_{2}...s_{N})\}

        该近似成立的前提是,Y通过所有隐序列产生X的概率,正比于Y通过概率最大的隐序列产生X的概率。这个前提本身是具有说服力的。

        而一个隐序列又能唯一确定一组\Theta,上式又等价于求:

argmax_{h_{k_{1}}h_{k_{2}}...h_{k_{T}}}\{P(x_{1}x_{2}...x_{T}|h_{k_{1}}h_{k_{2}}...h_{k_{T}})P(h_{k_{1}}h_{k_{2}}...h_{k_{T}}|s_{1}s_{2}...s_{N})\}

        所以还是要先确定文本的对齐,随后便可解出发射概率和转移概率。其过程是这样的:

# 算法1  用于求解发射概率和转移概率的EM算法

(1) 将状态序列s_{1}s_{2}...s_{N}按照先后顺序不变的方式均匀复制后分到各个语音帧x_{1}x_{2}...x_{T} ,并记作隐状态序列h_{1}h_{2}...h_{T} *;

(2) 对隐序列计算GMM参数,即计算每个状态的所有对应语音帧的均值和方差;

(3) 对当前的状态序列计算HMM参数,即用隐序列中状态s_n向状态s_m转移的频次除以状态s_n向所有状态转移的频次作为状态s_n向状态s_m转移的概率P(h_{t+1}=s_m|h_{t}=s_n),其中s_n可以等于也可以不等于s_m

(4) 使用Viterbi算法调整隐状态序列 h_{1}h_{2}...h_{T}  **;

(5) 再次计算GMM和HMM参数并更新

(6) 如果旧的GMM、HMM参数与新的参数差别不大(小于某一给定阈值),则结束,否则转至步骤(4)继续执行。

------------------------------------------------------------------------------------------------------------------------

注释:

*:例如,若T=2N,则将状态序列按不变顺序复制成两份s_{1}s_{1}s_{2}s_{2}...s_{N}s_{N},即h_{1}h_{2}h_{3}h_{4}...h_{T-1}h_{T}=s_{1}s_{1}s_{2}s_{2}...s_{N}s_{N}。如果不是整数倍,则随机选几个状态多复制一点,此处选择的不同对结果影响不大。

**: Viterbi算法求解该问题过程见4.2.3.5.

        而初始概率则通过统计所有样本中各个音素作为第一个音素出现的概率获得。

4.2.3.5.将Viterbi算法用于隐序列更新(文本对齐)

        首先我们指出,Viterbi算法是一种求最短路径的算法,如图8中,从S到E,只能从左往右走,每条路径的距离事先给出,求最短路径。

图8 篱笆形路径图,图源[12]
4.2.3.5.1.将最大化声学模型概率问题转化为最短路径问题

        那么算法1中的隐序列更新是怎么变成最短路径算法的呢?首先不难猜到,整个待更新的隐状态序列h_{1}h_{2}...h_{T}就对应着S到E中的每一列,而找到最合适的隐序列就等于从每一列中选择一个状态组成路径。但为什么是最短路径呢?

        在声学模型里,我们通过最大化以下式子来得到隐序列h_{1}h_{2}...h_{T}

P_{acoustic}^{(N)}=P(x_{1}x_{2}...x_{T}|h_{1}h_{2}...h_{T})P(h_{1}h_{2}...h_{T}|s_{1}s_{2}...s_{N})

        从头开始分析,首先由于文本和音频整体已经对应好了,所以h_1肯定是对应状态序列里第一个状态s_{1}的,记第一个位置的声学模型概率P_{acoustic}^{(1)}

P_{acoustic}^{(1)}=P(x_{1}|h_1)P(h_1|s_{1}s_{2}...s_{N})=\left\{\begin{matrix} P(x_1|s_1), & \textrm{if } h_1 = s_1\textrm{,}\\ 0 ,& \textrm{otherwise.} \end{matrix}\right.

        那么h_2对应什么呢?有可能还是第一个状态s_{1},但也有可能已经变成了第二个状态s_{2}了,别无其它可能(不可能跳过s_{2}直接转移到后面的状态)。那这时候h_2对应s_{1}和对应s_{2}的时声学模型概率分别是多少呢?我们写出第二个位置的声学模型概率P_{acoustic}^{(2)}

\begin{aligned} P_{acoustic}^{(2)}&=P(x_{1}x_2|h_1h_2)P(h_1h_2|s_{1}s_{2}...s_{N})\\&=P(x_{1}|h_1)P(x_{2}|h_2)P(h_1|s_{1}s_{2}...s_{N})P(h_2|h_1,s_{1}s_{2}...s_{N})\\&= P_{acoustic}^{(1)}P(x_{2}|h_2)P(h_2|h_1,s_{1}s_{2}...s_{N})\\&=\left\{\begin{matrix} P_{acoustic}^{(1)}P(x_{2}|h_2)P(h_2|h_1), &\textrm{if } h_2=s_1 \textrm{ or }s_2 ,\\ 0 ,& \textrm{otherwise.} \end{matrix}\right.\end{aligned}

        显然,我们希望挑选出使得概率P_{acoustic}^{(2)}最大的h_2,也就是要挑选使转移概率和发射概率的乘积P(s_i|s_1)P(x_2|s_i)最大的 i ,i=1,2

        继续往下推进,不难得出t+1个位置的声学模型概率与第t个位置的声学模型概率的递推关系

\begin{aligned} P_{acoustic}^{(t+1)}&=P(x_{1}x_2...x_{t+1}|h_1h_2...h_{t+1})P(h_1h_2...h_{t+1}|s_{1}s_{2}...s_{N})\\&= P_{acoustic}^{(t)}P(x_{t+1}|h_{t+1})P(h_{t+1}|h_1h_2...h_t,s_{1}s_{2}...s_{N})\\&=\left\{\begin{matrix} P_{acoustic}^{(t)}P(x_{t+1}|h_{t+1})P(h_{t+1}|h_t), &\textrm{if } h_{t+1}\textrm{ is possible } ,\\ 0 ,& \textrm{otherwise.} \end{matrix}\right.\end{aligned}

其中,h_{t+1} is possible 表示在给定h_t=s_n后,h_{t+1}有可能的取值:

h_{t+1}=\left\{\begin{matrix} s_{n}, &\textrm{when }t\geq n \textrm{, or,}\\ s_{n+1}, &\textrm{when }T-t= N-n. \end{matrix}\right.

        其原因是要保证隐序列h_{1}h_{2}...h_{T}满足能够对应状态序列s_{1}s_{2}...s_{N}的先后顺序的要求,如图9中展示了一个T=5N=3 的隐序列选择图(实际上是路径选择图,我们后面会证明)。

        如果对声学概率模型P_{acoustic}^{(t+1)}取负对数,作损失函数:

L^{(t)}=-logP_{acoustic}^{(t)}

则有,第一个值:

L^{(1)}=\left\{\begin{matrix} -logP(x_{1}|h_{1}),&\textrm{if } h_{1}=s_1,\\ +\infty ,& \textrm{otherwise.} \end{matrix}\right.

递推公式:

L^{(t+1)}=\left\{\begin{matrix} L^{(t)}-logP(x_{t+1}|h_{t+1})) -logP(h_{t+1}|h_t), &\textrm{if } h_{t+1}\textrm{ is possible } ,\\ +\infty ,& \textrm{otherwise.} \end{matrix}\right.

        要使声学模型概率最大,就要使上式最小。这样,我们就把求隐序列问题转换成了最短路径问题,路径长度(若存在)由L^{(t+1)}-L^{(t)}=-logP(x_{t+1}|h_{t+1})) -logP(h_{t+1}|h_t) 给出。如图9为一个隐序列路径示意图。

图9 三个状态五个语音帧的路径图,图中线段的标注为距离

       综上,我们发现,给定发射概率和转移概率,寻找声学模型概率P(x_{1}x_{2}...x_{T}|h_{1}h_{2}...h_{T})P(h_{1}h_{2}...h_{T}|s_{1}s_{2}...s_{N})最高的隐状态序列就等于在形如图9的图中找到从左至右的最短的路径,而图9是图8的一个特例

4.2.3.5.2.Viterbi算法解最短路径问题

        现在我们已经将算法1中第(4)步改进隐序列的问题和求最短路径的问题联系上了,那么Viterbi算法又是怎么求最短路径的呢?参考资料[13]对此的讲解非常好,在此笔者不做赘述,只对其进行简要提炼:

        回顾图8的篱笆形路径图,我们发现在所有可选路径必须每一列中的(不多不少)一个结点,所以从起点到第k列都有且仅有n_k个距离,其中n_k为该列的结点数。假设第k+1列有n_{k+1}个结点数,那么求从起点到第k+1列的n_{k+1}个距离时,只需取前一列n_k个结点到下一列的结点的最小值就行了。得到第k+1列的n_{k+1}个距离后,记录这n_{k+1}个距离各自经过前一列的哪一个结点。以此类推直到到达终点,然后根据记录进行回溯,便能得到起点到终点的最短路径。

        一点启发:如果读者了解单源最短路径算法的迪杰斯特拉(Dijkstra)算法,那么不难发现两者存在相似性——每到一个新的结点时,都只保存起点到此处的最短距离(及路径)。

4.2.4. 小结

        到这里,我们就讲完了整个声学模型的训练。在4.2.中,我们主要讲了GMM-HMM模型训练,其中包括:

  1. 对语音进行了特征提取,
  2. 对文本进行了向音素状态的转换
  3. 训练GMM-HMM系统,得到了语音识别系统中最重要的两个参数:发射概率和转移概率。

4.3. 语音的解码:GMM-HMM模型之预测

        在得到合理的GMM/HMM参数之后,我们就可以对新的语音信号做语音识别了。而从语音信号得到文本的过程,也被称为解码(decode)。回顾语音识别的目标式:

\hat{Y}=argmax_{Y}\{P(X|Y)P(Y)) \}

        这里仍旧只讨论前半部分的声学模型P(X|Y)

        有了4.2.中文本音素状态转换和音频特征提取的经验,我们可以改写目标式:

\hat{S}=argmax_{s_{1}s_{2}...s_{N}}\{P(x_{1}x_{2}...x_{T}|s_{1}s_{2}...s_{N})\}

而同时

\hat{Y}=f_{spell} (\hat{S})

表示预测文本\hat{Y}可以通过查字典(lattice)等一定方法从状态序列\hat{S}中解出。这一过程是很好理解的,有状态就有音素,有音素就能组成读音,进而拼写出单词。遇到多音字问题则可以通过语言模型P(Y)辅助判断。

        但与训练时的问题一样,此时的S=s_{1}s_{2}...s_{N}X=x_{1}x_{2}...x_{T}在长度上依然是不对应的,依然需要引入隐序列h_{1}h_{2}...h_{T}解决问题,有:

P(x_{1}x_{2}...x_{T}|s_{1}s_{2}...s_{N})=\sum_{k=1}^{K}P(x_{1}x_{2}...x_{T}|h_{k_{1}}h_{k_{2}}...h_{k_{T}})P(h_{k_{1}}h_{k_{2}}...h_{k_{T}}|s_{1}s_{2}...s_{N})

        和训练时一样,再做求和变求最大值的近似:

P(x_{1}x_{2}...x_{T}|s_{1}s_{2}...s_{N})\approx max_{k}P(x_{1}x_{2}...x_{T}|h_{k_{1}}h_{k_{2}}...h_{k_{T}})P(h_{k_{1}}h_{k_{2}}...h_{k_{T}}|s_{1}s_{2}...s_{N})

        记使得该概率最大的隐序列

h_{1}h_{2}...h_{T}=argmax_{h_{k_{1}}h_{k_{2}}...h_{k_{T}}}P(x_{1}x_{2}...x_{T}|h_{k_{1}}h_{k_{2}}...h_{k_{T}})P(h_{k_{1}}h_{k_{2}}...h_{k_{T}}|s_{1}s_{2}...s_{N})

        则原概率可化为:

\begin{aligned} P(X|Y)&=P(x_{1}x_{2}...x_{T}|s_{1}s_{2}...s_{N})\\&=\sum_{k=1}^{K}P(x_{1}x_{2}...x_{T}|h_{k_{1}}h_{k_{2}}...h_{k_{T}})P(h_{k_{1}}h_{k_{2}}...h_{k_{T}}|s_{1}s_{2}...s_{N})\\&\approx max_{k}P(x_{1}x_{2}...x_{T}|h_{k_{1}}h_{k_{2}}...h_{k_{T}})P(h_{k_{1}}h_{k_{2}}...h_{k_{T}}|s_{1}s_{2}...s_{N})\\&= P(x_{1}x_{2}...x_{T}|h_1h_2...h_T)P(h_1h_2...h_T|s_{1}s_{2}...s_{N})\\&=P(x_{1}x_{2}...x_{T},h_1h_2...h_T|s_{1}s_{2}...s_{N})\end{aligned}

        而由于得到隐序列h_{1}h_{2}...h_{T}就可以反推状态序列s_{1}s_{2}...s_{N},故找一个状态序列以最大化上式就等价于找一个隐序列最大化联合概率,即求:

        h_{1}h_{2}...h_{T}=argmax_{h_{1}h_{2}...h_{T}}P(x_{1}x_{2}...x_{T},h_{1}h_{2}...h_{T})

        如果上面的式子都理解起来比较困难,读者只需要知道以下结论:在预测新的样本时的声学模型部分,我们希望找到隐序列使该隐序列和语音帧序列共同出现的概率最高。而这个问题,同样可以通过化为最短路径问题用Viterbi算法解决。

4.3.1.将找隐序列以最大化联合概率问题转化为最短路径问题

        与4.2.3.5.1.中的方法相似,我们一步一步探讨概率P(x_{1}x_{2}...x_{T},h_{1}h_{2}...h_{T}),依次是

P(x_{1},h_{1})=P(h_1)P(x_1|h_1)

\begin{aligned} P(x_{1}x_{2},h_{1}h_{2})&=P(h_1)P(x_1|h_1)P(h_2|h_1)P(x_2|h_2)\\&=P(x_{1},h_{1})P(h_2|h_1)P(x_2|h_2) \end{aligned}

给出递推公式:

P(x_{1}x_{2}...x_{t}x_{t+1},h_{1}h_{2}...h_{t}h_{t+1})=P(x_{1}x_{2}...x_{t},h_{1}h_{2}...h_{t})P(h_{t+1}|h_{t})P(x_{t+1}|h_{t+1})

求负对数得损失函数(越小越好)L^{(t)}=-logP(x_{1}x_{2}...x_{t},h_{1}h_{2}...h_{t})^{(t)},第一个值:

L^{(1)}=logP(h_{1})-logP(x_{1}|h_{1})

,递推关系:

L^{(t+1)}=L^{(t)}-logP(h_{t+1}|h_{t})-logP(x_{t+1}|h_{t+1})

显然,这也是和图9类似的路径问题,路径长度仍然是两个负对数之和。但与图9不同的是,此时没有了【h_{t+1} is possible】的显式要求,因而是类似于图8的一般型路径图。

        代入Viterbi算法即可求出最优隐状态序列h_{1}h_{2}...h_{T}。进而去掉重复(隐)状态得到最优状态序列\hat{S}=s_{1}s_{2}...s_{N},代入\hat{Y}=f_{spell} (\hat{S}) 即可解出最优文本。

4.4.深度学习的力量:DNN-HMM模型

        至此,我们终于讲完了传统模型GMM-HNN的底层原理和流程做法。接下来我们讲一些现代手法,深度神经网络(Deep Neural Network, DNN)能对GMM-HMM模型带来什么改进?

        顾名思义,DNN-HMM相较于GMM-HMM的区别,就是用DNN替换掉了GMM。在4.2.小节中我们提到,GMM的作用在于给出单个音素状态s产生某一语音帧x的发射概率P(x|s)而给出概率这个事情,可是深度学习最在行的了

        我们知道,通过观察大量的语音样本和对应的音素状态概率标注(由GMM模型标注),深度神经网络DNN可以很容易在得到新的语音帧x时给出x对应某一音素状态s_i的概率p(s_i|x),而通过贝叶斯公式进行转换:

P(x|s)=\frac{P(x,s)}{P(s)}=\frac{P(s|x)P(x)}{P(s)}

得到GMM给出的概率P(x|s)与DNN给出的概率P(s|x)之间的关系,而其中P(x)与我们找状态s的过程无关,可以省略,而P(s)则可以从大量样本中统计得到。这样,我们就搭建了GMM的输出P(x|s)与DNN的输出P(x|s)的关系。在保证GMM-HMM的其它模块不变的同时,用DNN代替GMM来产出发射概率P(x|s),就是DNN-GMM模型。所以此时DNN可以看作一个状态分类器(state classifier)。

图10 将GMM换成DNN的过程示意,图源[1]

        当然,作为一股强大力量,DNN可以具有任意形式,比如CNN;而其输入甚至可以不用局限于单个语音帧,比如LSTM。

        但是在引入DNN的过程中,还会遇到一个问题,就是文本的对齐。在训练DNN-HMM前,我们是不知道哪个语音帧对应哪个音素状态的,所以DNN的输入数据就没法配对。虽然GMM-HMM在训练前也面临同样的问题,但是文本的对齐可以在训练的同时给出。所以,我们在引入DNN前,首先还是得做一次常规的GMM-HMM来获得文本的对齐,在此基础上,再训练DNN得到完整的DNN-HMM。

5.结语 | Epilogue

        写到这里已经一万两千字了。

        一直以来笔者都以为语音识别应该不难,但直到把本文写完的今天,才发现仅仅是DNN-HMM这一个模型,就能写一万两千字,更何况本文还大量省略了语言模型、GMM训练等部分。笔者这才明白为什么网上那么多深入普及语音识别技术的文章看着那么“天马行空”,忽略了大量对小白而言难以理解的细节——因为不这样做根本难以写出有深度的内容。

        笔者自知才疏学浅,不足之处还请各位指点。

参考资料

[1] 国立台湾大学李宏毅 (Hung-yi Lee)教授DLHLP2020课程,原网址:Hung-yi Lee (ntu.edu.tw) ,B站搬运Speech Recognition (Option) - HMM_哔哩哔哩_bilibili

[2] AI大道理 - AI大语音(十三)——DNN-HMM (深度解析)-CSDN博客

[3] Stanford University EE365: Hidden Markov Models  hmm.pdf (stanford.edu)

[4] W. Chan, N. Jaitly, Q. Le and O. Vinyals, "Listen, attend and spell: A neural network for large vocabulary conversational speech recognition," 2016 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP), Shanghai, China, 2016, pp. 4960-4964, doi: 10.1109/ICASSP.2016.7472621.

[5] Linhao Dong, Shuang Xu, and Bo Xu. "Speech-transformer: a no-recurrence sequence-to-sequence model for speech recognition."2018 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP). IEEE, 2018.

[6] Graves, Alex & Fernández, Santiago & Gomez, Faustino & Schmidhuber, Jürgen. (2006). Connectionist temporal classification: Labelling unsegmented sequence data with recurrent neural 'networks. ICML 2006 - Proceedings of the 23rd International Conference on Machine Learning. 2006. 369-376. 10.1145/1143844.1143891. 

[7] Graves, Alex. “Sequence Transduction with Recurrent Neural  Networks.”  2012 ArXiv abs/1211.3711

[8] W. Xiong et al., "Toward Human Parity in Conversational Speech Recognition," in IEEE/ACM Transactions on Audio, Speech, and Language Processing, vol. 25, no. 12, pp. 2410-2423, Dec. 2017, doi: 10.1109/TASLP.2017.2756440. 

[9] Ele实验室 - 【语音识别技术】重度鉴赏 

[10] 音素_百度百科 (baidu.com)

[11] 高斯混合模型(GMM) - 知乎 (zhihu.com)

[12] 隐马尔可夫模型(HMM)详解 - 知乎 (zhihu.com)

[13] 何通俗地讲解 viterbi 算法? - 路生的回答 - 知乎

[14] HMM+Viterbi(维特比算法)+最短路径分析 - 小田甜的文章 - 知乎

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐