(一)语音识别基本概念

写在前面
这是CMUSphinx系列教程的第一篇,文章译自官网,文中很多概念能翻译的尽量用中文翻译出来,并在后面跟上原英文,实在翻译不出来的就用原英文了,相信不会影响到大家的理解。如有翻译不当之处,请多但待并指出,谢谢!


语音是一个复杂的现象(phenomenon)。人们很少能理解它是怎样产生以及被感知的(perceived)。一个直观的感知(perception,和前面的感知意思类似,只不过词性不同)通常是:语音是由多个词(words)构建的,而每个词又是由多个音素(phones,语音学概念,但在多数情况下和语言学中phonemes(音位)的概念不做区分)构成的。但是很不幸,事实却和人们所感知的差别很大。语音是一个动态的过程,在它的每一部分之间没有明确的界限。因此,了解一段语音的一个很有效的方式是通过一个声音编辑器去观察(look into)下语音的波形(rcording),并去听一下。这是一段通过音频编辑器打开的语音的波形
image
当前所有对语音的刻画的方法或多或少都是用概率。这意味着在单元与单元,或者词与词之间不存在确定的界限。语音转写(speech to text)以及其他语音方面的应用不存在100%正确的情况。这和传统的软件开发人员的想法是相悖(rather unusual)的,他们通常是在确定的(deterministic)系统上进行工作的。这就产生了很多只属于语音技术的概念和话题。

语音的构成

目前的实践(practice)中,语音结构的描述如下文所示:
语音是一个连续的音频流,它是由相对稳定的状态和剧烈变化的状态混合而成的。在这些状态序列里,人们可以针对声音(sound)或者音素(phones)根据相似性定义一定数量的类别(我的理解是,作者想要表达的意思是确定一种建模方式,对于每一种建模方式,建模单元的数量是可以确定的)。词(words)通常被理解为是由音素(phones)构建的,但事实并不如此。一个音素对应的波形(waveform)的声学特性(acoustic properties)的变化会严重依赖于音素上下文(phone context)、说话人(speaker)、语音的风格(style)等等。所谓的协同发音(coarticulation,可以理解为一个音素的发音会受到相邻音素的影响,为了使发音自然连贯,人类在发音时总会使用协同发音以使音素与音素之间过渡平滑),会使得音素听起来和它原本的发音(canonical,单个音素的发音)差异很大。因为词与词之间的过渡所蕴含的信息要比稳定区域(stable regions,这里指一个词的内部)多得多,语音开发人员谈论的更多的是diphones,即两个音素相邻的部分(包括前一个音素的末尾部分和后一个音素的起始部分)。有时,他们也会谈论subphonetic单元,即一个音素的不同子状态(substates,这就是多音素建模方式的思想)。通常,一个音素可以根据不同的特性分成三个或更多的区域(regions)。
对于三个的情况很好解释:音素的第一部分依赖于它的前一个音素,中间的是稳定的自身的部分,第三部分依赖于它的下一个音素。这就是为什么在语音识别中一个音素常常包含三个状态。
有时,音素会被放到上下文中进行考虑。这些在上下文中的音素被称为三音素(triphones)甚至是五音素(quinphones)(注意:无论是考虑多少个相邻音素,这些音素都是一个音素,而不是将多个音素当作一个音素)。例如在单词”bad”中,”u”的左边是音素”b”,右边是音素”d”,它的发音和单词”ban”中,左边是音素”b”,右边是音素”n”的”u”发音就有点不同。注意,和diphones不同的是,考虑上下文的多音素和不考虑上下文的音素,对于同一个音素来说,它们在波形上的范围是一样的,多音素并不是将多个音素组成一个“大”的音素。它们只是因为发音有区别用不同的名字表示而已。
举例来说,如果你想对一个三音素的起始创建一个检测器,并将它在多个三音素之间共享,为了降低计算量,一个有效的做法是只检测(detect)部分三音素而不是检测所有(这里对detect的概念不是很明白,我的理解是,理论上,对于有 N 个音素的模型,对应的三音素个数是 N 3 ,而实际系统中,可以采用一些手段来降低三音素的个数,如下面提到的决策数聚类方法)。这样,大量的声音检测器(sound detector)就可以用少量的具有区分度的声音检测器来代表(很多三音素类似,可以将它们聚在一起,共享参数,经过聚类之后,不同类别之间的三音素区分度是比较大的)。通常我们是以哦嗯4000个具有区分性的声音检测器去组成三音素的检测器。我们称这些检测器为senones(也称为tied triphone states,即将分布类似的状态聚成一类共享参数)。一个senone可以依赖除了左边和右边的上下文以外更多的上下文信息。可以通过决策数或者其他方式定义相当复杂的函数。
音素也可以构成子词单元,如音节(syllables)。有时,音节被定义为“减少的稳定实体”(reduction-stable entities)。举个例子,当语音变得快的时候,音素经常会变化,但是音节就可以保持不变。同时,音节还可以反映语调轮廓(intonational contour)。除了音节,还有其他方式构建子词,即基于形态学的(morphologically-based)或者基于发音的(phonetically-based)。子词常常被用于开放词汇(open vocabulary)语音识别。
子词构成词。在语音识别中,词是很重要的,因为它们极大地限制了音素的组合。如果有40个音素,平均每个词有7个音素,那就有 40 7 个词。庆幸的是,在实际生活中,人们的常用词汇不超过20000个,这使得语音识别变得更可行。
词和其他非语言的声音(non-linguistic sounds,这些声音我们称为填充物(fillers),具体有呼吸声、表示犹豫或说话中间停顿的嗯声(um)、表示不肯定、不清楚或征求同意的啊声(uh)以及咳嗽声)构成了语音片段(utterances,语音学概念,人在说话时,两个较长停顿之间说的语音片段称为一个utterance,与句子(sentence,语言学概念,句子是具有更强的语义概念的)不是一个概念)。
还有其他的一些概念这里就不表了(dialog acts like turns)。

