答主 @王赟 Maigo 的回答已经把声学模型,发音词典和语言模型的关系过程阐述的很清晰了,本回答主要针对神经网络语言模型在语音识别中的应用做一些补充。
先来简单回顾一下神经网络语言模型。语言模型 (Language Models) 是语音识别系统中的重要组成部分,语音识别的核心公式如下
其中 就是语言模型,语言模型用于计算一段词序列 的概率
这可进一步表示为一系列单个词的条件概率的乘积,这些条件概率取决于它们各自的前文序列。这也是当前统计语言模型的核心公式,在大规模训练语料库中用合适的模型统计分析得到词与词之间的关系依赖,即语义信息。n 元语法模型就是用马尔科夫假设限制了前文的长度,然后用频率近似代替概率,是一种非常简单有效的建模方法。从公式 (2) 中可以看出统计语言建模的关键是学习长距离前文依赖关系 (long-span context depedency),但是用 n 元语法模型直接对长距离历史信息进行建模,即 n 的取值较大时,通常会由于需要统计的情况呈指数级增长,并且很多种情况不会出现在语料库中,从而导致严重的数据稀疏问题,这也是 n 元语法模型的局限。
近些年随着深度学习的发展,神经网络语言模型 (neural network language model) 由于能将词向量映射到低维连续空间,因此逐渐成为主流方法,具备不错的泛化性能。最早的神经语言模型是基于前馈神经网络 (feedforward neural network, FNN) 的,初步实现了对长文本序列在低维连续空间的建模,但这种方法能够处理的文本长度依然受限于网络的输入长度,而后循环神经网络 (recurrent neural network, RNN) 为代表的语言模型利用循环结构则可以在理论上对无限长的文本建模,性能得到极大提升;而后基于长短期记忆循环神经网络 (long short-term memory recurrent neural network, LSTM-RNN) 的语言模型则适当解决了 RNN 在长历史序列建模时梯度消失的问题,如下图所示,在各种任务上都取得不错的效果。
近年来基于 Transformer 的语言模型在自注意力机制作用下对长文本具有更强的建模能力,包括一个自注意力层和前馈层,以及残差连接,层归一化等模块,再利用位置编码引入单词序列的顺序信息,如图 2 所示,Transformer 语言模型在一系列自然语言和语音的任务上均取得最优性能。
从上述语言模型的发展中可以看出,研究核心在于如何提高模型对于长历史序列信息的建模能力,这也是神经语言模型在语音识别应用中需要考虑的核心问题。
从公式 (1) 中可以看出,语言模型 在语音识别任务中是作为一个先验项的,在贝叶斯公式中也确然如此。声学模型 是为了找出能产生声学信号 的最有可能的 ,但是在隐马尔科夫模型中我们可知实际上声学模型找到的是每一帧语音对应的最大概率的文本,因此只用声学模型得到文本序列是不考虑语义信息的,由于同音字词的存在识别结果往往很差;而语言模型就是在正常语料上训练,在声学模型得出的结果中选择出最符合语义和语法习惯的结果,因此语言模型虽然只是一个先验项,但在实际应用中是不可或缺的。
在声学隐马尔科夫模型上得到我们想要的结果的过程称为语音识别的解码 (decoding),使用较多的方法有动态网络 (dynamic network) 解码,有限加权状态转换器 (weighted finite state transducer) 解码等。在利用声学模型和发音词典把音素等信息解码为单词信息后,我们会在进行剪枝等一系列操作后把结果存储在一张图之中,称为词图 (lattice),如下图所示
对词图直接解码往往可以产生多条候选结果,我们可以利用性能更好的语言模型,重新评估所有的候选序列,得到最优的识别结果。在之前搜索与解码一节中,讲述了在解码初期通常会加入一些简单的 n 元语法模型作为先验,这是由于 n 元语法模型相对简单,历史序列较短且自带概率信息,而神经语言模型每次概率值都需要计算,其输出层的 Softmax 函数计算复杂度较高,且更适合长文本序列的建模,因此神经语言模型并不适用于早期解码过程,一般都是用于对初次解码结果进行重打分,有 N-best list 重打分和词图重打分 (lattice rescoring) 两种方法。
N-best list 重打分较容易理解,就是直接在词图上进行解码得到 N 条最好的结果,称为 N-best list。然后引入一个神经语言模型对所有结果重新打分然后排序,选出最好的结果。由于神经网络语言模型对自然语言的建模能力比 n 元语法模型更强,因此,神经网络语言模型重打分对语音识别结果的准确率有较大的提升,如下图所示
然而 N-best list 重打分的性能很大程度上依赖于 N 的取值,当 N 取值较大时,会出现大量的冗余信息导致重复计算,而当 N 取值较小时,实际上的搜索空间很小,很难保证所取 N-best list 包含较好的结果,导致很多有用信息丢失,扩展性不强。而且这种方法需要将整个句子输入后才能得到最终识别结果,在实时语音应用场景中会出现一定延迟。
另一种方法是直接在词图上重打分,词图重打分是对于初始解码生成的词图进行遍历扩展,利用语言模型将词图中所有的边上的分数重新计算,存储为新的词图,取词图中的最优路径得到解码结果。这种方法采用拓扑排序的方式遍历词图的每一条边,并且在遍历时记录下从开始节点到当前节点路径上的词序列,作为当前词的历史信息,因此可以充分利用此图中所有信息。
由于词图是一种图的表示形式,必然会出现某一个节点是多个节点的后继,可以称为汇聚节点,如图 4 中两条边 the 汇聚到同一节点。对于汇聚节点,由于有存在多条路径于它和开始节点之间,使得当前词存在多个历史。在遍历到汇聚节点时,我们需要构造出该节点的拷贝节点,将其扩展成一系列节点,并将其连接的边全部复制过来,如下图 5 所示,边 the 之后的节点会存在两条不同的序列。因此这种方法存在搜索空间巨大的问题,尤其是神经语言模型是基于长历史序列建模,为了在计算后面单词时考虑所有可能的路径,需要对词图进行扩展,而这种扩展会呈指数级增长,计算资源和内存消耗大,解码速度慢。
为了解决这一问题,减小运算复杂度,可以使用一些历史聚类或剪枝等策略。所谓历史聚类 (history clustering),就是对于两个不同的历史向量,用一定的方法测量到两者的相似度,当两者相似度达到一定程度时,可以近似认为是同一路径。可以采用 n 元语法模型或其他方法进行聚类,把合并相似的路径,降低计算量。这种方法一定程度上借鉴了马尔科夫假设,即认为长距离的词其对当前词的影响会逐步减少,因此对最近的一段序列进行聚类,如下图 5 所示
可以看出,在图 4 的原始词图进行回溯时,相似的路径 <s> see the 和 <s> sees the 可以视为相同的路径。历史聚类由于能在汇聚节点处将相似的历史通过聚类方法合并,因此对汇聚节点进行扩展时,可有效减少扩展次数,从而减少神经网络语言模型的计算量,这种在词图重打分的方法产生出的 1-best 路径可以取得和 n-best list 重打分相当的效果,而且可以在每一步都产生出当前最优的序列,因此也可以广泛用于实时语音识别等任务中。
看起来到目前为止还没有针对语音识别系统整体工作原理的科普,那么我就来补上这个空缺吧。
语音识别系统的目的,是把语音转换成文字。具体来说,是输入一段语音信号,要找一个文字序列(由词或字组成),使得它与语音信号的匹配程度最高。这个匹配程度,一般是用概率表示的。用表示语音信号,表示文字序列,则要求解的是下面这个问题:
一般认为,语音是由文字产生的(可以理解成人们先想好要说的词,再把它们的音发出来),所以上式中条件概率的顺序就比较别扭了。没关系,我们有贝叶斯公式,可以把条件和结论拧过来:
第二步省略分母是因为我们要优化的是,而不含,是常数。
上面这个方程,就是语音识别里最核心的公式。可以这样形象地理解它:我们要找的,需要使得和都大。表示一个文字序列本身的概率,也就是这一串词或字本身有多“像话”;表示给定文字后语音信号的概率,即这句话有多大的可能发成这串音。计算这两项的值,就是语言模型和声学模型各自的任务。
====================
先说语言模型(language model)。语言模型一般利用链式法则,把一个句子的概率拆解成其中每个词的概率之积。设是由组成的,则可以拆成:
每一项都是在已知之前所有词的条件下,当前词的概率。
不过,当条件太长的时候,概率就不好估计了,所以最常见的做法是认为每个词的概率分布只依赖于历史中最后的若干个词。这样的语言模型称为n-gram模型,在n-gram模型中,每个词的概率分布只依赖于前面n-1个词。例如在bigram(bi-是2的前缀)模型中,是拆成下面这种形式的:
n-gram模型中的n越大,需要的训练数据就越多。一般的语音识别系统可以做到trigram(n=3);Google似乎可以做到n=7。
为了利用到历史中比较久远的信息,人们还创造了许多种其它的语言模型,例如基于神经网络的语言模型。由于训练数据量的限制,这些模型单独使用时性能一般并不好,需要跟n-gram模型结合使用。
====================
再说声学模型(acoustic model)。声学模型的任务是计算,即给定文字后,发出这段语音的概率。首先第一个问题就是:怎么才能知道每个单词应该发什么音呢?这就需要另一个模块,叫作词典(lexicon),它的作用就是把单词串转换成音素串。词典一般认为是跟声学模型、语言模型并列的模块。词典中会遇到一词多音的问题,但这里就不节外生枝了。
有了词典的帮助,声学模型就知道给定的文字串该依次发哪些音了。不过,为了计算语音与音素串的匹配程度,还需要知道每个音素的起止时间。这是通过动态规划算法来进行的,利用动态规划算法,可以高效地找到音素的分界点,使得每一段语音与音素的匹配程度(用概率表示)之积最大。实际使用的算法称为Viterbi算法,它不仅仅考虑了每一段语音与音素的匹配程度,还考虑了在各个音素之间转换的概率;后者是通过隐马尔可夫模型(HMM)估计出来的。
(实际系统中使用的是比音素更小的单位,不过原理是一样的,也不展开了)
在求音素分界点的过程中,以及在有了分界点后计算时,声学模型都需要知道怎样计算一个音素与一段语音信号的匹配程度。要做这件事,需要找到一种合适的表示语音信号的方法。一般是把语音信号分成许多帧,对于每一帧,通过傅里叶变换等一系列操作,把它转换成一个特征向量。最常用的特征是MFCC,具体提取过程可以参见语音识别技术中提取的声音特征的参数具体指什么? - 频谱分析。从训练数据中,我们可以提取出大量的特征向量,以及它们对应的音素;利用这些数据,就可以训练从特征到音素的分类器。前些年最常用的分类器是高斯混合模型(GMM),它的大致原理是估计出每个音素的特征向量的分布,然后在识别阶段,计算每一帧的特征向量由相应音素产生的概率,把每一帧的概率相乘,就得到。现在,神经网络渐渐火了起来,它可以直接给出,用贝叶斯公式可以转换成,再相乘得到。
====================
从上面的叙述来看,求文字串、计算语言模型概率、求音素串、求音素分界点、计算声学模型概率几个步骤似乎是依次进行的。其实不然,因为文字串、音素分界点都有非常多种可能,枚举是不现实的。实际中,这几个步骤同时进行并互相制约,随时砍掉不够优的可能,最终在可接受的时间内求出最优解。