MFCC算法的实现过程(原理篇)

前期的博客中,已经贴出了MFCC算法的C++代码实现。本篇文章,主要讲解该算法的数学原理。

声音是因为物体振动而产生的声波,是可以被人或动物的听觉器官所感知的波动现象。声音有多种特性,比如音色、音调、响度、频率。人耳是能够通过这些特征区分出声音的种类,那么如何让机器去区别不同种类的声音呢?研究者通常采用梅尔频率倒谱系数(Mel Frequency Cepstrum Coefficient, 简称:MFCC)作为声学特征,让机器学会辨别声音。

梅尔(Mel)频率是由研究人员跟据人耳听觉机理提出,它与赫兹(Hz)频率成非线性对应关系。MFCC则利用两者之间的非线性关系,计算得到Hz频谱特征。当前MFCC已经广泛应用于语音数据特征提取和降低运算维度。由于Hz频率与Mel频率之间存在非线性的对应关系,使得当频率提高时,MFCC的计算精度随之下降。通常情况下,在应用时仅使用低频MFCC,而舍弃中频和高频MFCC。

MFCC的计算包括预加重,分帧,加窗,快速傅里叶变换,梅尔滤波器组(梅尔频率转换),离散余弦变换(Discrete Cosine Transform,简称:DCT),动态特征等过程。其中最重要的步骤是快速傅里叶变换和梅尔滤波器组,它们对数据进行了主要的降维操作。下面,介绍一下MFCC算法的具体实现过程:

1)预加重。预加重是为了突出语音信号的高频特性,使信号的频谱变得平坦,并保持在低频到高频的整个频带中可以使用同样的信噪比求频谱。同时,预加重还可以消除发声过程中声带和嘴唇之间的效应,用以补偿发音系统对语音信号抑制的高频部分,也为了突出高频的共振峰。一般通过下面计算式实现预加重,s_m代表声音流中的第m个采样点:

2)分帧。将N个采样点集合成为一个观测单位,称之为帧,一般设置N=512。为了防止相邻两帧的变化太大,通常会使两个相邻的帧之间有一段重叠区域,我们实验的重叠区域包含了256个采样点。分帧之后,均以帧为单位进行特征处理。

3)加窗。相比于使用矩形窗函数,使用汉明窗平滑信号可以减弱快速傅里叶变换以后旁瓣大小以及频谱泄露(主瓣是变换为频谱之后振幅最大的那个波峰部分,而周围的小的波峰部分叫旁瓣),能取得更高质量的频谱(频谱表示频率与能量的关系)。s_{n}^'表示每帧中预加重的第n个采样点:

4)快速傅里叶变换。因为时域上的信号变换难以表现出信号的特性,所以一般将它转变成为频域上的能量分布来分析,不相同的能量分布,就意味着不相同语音的特性。因此在加窗后,每帧还需要经过快速傅里叶变换以获取在频谱上的能量分布。使用快速傅里叶变换对分帧加窗后的各帧信号求取频谱,并对得到的频谱取模方平均来获取其功率谱。K是傅里叶变换的长度,这里K=512;s_n^{''}(i)表示声音流第i帧加窗后的第n个采样点值;S_k(i)表示声音流第i帧的频谱的第k个值;P_k(i)表示声音流第i帧的功率谱的第k个值。

5)梅尔滤波器组。虽然得到了频谱和功率谱,但频域信号中存在较多冗余。因此,需要使用梅尔滤波器组来对频域的幅值进行精简,使用单个值来表示每一个频段。这里展示对每帧数据获取梅尔频率转换:①使用下式1将频率转换成梅尔频率,分别将高频sf/2(采样频率sf=12000)和低频300转换成梅尔高频maM和梅尔低频miM;②使用下式2计算每点的频率f_n(1<=n<=K/2),并使用式1将其转换成梅尔频率Mf_n;③在梅尔低频miM与梅尔高频maM区间内均匀取NF个点(NF=26为梅尔滤波器的个数),每个点记作fb_{nf}(1<=nf<=26);④则对于每个梅尔滤波器值可以使用下式4计算,其中mfb_{nf}是利用式3对fb_{nf}求得;⑤对每帧数据,得到一个26维的梅尔滤波值。

6)取对数。由于人耳对声音的感知并不是线性的,使用非线性方式更好描述。处理之后,才能进行倒谱分析。因此,对梅尔滤波得到的值取对数。

7)离散余弦变换。因为滤波器之间是存在重叠的,故而之前计算得到的能量值之间具有相关性。离散余弦变换可以对数据进行降维压缩和抽象,使获得的特征参数没有虚部,更便于计算。这里离散变换维度的维度取13,即1<=nc<=13。

8)动态特征。语音信号具有时域连续的特征,而以帧为单位提取的特征信息仅仅体现了当前帧语音的特性。为了使特征信息能够反应出语音信号的时域连续性,一般会给特征维度增加前后帧信息的维度,常见的是一阶差分和二阶差分。下式展示了一阶差分的计算过程,其中d_t表示对第t帧增加的一阶差分值,c_{t+st}表示离散余弦变换后第t+st帧的特征,c_{t+st}=[D_{1}(t+st),...,D_{i}(t+st),...,D_{13}(t+st)],常用的ST=1或2。计算二阶差分时,c_{t+st}表示第t+st帧一阶差分的结果。增加一阶差分和二阶差分后的每帧特征是39维。