背景和基础知识

Posted by lili on

这个模块介绍语音识别的背景和基础知识。更多本系列文章请点击微软Edx语音识别课程

目录

基础理论

视频——模块内容简介

欢迎来学习模块1,在这里我们会学习使用机器学习方法来实现语音识别系统的基础知识。学完本模块后,你会知道一些需要学习什么以及学会后能做什么,下面让Mike来介绍本模块的主要内容。

在本模块,我们会学习理解语音识别系统需要的基础知识。我们会简要的介绍语音产生过程,为了构建语音识别系统我们怎么用计算机来建模这个过程。接下来会介绍怎么评价语音识别系统效果的好坏。

在这个模块里,我们会介绍声音,尤其是人类的语音。我们也会介绍语音的产生过程,人类是怎么发出语音的。这是Phonetics的研究方向,它研究人类发出的各种语音。接下来我们会介绍语音的层次结构:语音是怎么由句子组成;句子又是怎么分解成词;词又可以分解为音节(Syllable);最后音节又由语音最基础的单元音素(Phoneme)组成。

语音识别系统有三个基础部分,首先是声学模型,它是一个分类器,给它一些声音片段,它会预测最可能的音素序列。再就是语言模型,它研究词之间的组合关系,哪些词的序列更可能出现。这两个模型结合起来就得到所谓的语音识别基本等式。

了解了语音识别系统的基本概念之后我们最后介绍怎么评价一个系统的好坏。

Introduction

声音和语音

语音识别是一个交叉学科,设计的学科包括语言学、计算机科学和电子工程。

本课程重点关注北美英语。其它各种语言和英语的差别有大有小,比如有的语言会区别语调(汉语)。

Phonetics

Phonetics

Phonetics是语言学的一个细分领域,它主要研究人类的语音。它包括语音的产生过程(通过人类的发音器官),语音的声学特性和语音的感知过程。Phonetics有有三个分支,它们都会和自动语音识别系统有关。

  • 发音语音学(Articulatory Phonetics) 它关注通过发音器官产生语音的过程,以及各种发音器官。

  • 声学语音学(Acoustic Phonetics) 它关注在空气中传输的语音信号的特效。

  • 听觉语音学(Auditory Phonetics) 它关注听者接受和感知语音的过程。

语音的最小单元是音素(phoneme),一个词是由一个或者多个音素组成。一个音素的一种声学实现叫做phone,所谓的声学实现可以理解为一种发音方式,这跟说话人的性别、年龄、地域以及外部的声学环境都有关系。下图是北美英语的常见音素表。

图:英语的音素

英语的音素通常分为元音(vowels)和辅音(consonants)。

元音有两个重要特性。首先它们是浊音(voiced),也就是声带有气流通过(读者可以尝试发一个元音时把手放到嘴边感受一下),气流通过声门时会引起它规律的开启与闭合,从而产生周期的信号,这个周期对应的频率就是基频(fundamental frequency)或者pitch。其次,我们的舌头和口腔不会阻碍空气的流动(尝试一下把嘴堵住还能不能发出元音)。发声器官包括舌头、嘴唇和下颚的不同位置会产生不同的发音。这些发音器官的不同状态会使得声道形成不同的共振,这就是共振峰(formants),不同的元音有不同共振峰的共振频率。

辅音都会对气流产生某种程度的阻碍(比如我们发b的时候首先闭嘴阻碍空气的流动,然后张口让气流迅速通过),辅音可以是浊音,也可以是清音(unvoiced)——也就是没有空气流动的。比如/b/是浊辅音,而/p/是清辅音。清音是没有气体通过声带的,因此也就没有周期性的基频或者pitch。

音素的一个重要特性是它的具体发音会受到它周围的音素的影响,这种现象叫做协同发音(coarticulation)。影响一个音素的周围音素叫做它的语音上下文(phonetic context)。连续的音素由于协同发音的影响会改变其原始的发音。一个音素由于协同发音产生的不同发音叫做allophone。

所有SOTA的语音识别系统都会在建模一个音素时考虑它的语音上下文。

词和句法

音节和词

一个音节是一个声音的序列,由一个核心(nucleus)的phone和可选的开始和结束phone组成。核心phone一般是元音或者能当主音的辅音,它是浊音并且可以是喊叫或者被歌唱的。

比如,”bottle”包含两个音节。第一个音节有3个phone,用Arpabet的表示为”b aa t”。其中”aa”是核心phone,”b”是浊辅音作为音节的开始phone,而”t”是清辅音作为结束的phone。第二个音节是可以当主音的辅音”l”。

一个词有一个或者多个音节组成,“Eye”、“uh”和“eau”都是一个音节的词。

在语音识别里,我们很少考虑音节。通常我们建模是认为词是由音素序列组成。

句法和语义

句法描述一个句子怎么由词组成以及规定它们的语法结构。语义是指句子的词和短语的意义。句法和语义都是自然语言处理的研究内容,通常语音识别系统不考虑它们。

衡量效果的指标

词错误率

当构建一个语音识别系统的时候,我们会进行很多次实验,因此需要有一个指标能衡量模型的好坏。因为语音识别的输入和输出都是一个序列,因此我们的指标需要考虑整个序列。

最常见的指标是词错误率(Word Error Rate, WER),它是基于编辑距离(Edit Distance)算法的。和正确的词序列相比,它有替换、插入和删除三种错误,换一种思路,为了把正确序列变成模型的序列(或者反过来)需要最少进行多少次替换、插入和删除操作。比如下面的例子:

