4. 音频采集与质量评估
MFCC,全称梅尔频率倒谱系数。说白了,就是把声音信号变成一组数字,让机器能听懂。我做了这么多年语音识别,可以负责任地告诉你:MFCC 提取的质量,直接决定了识别系统的天花板。前端特征没做好,后端模型再强也白搭。
这一节,我们从头拆解 MFCC 的每个环节。我会把我在项目中踩过的坑、积累的经验,都揉进去。
4.1 梅尔滤波器组设计:把频率掰弯
人耳对频率的感知不是线性的。低频区,我们分辨得很细;高频区,反而很粗糙。梅尔刻度就是模拟这种非线性。
公式很简单:
Mel(f) = 2595 * log10(1 + f / 700)
滤波器组的设计,核心就是在这条弯弯的梅尔刻度上,等间距地放一堆三角滤波器。每个滤波器覆盖一小段频率范围,重叠一半。
我个人习惯用 40 个滤波器。为什么是 40?
- 太少(比如 20):高频细节丢失,识别带噪语音时容易出错。
- 太多(比如 80):计算量上去了,但收益微乎其微。我在车载项目里试过 80 个滤波器,识别率只提升了 0.3%,延迟却涨了 15%。
滤波器组的频率范围也要注意。默认一般是 0-8kHz(采样率 16kHz)。但如果你做的是窄带电话语音,上限只有 4kHz,滤波器组就得跟着缩。
4.2 DCT变换:去相关,降维
滤波器组输出的能量,相邻滤波器之间高度相关。直接拿去做识别,特征冗余大,模型学起来费劲。DCT(离散余弦变换)就是来解决这个问题的。
DCT 把能量从频域变换到倒谱域。变换后,低阶系数代表频谱的包络(音色),高阶系数代表细节(噪声)。
我们通常只保留前 12-13 个系数。为什么?
- 前 1-2 阶:包含太多信道信息(比如麦克风差异),一般直接丢掉。
- 3-13 阶:语音的声学特征精华,全在这。
- 14 阶以后:基本都是噪声和细微扰动,留着反而干扰分类器。
// DCT 系数选择示例(Python 伪代码)
mfcc = dct(log_mel_energies, type=2, axis=1, norm='ortho')
mfcc = mfcc[:, 1:13] # 丢掉第0阶,保留1-12阶
4.3 动态特征(Δ、ΔΔ):让特征动起来
静态 MFCC 只描述当前帧的频谱形状。但语音是连续的,前后帧的变化信息同样重要。Δ(一阶差分)和 ΔΔ(二阶差分)就是用来捕捉这种动态变化的。
Δ 的计算很简单:当前帧减去前一帧。ΔΔ 就是 Δ 的 Δ。
Δ(t) = MFCC(t+1) - MFCC(t-1)
ΔΔ(t) = Δ(t+1) - Δ(t-1)
加上动态特征后,特征维度会变成原来的 3 倍。比如 13 维静态 MFCC,加上 Δ 和 ΔΔ,变成 39 维。
我建议:
- 静态 + Δ + ΔΔ:标准配置,适用于大多数场景。
- 只加 Δ:算力受限时(比如嵌入式设备),可以只加 Δ,牺牲一点精度换速度。
- 不加动态特征:除非你用的是 Transformer 这类自带时序建模能力的模型,否则别省。
4.4 MFCC参数调优经验
调参是门手艺活。下面这张表是我多年积累的推荐配置,你可以直接拿去用:
| 参数 | 推荐值 | 调优方向 |
|---|---|---|
| 采样率 | 16kHz | 语音识别标准,8kHz 用于电话 |
| 帧长 | 25ms | 短(20ms)适合快速语音,长(30ms)适合平稳语音 |
| 帧移 | 10ms | 固定值,一般不调 |
| FFT点数 | 512 | 16kHz 采样率下够用,更高采样率用 1024 |
| 滤波器数量 | 40 | 干净环境 26,噪声环境 48 |
| MFCC系数 | 13(去掉第0阶) | 保留 12-13 阶,不要超过 20 |
| 动态特征 | Δ + ΔΔ | 算力受限只加 Δ |
| 窗函数 | 汉明窗 | 汉宁窗也行,差别不大 |
调优时,我一般遵循这个顺序:
- 先定采样率和帧长:这是基础,后面所有参数都依赖它。
- 再调滤波器数量:根据噪声水平决定。
- 最后调 MFCC 系数个数:用验证集跑一遍,看哪个维度组合效果最好。
4.5 MFCC提取全流程
下面这张图,把整个 MFCC 提取流程串起来了。你可以把它贴在工位上,每次调参时对照着看。
流程走完,你得到的就是一组 39 维的特征向量(13 静态 + 13 Δ + 13 ΔΔ)。每一帧语音,对应一个 39 维的向量。把这些向量按时间顺序排好,就是模型的输入了。