识别过程

目前通用的语音识别方式如下:有一段波形,通过静音(silences)将它分割成若干个语音片段(utterances),然后识别每一个语音片段说的是什么。要想实现上述想法,我们需要穷举出所有可能的词的组合,然后和音频进行匹配(match),选择最好的匹配组合。
在匹配过程中,有几个重要的概念。第一是特征(features)。因为参数的数量非常大,我们尝试减少它。通常会将语音分成帧(frames),然后在帧的单位上计算参数数量。对于每一帧,通常选择10ms作为一帧的长度,然后提取39个数来表示语音。这39个数就构成了一个特征向量。至于这39个数怎么计算是一个活跃的研究方向,但是一个简单的方式是,它可以从声谱(spectrum)中得到。
第二个概念是模型(model)。一个模型描述了一些数学对象,这些对象集合了口语说的话(spoken word)的共同属性。实际上,对于一个senone音频模型,模型就是指它的三个状态的高斯混合,简单地说,它是最有可能的特征向量(这里是按照原文翻译的,可能不太好理解,我个人理解是模型就是通过高斯混合模型去刻画每一帧特征向量的分布,并将特征向量对齐到HMM每一个状态上去)。从模型的概念,可以导出如下议题:
- 1.模型对实际语音的刻画能力有多好
- 2.如果模型内部有问题,可以使模型变得更好吗
- 3.如果条件发生变化模型的适应能力有多强
语音的模型称为隐马尔可夫模型(Hidden Markov Model,HMM)。它是一个用于刻画黑盒通信信道(black-box communication channel)的通用模型。在这个模型中,过程被描述为一系列状态以特定的概率进行跳转。这个模型试图去描述包括语音在内的任何序列过程。HMMs已经被证明在语音解码(speech decoding)中是确实有效的。
第三,就是匹配过程本身。因为将所有的特征向量和所有的模型进行比较是非常耗时的,因此通常会应用很多技巧来优化搜索过程。在任何时候,我们保存最佳匹配的变量,并随着时间推移对其进行扩展,为下一帧生成最佳匹配变量(动态规划的思想,对于每一帧来说,它前面走过的路径是最优的)。