参考脚本(Reference) 模型预测(Hypothesis) 错误类型
however how 替换
  never 插入
a a  
little little  
later later  
we he 替换
had had  
a   删除
comfortable comfortable  
chat chat  

为了把参考脚本变成模型预测的结果,我们最少要经过4词操作:把however替换成how;在howerver后面插入never;把we替换成he;删除a。

因此词错误率的定义为:

\[WER = \frac{N_{\text{sub}} + N_{\text{ins}} + N_{\text{del}}}{N_{\text{ref}}}\]

其中,\(\text{N}_{\text{sub}},\text{N}_{\text{ins}},\text{N}_{\text{del}}\)分别代表替换次数、插入次数和删除次数。

那给定两个字符串怎么计算最少需要的编辑次数呢?这是一个经典的算法,可以使用动态规划来解决,读者可以参考wiki

另外一个评价的指标是句子错误率,如果一个句子完全正确就是1,只要有错误就是0。但是一个句子错一个词和错十个词都是一样的,这个指标并不实用。

显著性测试

显著性测试是统计里常用的技巧,比如模型比baseline高出多少就算”显著”的提高。不过这语音识别系统里并不常用,我们就略过。

其它

RTF

除了识别的准确率,另外一个很重要的指标就是处理的速度和延迟。因为语音识别的很多应用都是要求实时性的,比如语音助手,用户说完话之后如果你需要处理一分钟,即使准确率100%,这样的系统肯定是没法使用的。

我们通常用实时率(Real Time Factor, RTF)来衡量识别的速度,实时率等于识别花的时间除以语音本身的时间。实时率为1就表示用户一说完话结果就能出来(前提是忽略假设录音实时的传给语音识别系统,时间情况很多时候是在服务器端进行解码的,因此会有网络的延迟)。实时率大于1就表示话说完了,系统还得再处理一段时间。而实时率小于1表示识别速度比说话速度快,这样万一有网络延迟,它还能追上来。

基本公式

语音识别最后是变成一个统计优化问题。给定输入的观察序列\(\mathbf{O} = \left\{ O_{1},\ldots,O_{N} \right\}\),我们需要寻找最可能的词序列\(\mathbf{W} = \{ W_{1},\ldots,W_{M}\}\)。也就是寻找使得概率$P\left( \mathbf{W} \middle \vert \mathbf{O} \right)$最大的词序列,用数学语言描述就是:

\[\hat{W} = argmax_{W}P(W|O)\]

通过贝叶斯公式,我们可以把它变成:

\[P\left( W \middle| O \right) = \frac{P\left( O \middle| W \right)P\left( W \right)}{P(O)}\]

因为观察序列的概率$P(O)$是固定的,它与词序列是无关的,因此上式等价于:

\[\hat{W} = argmax_{W}P\left( O \middle| W \right)P(W)\]

上式就是语音识别系统的基本公式。语音识别的过程就是在所有的词序列里寻找使得上式最大的那一个。

上式中$P(O \vert W)$叫做声学模型,它描述的是给定词序列$W$时声学观察为$O$的概率。声学模型负责建模词序列是怎么转换成声学实现的,然后把它在ASR系统里表示除了。声学特征和声学模型会在模块2和模块3中介绍。

而$P(W)$叫做语言模型,它只关心词序列$W$。语言模型计算一个词序列的概率。它用的训练数据应该和最终语音识别系统应用的场景相匹配。一个英语的语言模型可能会给词序列”I like turtles”比较高的概率,而对于”Turtles sing table”它计算出的概率应该比较低。语言模型使得语音识别搜索的时候更倾向于”更可能”的句子。当然语言模型也可以在其它场景使用,比如输入自动补全。模块4会介绍语言模型。

当然实际的语音识别系统远比上面介绍的基本公式复杂,后面我们会详细的介绍这些细节。

Lab1

这个实验实现语音识别系统的评价,也就是计算一个模型的词错误率(WER)。

在这个实验里,我们会用写Python代码来计算测试数据集上的词错误率(WER)和句子错误率(SER)。这个代码的输入是语音识别系统输出的脚本(transcription)和参考的正确的脚本。

这里假设脚本是NIST创建的trn格式,这个文件的每一行是一个utterance的脚本,然后是一个空格,然后是用括号括起来的文件名。比如录音文件”tongue_twister.wav”,这一行为:

sally sells seashells by the seashore (tongue_twister)

注意脚本没有任何表达和首字母大写,也没有任何其它格式(比如把”doctor”变成”dr.”,把”eight”变成”8”)。这种格式叫做”Inverse Text Normalization”。

Python代码M1_Score.py和wer.py提供了基本的程序骨架。M1_Score.py的main函数解析好了参数,并且wer.py实现了编辑距离算法,函数string_edit_distance()用于计算两个字符串的编辑距离,我们可以直接使用。

我们需要增加代码来读取模型预测和参考的trn文件,计算它们的编辑距离,并且统计各种错误数据,具体来说需要统计如下信息:

  • 测试集中参考脚本的句子个数
  • 错误的句子个数
  • 句子错误率
  • 参考脚本的词的个数
  • 错误的词的个数
  • 替换、删除和插入错误的个数
  • 词错误率

具体的输出格式不做要求。注意我们不能假设参考trn文件和模型预测trn文件的顺序是一致的,我们应该用utterance的key来比较。当代码完成后,使用misc目录下的hyp.trn和ref.trn来做测试。

请读者一定想办法自己实现,如果实在做不出来可以参考我的实现。请尽量自己完成,否则不会有太大的收获!