声纹识别技术原理:从声音到身份
声纹识别,说白了就是让机器学会「听声辨人」。跟人脸识别、指纹识别一样,它也是一种生物特征识别技术。但声纹有个独特优势——你不需要靠近传感器,只要说话就行。这在远程身份认证场景下特别实用。
不过,声纹识别也有它的难点。人的声音会随年龄、情绪、健康状况变化,甚至你今天感冒了,声音都可能跟昨天不一样。我刚开始做这个方向时,就被这些「变数」折腾得不轻。
这一章,我们来拆解声纹识别的核心技术链路。从原始音频到最终的身份判决,中间经历了三个关键阶段:特征提取 → 声纹建模 → 比对决策。下面这张图可以帮你建立整体认知。
2.1 声纹特征提取:MFCC 与 PLP
原始音频信号里,信息太杂了。有说话内容、有环境噪声、有信道干扰,还有说话人本身的个性特征。特征提取要做的,就是「去粗取精」——把跟说话人身份相关的信息保留下来,把无关的扔掉。
目前最主流的两种特征,就是 MFCC(梅尔频率倒谱系数)和 PLP(感知线性预测系数)。
MFCC:声纹特征的「老黄牛」
MFCC 的历史可以追溯到 80 年代,但直到今天,它仍然是声纹识别领域最常用的特征之一。为什么?因为它模拟了人耳的听觉特性。
人耳对不同频率的声音敏感度不一样。低频段我们分辨得很细,高频段则比较粗糙。MFCC 通过梅尔滤波器组,把线性频率映射到梅尔刻度上,正好模拟了这个特性。
提取 MFCC 的流程大致如下:
- 预加重:提升高频分量,补偿语音信号的高频衰减
- 分帧加窗:把音频切成 20-30ms 的短帧,每帧加汉明窗
- FFT:把时域信号变换到频域
- 梅尔滤波器组:用三角滤波器对频谱加权,得到梅尔频谱
- 取对数:模拟人耳对音量的对数感知
- DCT:离散余弦变换,去相关并降维
最终得到的就是 MFCC 系数。通常取 13 维或 20 维,再加上一阶差分和二阶差分,构成 39 维或 60 维的特征向量。
PLP:更「拟人」的特征
PLP 是另一种经典特征。跟 MFCC 不同,PLP 更强调模拟人耳的听觉感知,它引入了等响度曲线和强度-响度幂律。
PLP 的提取流程跟 MFCC 有相似之处,但多了几个步骤:
- 频谱分析后,先做临界带分析(Bark 尺度)
- 然后做等响度预加重,模拟人耳对不同频率的敏感度差异
- 再做强度-响度变换(取 0.33 次幂)
- 最后用线性预测(LPC)代替 DCT,得到倒谱系数
PLP 在噪声环境下通常比 MFCC 更鲁棒。但它的计算量也更大。我在一个车载项目里对比过,PLP 在 60dB 以上的安静环境跟 MFCC 差不多,但到了 45dB 以下的嘈杂环境,PLP 的识别率能高出 5-8 个百分点。
MFCC vs PLP 对比
| 对比维度 | MFCC | PLP |
|---|---|---|
| 听觉模型 | 梅尔刻度 | Bark 刻度 + 等响度曲线 |
| 计算复杂度 | 较低 | 较高(多 LPC 步骤) |
| 噪声鲁棒性 | 一般 | 较好 |
| 嵌入式适用性 | 推荐 | 算力充足时可选 |
2.2 声纹建模方法:从 GMM 到 x-vector
特征提取完了,我们得到的是每帧一个特征向量。但一段语音可能有几百帧,你不能拿几百个向量去跟别人比对。所以需要建模——把这些帧级别的特征,压缩成一个固定维度的「声纹模型」或「声纹向量」。
建模方法经历了三代演变:GMM-UBM → i-vector → x-vector。每一代都在精度、鲁棒性和计算效率上做了改进。
GMM-UBM:经典的概率模型
GMM-UBM 是声纹识别的「老前辈」。它的思路很直观:每个人的声音特征分布,可以用多个高斯分布的组合来拟合。
具体做法是:
- 先拿大量说话人的数据,训练一个通用背景模型(UBM),代表「平均人」的声音分布
- 然后对每个目标说话人,用他的少量语音数据,从 UBM 出发做自适应(MAP 自适应),得到该说话人的 GMM
- 比对时,计算待测语音在目标 GMM 和 UBM 下的似然比
GMM-UBM 的优点是原理简单、训练快。但缺点也很明显:它假设各帧独立,忽略了语音的时序信息。而且模型大小跟说话人数量成正比,注册 1000 个人就要存 1000 个 GMM,在嵌入式设备上不太现实。
i-vector:把声纹压缩成「向量」
i-vector 是 GMM-UBM 的进化版。它不再为每个说话人存一个 GMM,而是把所有说话人的差异映射到一个低维空间里,用一个固定维度的向量来表示。
这个向量就叫 i-vector(身份向量)。它的核心思想是:
- 用 UBM 的均值超向量作为基础
- 通过总变化子空间(Total Variability Space)建模,把说话人差异和信道差异都压缩进去
- 最终得到一个 400-600 维的向量
i-vector 的好处是:向量维度固定,比对时只需要计算余弦距离或 PLDA 打分,速度快。而且它比 GMM-UBM 更鲁棒,对短语音(3-5 秒)也有不错的效果。
我个人的习惯是,在嵌入式平台上优先考虑 i-vector。400 维的向量,用余弦距离比对,一次计算只需要几十微秒,非常适合实时场景。
x-vector:深度学习时代的选择
x-vector 是近年来最火的声纹建模方法。它用深度神经网络(DNN)来提取声纹向量。
网络结构大致是这样的:
- 输入是帧级别的 MFCC 特征
- 前面几层是时延神经网络(TDNN),捕捉帧间的时序依赖
- 中间有一个统计池化层,把帧级别的特征聚合成段级别的均值和标准差
- 最后通过全连接层,输出一个固定维度的 embedding(即 x-vector)
x-vector 的精度通常比 i-vector 高 10-20%,尤其是在复杂噪声环境下。但代价是计算量大,需要 GPU 训练,推理时也需要一定的算力。
三种建模方法对比
| 方法 | 向量维度 | 精度 | 计算量 | 短语音表现 | 嵌入式适用性 |
|---|---|---|---|---|---|
| GMM-UBM | 不固定(模型大小) | 中等 | 低 | 差(需≥5秒) | 一般 |
| i-vector | 400-600 | 良好 | 中 | 可接受(3秒) | 推荐 |
| x-vector | 128-512 | 优秀 | 高 | 好(1-2秒) | 需算力支持 |
2.3 声纹比对与决策
模型建好了,最后一步就是比对和决策。这一步看起来简单,但坑也不少。
比对的核心是计算相似度。常用的方法有:
- 余弦距离:计算两个向量的夹角余弦,值越接近 1 越相似。简单高效,i-vector 常用
- PLDA:概率线性判别分析,建模说话人内和说话人间的分布,精度更高但计算量也大
- 欧氏距离:简单粗暴,但效果一般,很少单独用
决策就是拿相似度跟阈值比较。大于阈值判为同一人,小于则判为不同人。
阈值怎么定?这取决于你的应用场景:
- 安全场景(如支付、门禁):阈值设高一点,宁可拒真(FRR)也不要认假(FAR)
- 便利场景(如智能音箱唤醒):阈值设低一点,宁可误唤醒也不要叫不醒
我一般会在开发阶段先收集一批测试数据,画出DET 曲线(检测错误权衡曲线),然后根据业务需求选一个等错误率(EER)附近的阈值。嗯,这里要注意:EER 只是参考,实际部署时一定要根据真实场景微调。