第1章语音识别概述
小爱同学、小度小度、天猫精灵、叮咚叮咚 我们身边好像突然就出现了一些可以和我们“聊天”的音箱,图1.1所示为百度智能音箱。
图1.1百度智能音箱“小度小度”
智能音箱与传统音箱*大的区别就是能够听懂我们的语音,人们通过说话就能与电子设备沟通,实现信息的检索与查找,比如查询天气、设定闹钟、播放音乐等。这其中*关键的就是语音识别技术。
1.1语音识别技术
语音识别通俗地讲就是将人类语音中的词汇内容转换为计算机可读的输入,让机器知道我们在说什么,这是一门交叉学科,涉及的领域包括信号处理、模式识别、概率论和信息论、发声机理和听觉机理、人工智能,等等。*近几年随着人工智能技术的快速发展,语音识别技术取得显著进步,开始从实验室走向市场。
1.2语音识别技术的发展
自从机器出现以后,通过语音与机器进行交流一直是科研人员的梦想。应用语音识别技术的第一个装置应该是1952年贝尔研究所Davis等人研发的能识别10个英文数字发音的实验系统。
1960年,英国Denes等人成功研制出第一个计算机语音识别系统。而大规模的语音识别研究是在进入了20世纪70年代以后,在小词汇量、孤立词的识别方面取得了实质性的进展。
20世纪80年代,语音识别技术研究的重点逐渐转向大词汇量、非特定人连续语音识别,包括噪声环境下的语音识别和会话(口语)识别系统。在研究思路上也发生了重大变化,即由传统的基于标准模板匹配的技术思路转向基于统计模型的技术思路。当时出现了两项非常重要的技术:隐马尔可夫模型(HMM:Hidden Markov Model)和N-gram语言模型。此外还提出了将神经网络技术引入语音识别领域的技术思路。20世纪90年代以后,在语音识别的系统框架方面并没有什么重大突破,不过在语音识别技术的应用及产品化方面进展很大。
进入21世纪,随着深度学习的不断发展,神经网络之父Hinton提出深度置信网络(DBN:Deep Belief Networks),2009年,Hinton和学生Mohamed将深度神经网络(DNN:Deep Neural Networks)应用于语音识别,在小词汇量连续语音识别任务TIMIT上获得成功。
中国的语音识别技术研究始于1958年,中国科学院声学研究所利用电子管电路实现了识别10个元音的实验系统。1973年,中国科学院声学研究所开始研究计算机语音识别。由于当时条件的限制,中国的语音识别技术研究工作一直处于缓慢发展的阶段。
20世纪80年代以后,随着计算机应用技术在中国逐渐普及和广泛应用,以及数字信号技术的进一步发展,国内许多单位具备了研究语音识别技术的基本条件。与此同时,国际上语音识别技术在多年沉寂之后重又成为研究的热点,迅速发展。在这种形式下,国内许多单位纷纷投入这项研究工作中。
1986年3月,中国高技术研究发展计划(863计划)启动,语音识别技术作为智能计算机系统研究的一个重要组成部分被专门列为研究课题。在863计划的支持下,中国开始了有组织的语音识别技术的研究,中国的语音识别技术进入了一个前所未有的发展阶段。
1.3语音识别技术的原理
语音识别系统可以分为:特定人与非特定人的识别、独立词与连续词的识别、小词汇量与大词汇量以及无限词汇量的识别。但无论哪种语音识别系统,其基本原理和处理方法都大体类似。
1.3.1WAV文件
大家都知道语音(或声音)实际上是一种波,声波经过拾音器(话筒或麦克风)采集后被转换成连续变化的电信号。电信号再经过放大和滤波,然后被电子设备以一个固定的频率进行采样,每个采样值就是当时检测到的电信号幅值。接着电子设备会将采样值由模拟信号量化为由二进制数表示的数字信号。*后是对数字信号编码,并将编码后的内容存储为音频流数据。在计算机应用中,能够达到高保真水平的是PCM(Pulse Code Modulation,脉冲编码调制)编码。编码之后有些应用为了节省存储空间,存储前还会对音频流数据进行压缩,常见的MP3文件就是一种压缩后的音频流数据。
说明
虽然PCM是数字音频中*佳的保真水平,但并不意味着PCM就和原音频一样毫无失真。PCM只是能做到*大限度的无限接近,但依然是有失真的。
处理音频流数据时,必须是非压缩的纯波形文件。WAV就是*常见的无压缩声音文件格式之一(也是采用PCM编码),是微软公司专门为Windows操作系统开发的一种标准数字音频文件,*早于1991年8月出现在Windows3.1操作系统上。WAV文件里存储的内容除了一个文件头以外,就是声音波形的采样点。WAV文件能记录各种单声道或立体声的声音信息,并且能保证声音不失真。不过相比于MP3文件,WAV文件非常大。一般来说,由WAV文件还原的声音的音质取决于声音采样样本的多少(即采样频率的高低),采样频率越高,音质就越好,但WAV文件也就越大。
一个WAV文件的参数包括采样频率、采样精度和声道数,这几个参数介绍如下。
(1)采样频率:每秒钟采集音频数据的次数。采样频率越高,音频保真度越高。常用的采样频率包括11025Hz、22050Hz、44100Hz和48000Hz四种,其中,11025Hz的采样频率相当于电话声音的效果;22050Hz的采样频率相当于FM调频广播的效果;44100Hz的采样频率相当于CD声音的效果。
(2)采样精度:这是用来衡量声音波动变化的参数,也是声卡的分辨率。它的数值越大,声卡的分辨率就越高。目前计算机配置的16位声卡的采样精度包括8位和16位两种。一般讲话以8位11.025kHz采样就能较好地还原。
(3)声道数:有单声道和立体声之分,单声道的声音只能使一个喇叭发声(有的声卡会将单声道信息处理成两个喇叭同时输出),立体声的声音可以使两个喇叭都发声(一般左右声道各有分工),这样更能感受到音频信息的空间效果。显然,立体声数据还原特性更接近人们的听力习惯,但采集的数据量会增加1倍。
1.3.2声学特征提取
有了数字化的音频文件之后,语音识别的第二步是进行声学特征提取。这是语音识别*重要的一环。提取的特征参数必须满足以下要求:
(1)提取的特征参数能有效代表语音特征,具有很好的区分性。
(2)各阶参数之间有良好的独立性。
(3)特征参数要计算方便,*好有高效的算法,以保证语音识别的实时实现。
简单来说,声学特征提取的过程如下:
首先在语音识别之前,通常先把首尾端的静音切除,降低对后续步骤造成的干扰。
其次对声音分帧,也就是把声音切成一小段一小段,每小段称为一帧。分帧操作不是简单地切开,而是通过移动窗函数来实现。帧与帧之间一般是有交叠的。对于典型的语音识别任务,推荐一帧的时间为20~30ms。在这段时间内,人类*多只能说一个音素(根据语音的自然属性划分出来的*小语音单位)。帧与帧之间的重叠率可以根据需要在25%~75%之间选择,通常来说,设置为50%。
分帧后,语音就变成了很多小段。不过波形在时域上几乎没有描述能力,因此,必须对波形进行变换。常见的一种变换方法是提取MFCC(Mel-Frequency Cepstral Coefficients,梅尔频率倒谱系数)特征。梅尔频率是基于人耳听觉特性提出来的,它与赫兹频率成非线性对应关系。梅尔频率倒谱系数(MFCC)则是利用它们之间的这种关系,计算得到的赫兹频谱特征。经过变换,每一帧波形会变成一个多维向量,可以简单地理解为这个向量包含了这帧语音的内容信息。实际应用中,变换又分为预加重、分帧、加窗、快速傅里叶变换(FFT:Fast Fourier Transform)、梅尔滤波器组、离散余弦变换(DCT:Discrete Cosine Transform)等几个步骤,而声学特征也不是只有MFCC这一种。
1.3.3匹配识别
提取音频的声学特征之后,语音识别的*后一步就是通过训练好的模型将这些特征进行分类,进而依据判定准则找出*佳匹配结果。
声学模型是语音识别系统中非常重要的一个组件,对不同基本单元的区分能力直接关系到识别结果。语音识别本质上是一个模式识别的过程,而模式识别的核心是分类器和分类决策的问题。
通常,在孤立词、中小词汇量识别中使用动态时间规整(DTW:Dynamic Time Warping)分类器会有良好的识别效果,并且识别速度快,系统开销小,是语音识别中很成功的匹配算法。但是,在大词汇量、非特定人语音识别的时候,DTW识别效果就会急剧下降,这时候使用隐马尔可夫模型(HMM)进行训练识别效果会有明显提升,由于在传统语音识别中一般采用连续的高斯混合模型(GMM:Gaussian Mixture Model)对状态输出密度函数进行刻画,因此又称为GMM-HMM构架。不过随着人工智能(尤其是深度学习)的发展,通过深度神经网络(DNN)来完成声学建模,形成所谓的DNN-HMM构架来取代传统的GMM-HMM构架,在语音识别上也取得了很好的效果。
1.4录制及播放音频
编写Python代码实现录制和播放音频,需要用到wave模块和PyAudio模块。
1.4.1wave模块
wave模块是Python标准库中的模块,它提供了一个处理WAV声音格式文件的接口,让用户可以读写、分析及创建WAV文件。它不支持压缩/解压,但是支持单声道/立体声。
如果希望打开一个WAV文件,可以使用wave模块中的函数
wave.open(file, mode = None)
第一个参数file是一个字符串,表示要打开的WAV文件的路径以及文件名。
第二个参数mode表示文件的读写模式,如果是rb表示只读模式,返回一个Wave_read对象,如果是wb表示只写模式,返回一个Wave_write对象。
说明
打开WAV文件是不支持同时读写的。
对于Wave_read对象来说,其包含以下方法:
(1)Wave_read.close(),关闭打开的数据流并使对象不可用。当对象销毁时会自动调用。
(2)Wave_read.getnchannels(),返回声道数,1为单声道,2为立体声。
(3)Wave_read.getsampwidth(),返回采样字节长度。
(4)Wave_read.getframerate(),返回采样频率。
(5)Wave_read.getnframes(),返回音频总帧数。
展开