模型

按照语音结构,在语音识别中有三个被用到的模型去进行匹配:
-声学模型(acoustic model)
对于每一个senone,声学模型包含了其声学特性。有上下文无关的模型和上下文相关的模型两种。
-发音字典(phonetic dictionary)
发音字典包含了从词到音素的映射关系。这个映射并不是非常有效。例如,对大多数音素,字典中只记录了两种或三种不同的发音方式。但是,这在绝大多数情况下也够用了。字典并不是将词映射到音素的唯一方法。你也可以使用一些通过机器学习算法学习到的复杂的函数来进行映射。
-语言模型(language model)
语言模型用于限制词的搜索范围。它定义了哪个词可以跟在前一个已经被识别出来的词的后面(因为匹配是一个序列的过程,只有识别出前一个词才能识别后一个词),并且通过剔除不可能的词来帮助我们极大地限制匹配的过程。最广泛使用的语言模型就是n-gram语言模型(统计词序列)和有限状态(finite state)语言模型(通过有限状态自动机,有时还带有权重,来定义语音序列)。要想获得好的识别精度,你的语言模型必须限制搜索空间上做的非常成功。这就意味着它应该非常善于预测下一个词。一个语言模型常常会限制被考虑包含的单词的词汇量。这是命名识别(name recognition)中的一个问题。为了处理这种情况,一个语言模型可以包含更小的块(chunks),如子词甚至音素。但要注意的是,在这种情况下对搜索空间的限制要差很多,因此识别的精度也会比基于词的语言模型要低。
在一个引擎中,这三个部分被组合到一起用于识别语音。如果你想用你的引擎去识别其他的语言,你需要把这些部分放在适当的位置。对很多语言来说,有声学模型、发音字典甚至大词汇量语言模型可供下载。

其他常用概念

-Lattice
一个Lattice是用于表示所有识别可能的有向图(directed graph)。通常,获得最佳匹配是不实际的(动态规划只能获得局部最优,无法保证全局最优)。在这种情况下,lattices是一种好的用于表示识别结果的中间形式。
-N-best lists
和lattices类似,但是没有lattices稠密(只保留前N条概率最大的路径)
-词混淆网络(Word confusion networks)
和lattices一样,只是格式更为规整
-语音数据库
-文本数据库
用于语言模型训练。需要将格式转化成口语文本形式(spoken text form),即,将标签和头移除,将数字转化成口语的形式,将缩写转化为完整形式。

评价指标

当语音识别开发完成后,最复杂的问题是使搜索精确,并使搜索速度达到最快。因为模型不完美,另一个挑战是使模型匹配语音。
通常系统会在测试集上进行测试,评价指标如下:
-词错误率(Word error rate)
假设我们有一个原始的文本以及长度为N个词的识别文本。I是插入词(inserted words)的数量,D是删除词(deleted words),S表示替换词(substituted words)。则词错误率可以通过下式计算:

W E R = ( I + D + S ) / N

词错误率通常用百分数来表示。
- 准确率(Accuracy)
和词错误率类似,但是不考虑插入错误的情况:
A c c u r a c y = ( N D S ) / N

在绝大多数情况下,准确率都是一种比词错误率更差的衡量指标,因为插入错误对最终的结果也非常重要。然而,对于一些任务,准确率是一个合理的评价指标。
- 速度
包括录音的时间和解码的时间
- ROC曲线
当我们谈论检测任务时,会有虚警(false alarms)和命中/错过(hits/misses)的概念。用ROC曲线可以描述它们。ROC曲线试图找出最佳点,在这个点上虚警小而命中数100%匹配上(意思是所有被命中的都是应该被命中的,即precision为100%)。关于ROC曲线可以参考 维基百科
还有一些其他一些不常被考虑但是对于很多应用很有用的特性。你的第一个任务应该是创建该评价方式并且将其应用到系统开发中。你的第二个人无是收集文本数据库,然后测试你的应用的性能怎么样。

猜你喜欢

转载自blog.csdn.net/xm1076709179/article/details/82218262