3. 数据采集避坑
数据增强,说白了就是给训练数据「化妆」。你想想看,真实场景下的唤醒词,哪有实验室里那么干净?
我刚开始做唤醒词的时候,模型在测试集上跑得挺好,一上真机就崩。后来才发现,问题就出在数据太「素」了。模型没见过带噪的、混响的、变调的语音,它当然不会处理。
这一章,我把常用的增强手段掰开揉碎讲清楚。最后会给出我自己的增强流水线,你直接拿去用就行。
3.1 加噪:最基础也最有效
加噪是数据增强的「基本功」。它的逻辑很简单:把干净的唤醒词语音,叠加上各种背景噪声。
噪声从哪里来?我一般用这几个公开数据集:
- MUSAN:包含音乐、语音、噪声三类,质量不错。
- CHiME:真实场景噪声,比如公交车、咖啡馆、街道。
- NoiseX-92:经典噪声库,虽然老了点,但够用。
加噪时,信噪比(SNR)是关键参数。SNR 越低,噪声越大,训练难度越高。
| 场景 | 推荐 SNR 范围 (dB) | 说明 |
|---|---|---|
| 安静室内 | 15 ~ 25 | 模拟办公室、卧室 |
| 嘈杂街道 | 5 ~ 15 | 模拟户外、商场 |
| 极端噪声 | 0 ~ 5 | 模拟工厂、地铁 |
3.2 混响:让声音「有空间感」
混响模拟的是声音在房间墙壁上反射的效果。没有混响的语音听起来像「贴着脸说」,有混响才像真实环境。
混响的核心是房间冲激响应(RIR)。你可以用实测的 RIR,也可以用工具生成。
我常用的工具:
- pyroomacoustics:Python 库,可以模拟任意形状的房间。
- RIR Generator:MATLAB 工具,生成速度快。
混响参数里,RT60(混响时间)最重要。RT60 越大,声音越「空灵」。
| 房间类型 | RT60 范围 (秒) | 示例 |
|---|---|---|
| 小房间 | 0.2 ~ 0.4 | 卫生间、电梯 |
| 中等房间 | 0.4 ~ 0.8 | 客厅、办公室 |
| 大房间 | 0.8 ~ 1.5 | 会议室、大厅 |
3.3 变速与音高偏移:对抗语速和语调差异
不同的人说话,语速和音调都不一样。模型如果没见过变速和变调,遇到说话快或声音尖的用户,就容易翻车。
变速:改变语速,但不改变音高。
- 速度因子 0.8:语速变慢,适合模拟老年人。
- 速度因子 1.2:语速变快,适合模拟急性子。
音高偏移:改变音高,但不改变语速。
- 偏移 +3 semitones:声音变尖,模拟儿童或女性。
- 偏移 -3 semitones:声音变粗,模拟男性或低沉嗓音。
实现上,我推荐 librosa 或 sox。librosa 的 time_stretch 和 pitch_shift 函数,一行代码搞定。
import librosa
# 变速:速度变为原来的 1.2 倍
y_fast = librosa.effects.time_stretch(y, rate=1.2)
# 音高偏移:升高 3 个半音
y_high = librosa.effects.pitch_shift(y, sr=sr, n_steps=3)
3.4 SpecAugment:频域增强的「黑科技」
SpecAugment 是 Google 在 2019 年提出的方法。它不操作原始波形,而是直接对频谱图做「遮挡」。
具体有三种操作:
- 时间遮蔽:随机遮掉一段时间的频谱。
- 频率遮蔽:随机遮掉一段频率的频谱。
- 时间扭曲:在时间轴上做非线性拉伸。
为什么有效?因为模型被迫从「不完整」的频谱中学习特征,泛化能力自然更强。
我常用的参数:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 时间遮蔽宽度 | 10 ~ 20 | 帧数,对应约 0.1~0.2 秒 |
| 频率遮蔽宽度 | 8 ~ 16 | Mel 频带数 |
| 遮蔽次数 | 2 ~ 4 | 每个样本遮蔽 2~4 块 |
3.5 我常用的增强 Pipeline
好了,前面讲了各种增强手段。现在说说我怎么把它们串起来。
我的流水线分两步:离线增强和在线增强。
离线增强:一次性生成大量增强数据,存到磁盘。适合加噪和混响,因为计算量大。
在线增强:训练时实时做,不存盘。适合变速、音高偏移、SpecAugment,因为参数随机,每次都不一样。
下面是我常用的完整流程:
- 原始语音 → 16kHz 单声道,归一化到 -26 dBFS。
- 随机选择 RIR(RT60 0.2~1.0s),做卷积混响。
- 随机选择噪声(SNR 0~25 dB),叠加到混响后的语音上。
- 随机变速(速度因子 0.85~1.15)。
- 随机音高偏移(偏移 -3~+3 semitones)。
- 提取 FBank 特征(80 维 Mel 滤波器组)。
- 在线 SpecAugment(时间遮蔽 12 帧,频率遮蔽 10 个 Mel 频带)。
这个流水线,我用了两年多。效果稳定,模型在真实场景下的误唤醒率降低了 40% 以上。
下面这张图,是我这个 Pipeline 的完整流程:
嗯,这个 Pipeline 看起来步骤多,但实际跑起来很快。我一般在训练前,先把混响和加噪做完,存成 TFRecord 或 HDF5。训练时,从磁盘读数据,再做变速、音高偏移和 SpecAugment。
这样做的好处是:离线部分保证数据多样性,在线部分保证随机性。两者结合,模型见过的数据组合几乎是无限的。