声纹特征提取基础:MFCC、Fbank与Delta系数
特征提取,说白了就是把声音信号变成机器能懂的数学表达。我刚开始做声纹识别时,总觉得这步就是调个库的事。后来踩了不少坑才明白——特征提取得好不好,直接决定了整个系统的天花板。
这一章,我们重点聊三个东西:MFCC、Fbank,还有Delta系数。它们是什么?怎么算?为什么重要?我会结合项目经验,把原理和实战都说透。
从声音到特征:我们到底在提取什么?
原始语音信号是一维的波形,信息密度低,冗余多。直接拿它做识别,效果很差。我们需要把它转换成更紧凑、更具区分性的表示。
人耳对声音的感知是非线性的——对低频变化敏感,对高频变化迟钝。所以,特征提取的核心思路就是模拟人耳的听觉特性,把线性频率映射到Mel频率上。
核心思想:特征提取 = 模拟人耳听觉 + 降维去冗余 + 保留说话人个性信息
我个人习惯把特征提取流程分成四步:预加重→分帧加窗→FFT→Mel滤波。下面这张图可以帮你建立整体认知。
MFCC:最经典的声纹特征
MFCC(Mel频率倒谱系数)是声纹识别领域使用最广泛的特征。它为什么这么能打?我们一步步拆解。
预加重:别让高频信息被淹没
语音信号的能量主要集中在低频段,高频部分衰减很快。如果不做处理,高频细节会被低频淹没。预加重就是一个简单的高通滤波器:
y[n] = x[n] - α * x[n-1]
α通常取0.97。我在项目中试过不同的α值,发现0.95~0.98之间差异不大,但低于0.9时高频信息明显丢失。嗯,这个值别乱改。
分帧加窗:把非平稳信号切成平稳片段
语音信号是非平稳的,但在极短时间(10~30ms)内可以看作平稳。所以我们把它切成帧,每帧25ms,帧移10ms。这样相邻帧之间有重叠,信息不会断。
加窗是为了避免FFT时的频谱泄漏。汉明窗是最常用的选择:
w[n] = 0.54 - 0.46 * cos(2πn / (N-1))
我的经验:帧长25ms、帧移10ms是黄金参数。帧长太短(<10ms)频率分辨率不够;太长(>50ms)平稳性假设不成立。我曾经在噪声环境下试过40ms帧长,效果反而变差。
FFT与Mel滤波:模拟人耳的关键一步
对每一帧做FFT,得到频谱。然后通过Mel滤波器组,把线性频率映射到Mel刻度上。
Mel频率的转换公式:
Mel(f) = 2595 * log10(1 + f / 700)
滤波器组通常用20~40个三角滤波器,覆盖整个频率范围。每个滤波器的输出就是该频段的能量。
对数运算与DCT:压缩与去相关
对滤波器组输出取对数,压缩动态范围。然后做DCT(离散余弦变换),去除特征间的相关性。
DCT之后得到的就是MFCC系数。通常取前12~13维,加上帧能量,构成13维特征向量。
为什么DCT很重要? 滤波器组输出的相邻频段能量高度相关。DCT能把这些冗余去掉,让特征更紧凑。我见过有人跳过DCT直接用Fbank,在特定任务上效果也不错,但模型需要更大的容量去学习相关性。
Fbank vs MFCC:怎么选?
Fbank(滤波器组特征)和MFCC的区别,就在DCT这一步。Fbank不做DCT,保留了完整的能量分布信息。
| 对比维度 | Fbank | MFCC |
|---|---|---|
| 特征维度 | 40~80维 | 13~20维 |
| 特征相关性 | 高(相邻频段相关) | 低(DCT去相关) |
| 信息保留 | 完整能量分布 | 压缩后丢失部分细节 |
| 适用模型 | DNN/CNN(能学习相关性) | GMM/HMM(需要独立特征) |
| 噪声鲁棒性 | 中等 | 较好(DCT有去噪效果) |
我个人习惯:用深度学习模型时,优先选Fbank。因为DNN能自动学习特征间的相关性,保留更多信息反而有利。用传统GMM-UBM系统时,MFCC是更稳妥的选择。
避坑提醒:我曾经在一个项目里直接用MFCC喂给CNN,效果一直上不去。后来换成Fbank,准确率直接提升了3%。原因就是CNN的卷积核本来就能捕捉局部相关性,DCT反而把有用的结构信息破坏了。
Delta系数:让特征动起来
静态MFCC只描述当前帧的信息。但说话人的个性特征,往往体现在音调、音色的变化过程中。Delta系数就是用来捕捉这种动态变化的。
一阶Delta:帧间变化率
一阶Delta计算当前帧与前后帧的差分,反映特征的变化趋势:
Δ(t) = (c(t+1) - c(t-1)) / 2
更通用的公式会考虑多帧窗口:
Δ(t) = Σ(θ * (c(t+θ) - c(t-θ))) / (2 * Σ(θ²))
θ是窗口大小,通常取2。窗口越大,平滑效果越强,但会丢失快速变化的细节。
二阶Delta:变化率的变化率
二阶Delta(Delta-Delta)在一阶Delta的基础上再做一次差分,捕捉加速度信息:
Δ²(t) = (Δ(t+1) - Δ(t-1)) / 2
最终的特征向量 = 静态MFCC + 一阶Delta + 二阶Delta。如果静态是13维,加上Delta后就是39维。
我的建议:Delta系数不是越多越好。一阶Delta基本是必加的,能提升5~10%的识别率。二阶Delta在干净语音上有帮助,但在噪声环境下增益有限。我一般先加一阶,看效果再决定是否加二阶。
实战中的参数选择
参数怎么设?我整理了一份常用配置表,你可以直接参考:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 采样率 | 16kHz | 声纹识别标准采样率 |
| 帧长 | 25ms | 400个采样点(16kHz) |
| 帧移 | 10ms | 160个采样点 |
| FFT点数 | 512或1024 | 2的幂,方便计算 |
| Mel滤波器数 | 40 | Fbank常用40维 |
| MFCC维数 | 13 | 不含能量维 |
| Delta窗口 | 2 | 一阶和二阶通用 |
一句话总结:MFCC是经典选择,Fbank更适合深度学习,Delta系数捕捉动态信息。三者结合使用,才能构建出高质量的声纹特征。