上一章提到了整个发声与拾音及存储的原理。但是在了解ASR的过程中,发现基本上遇到的资料都避不开MFCC特征。
整个ASR的处理流程大致可以分为下图:
左侧是经典的处理流程,右侧是近期流行的流程。发生的变化是,将语言模型以下的部分变成端到端的了。 我们将语言模型以下的部分统一看成是声学模型就好。
而MFCC主要用在左侧的处理流程中,即“特征处理”的输出结果。 虽然可以看成,端到端的声学模型出来后,我们已经不需要MFCC了,直接输入音频即可。 不过这并不意味着MFCC就没用了。 在“根据发音确认发音人身份”等许多领域,MFCC还是个很短平快切粗暴有效的特征。 由于MFCC的重要性,和asr相关专业的人士交流时,最好是能提前具备此共识。
MFCC 细节介绍:
MFCC给人的感觉像是孟德尔遗传定律。在人们还并不确定人耳是如何解析声音的时候,假设了这是一个傅里叶变换后的频域处理过程。然后,最近的医学研究成果表明,人耳也确实大致是这么工作的,对应的器官名字叫耳蜗,或蜗牛。
MFCC虽然名字就4个字母,但其实是集成了很多很多的思考和假设在里面。 了解过之后,你就不会再后悔大学数学的卷积操作毛用都没有了。 可谓是人类智慧的一大结晶。
一:整体流程
MFCC整体流程看其来好像有些复杂,但其实拆细了之后,会发现这个很符合常识的。
上图便是MFCC的主要流程。这里稍微提到一点,Cepstral 是 spectral的字母倒序,后者是频谱的意思,前者是倒谱的意思,就是把频谱倒回来。。。 这个定义确实有些冷。
图中的DFT和IDFT便是堪称深刻影响到了人类技术进程的经典技术——离散傅里叶变换及离散傅里叶逆变换。 这里就当成是傅里叶正逆变换就好。离散主要是因为处理的数据是离散的一个个数值,而不是坐标轴上那种可以无限往下细分的点。
整个处理流程从左上角开始看。 输入是第一章讲到的pcm文件,可以理解成一个数组,数值的大小表示声音的强弱。 至于频率等信息,是固定值,设定一下就好。
1、pre-emphasis
这个加强里掺杂着各种各样的“窗”or过滤器之类字眼的术语,其实原理挺简单的,那些个“窗”主要是信号处理领域的术语,大意就是对部分频率段的数据增强幅度。由于是已知的频率操作,可以根据公式事前转换为时域的操作(就是直接对pcm数据的操作)
2、滑动窗口
这里要交代的一个背景信息是,傅里叶变换针对的是一个时间片段的值,或者说,是一个数组,而非一个数组中的某个值。所以在提取特征的时候,首先要假设基本的发音单元所占用的时间,然后把这个时间片段的数据拿过来,做傅里叶变换。 但是怎么知道某段声音是从什么时候开始的呢? ——就是不知道的,这里采用滑动窗口就好了,差个1、2ms不影响分析的。
整个提取流程,起初是使用了滑动窗口,术语上管这个窗口叫frame。 一个frame的长度一般在20-25ms,然后窗口的移动步长在10ms左右。这也是上图最左侧所展示的内容。 这里的假设是,声音的最基本发音单元,至少需要20ms左右的发音时长。
得到关于frame的数组之后,接下来要为每个数组做一下离散傅里叶变换。 示意过程如下图:
这一步操作的依据或者说灵感主要来自上图左上角,就是大家发现,提取了一个个frame后,做下DFT,然后把各个frame对应的DFT数据放到一块(左上图中,纵轴是频域的横坐标-评率,频率,横轴是时间,每个横坐标上的点对应着一个frame,颜色的深浅代表对应频率下的幅度。傅里叶变化的本质就是拿一堆的正弦函数求和去拟合原始数据。这些sin cosin 函数,区别只在于 周期和幅度)。 把这些DFT之后的frame放到一块之后,就能明显的发现:音节在频域上确实有些区分度的。 左上图的蓝线表示那一段时间内,都是某个频率下的幅度特别大,这个给了个术语,叫做——共振峰。左上图的红线用来区分音节的边界。
有了灵感之后,滑动窗口+DFT(或者FFT 表示傅里叶变化)之后,输出就类似上图右边的效果—— 把一个关于frame的数组,转换成了关于这个frame的傅里叶变换后结果的数组。数组中,每个元素表示这个频率值下的幅度。
3、梅尔滤波
工序2已经把数据变成了关于frameDFT之后的数组。既然已经都变成了频域后的数据,接下来要做的,很直观的——就是把人耳敏感的频率下的数据加强,人耳不敏感的频率下的数据减弱。充分的模拟人耳。
梅尔发现,人耳对各个频域段的声音的敏感程度不同,对高频的敏感度较低,所以,梅尔就做了映射方法, 低频区给与较多的区分度,高频区给与较少的数据表示。所以,他的工作可以理解是定义了一个map或者说函数, 如上图右上角。这函数的横轴和前面的DFT结果的长度一一对应,然后对每个DFT的结果中的每个元素,乘以对应纵轴上的数值。输出的结果如上图右下角。说白了,就是每次拿右上角图中的一部分乘以DFT之后的数据,得到一个值。 最终把DFT变成一系列Y的数组。
4、提取声道信息/倒谱
上图左展示的是人的发声过程——气体从胸腔发出(基音),经过声道和口腔的改造,最终形成声音。 而气体经过声道改造的过程,恰恰就是数学中的卷积运算过程。 这里特别像软件开发中归纳的思想,卷积是一个抽象出来的操作。很多基信号+加工信号构成新信号的操作基本都适用。
前面讲到,根据共振峰的位置,大致就能区分出音节or音素出来。而共振峰主要是Filter or 声道及口腔带来的信息。所以根据抓主干的哲学指导,想让特征更鲜明,需要提取Filter部分的信息。
既然Filter与基音是卷积操作,那么接下来就是一系列的数学推导骚操作,这里面依据了一个公式,那就是:时域的卷积 = 频域的乘积。 而乘积运算左右加log就变成了加法运算。然后就得到了如上图右下角的效果。然后就发现,取了log后,再对信号做一下傅里叶变换,就能得到右下图中左侧的效果,感觉在新的频域里把属于基音的频率去掉就好了。
这样一下子就简单了。就是取了log后再搞一次傅里叶变换。 但这里实际操作时,由于我们原来已经搞成 DFT结果的数组,针对这部分数据再搞一次傅里叶变换,数学上等同于再做一次傅里叶逆变换。。。 大繁至简的感觉。。所以就看到了处理流程中的IDFT了(离散傅里叶逆变换)。
5、提取变化信息delta
delta信息相对于上面的处理就好理解多了。 大家可以回一下导数是怎么求的——后一时刻的值 减去 前一时刻的值 然后,除以时间间隔。 那么到了离散领域, 一阶导数就是一阶delta。 他就是我们上面求的的数组中的每个元素(注意我们上面数组中的每个值其实已经是个向量了),按位和相邻的最近的一个元素相减。
然后,二阶导就是上面求得的一阶导数,再做一次和最近的元素相减的操作。 然后把这两部得到的结果加入进去就完事了。 很简单
6、Finish
经过以上的几部,MFCC最终输出结果为: 一个数组,数组的每个元素是一个39维的向量。
以上便是本章的内容