声纹识别项目说明¶
项目概述¶
该项目基于PaddlePaddle框架实现了高效的声纹识别系统,支持声纹注册、识别和对比功能。通过ECAPA-TDNN模型提取声纹特征,使用余弦相似度计算特征相似度,从而实现说话人识别。
模型架构¶
- 骨干网络:ECAPA-TDNN(增强通道注意力、传播和聚合的TDNN)
- 特征提取:通过AttentiveStatisticsPooling(ASP)池化层生成192维特征向量
- 损失函数:AAMLoss(加性角度间隔损失)+ 余弦相似度对比
安装依赖¶
# 创建虚拟环境
conda create -n voice_recognition python=3.8
conda activate voice_recognition
# 安装PaddlePaddle
pip install paddlepaddle-gpu==2.4.2.post102 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html
# 安装其他依赖
pip install soundfile librosa matplotlib visualdl pyaudio paddleaudio
数据准备¶
- 创建
dataset目录,结构如下:
dataset/
├── train_list.txt # 训练数据列表
├── test_list.txt # 测试数据列表
├── enroll_list.txt # 注册数据列表
└── noise/ # 噪声数据
- 数据格式示例(
train_list.txt):
/path/to/audio1.wav speaker1
/path/to/audio2.wav speaker1
/path/to/audio3.wav speaker2
训练模型¶
# 单卡训练
python train.py
# 多卡训练
python -m paddle.distributed.launch --gpus '0,1' train.py
训练参数说明¶
- 配置文件:
configs/ecapa_tdnn.yml - 关键参数:
model_conf:模型参数(嵌入维度、池化方式等)loss_conf:损失函数参数(角度间隔、缩放因子等)optimizer_conf:优化器参数(学习率、衰减策略等)
模型评估¶
python eval.py
评估指标¶
- EER(等错误率):模型区分说话人和非说话人的能力
- MinDCF(最小检测成本函数):综合考虑误报和漏报成本
声纹对比¶
python infer_contrast.py --audio_path1=audio/a_1.wav --audio_path2=audio/b_2.wav
核心功能¶
- 计算两个音频文件的特征相似度
- 通过阈值判断是否为同一说话人
- 支持命令行和GUI界面两种操作模式
声纹识别¶
python infer_recognition.py
核心功能¶
- 注册:将音频录入声纹库并保存特征
- 识别:将测试音频与声纹库比对并返回结果
- 管理:支持用户增删和语音实时识别
关键代码解析¶
特征提取¶
def extract_feature(wav_path, sample_rate=16000):
"""音频特征提取函数"""
audio, _ = librosa.load(wav_path, sr=sample_rate)
# 预处理
if len(audio) < sample_rate:
audio = np.pad(audio, (0, sample_rate - len(audio)), mode='constant')
# 特征提取
stft = librosa.stft(audio, n_fft=512, hop_length=160, win_length=400)
spec = np.abs(stft)
mel_basis = librosa.filters.mel(sr=sample_rate, n_fft=512, n_mels=80)
mel_spec = np.dot(mel_basis, spec)
log_mel_spec = np.log(mel_spec + 1e-6)
return log_mel_spec.T # 返回特征矩阵
模型前向计算¶
def forward(self, x):
"""模型前向传播"""
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
for block in self.blocks:
x = block(x)
x = self.avg_pool(x)
x = self.fc(x)
x = self.tanh(x)
return x
相似度计算¶
def similarity_score(feat1, feat2):
"""计算特征相似度"""
feat1 = feat1.flatten()
feat2 = feat2.flatten()
norm1 = np.linalg.norm(feat1)
norm2 = np.linalg.norm(feat2)
if norm1 == 0 or norm2 == 0:
return 0.0
return np.dot(feat1, feat2) / (norm1 * norm2)
模型推理¶
声纹注册¶
def register_audio_to_db(audio_path, user_name):
"""将音频注册到声纹库"""
feature = extract_feature(audio_path)
feature = feature.reshape(1, 80, 32) # 调整维度适配模型输入
# 模型推理
with paddle.no_grad():
feat = model(feature)
# 保存特征到数据库
if not os.path.exists("audio_db"):
os.makedirs("audio_db")
save_path = f"audio_db/{user_name}.npy"
np.save(save_path, feat.numpy())
print(f"已注册用户:{user_name}")
声纹识别¶
def recognize_speaker(audio_path):
"""识别说话人"""
feature = extract_feature(audio_path)
feature = feature.reshape(1, 80, 32)
with paddle.no_grad():
query_feat = model(feature)
max_score = 0.0
best_user = "unknown"
# 遍历声纹库
for user in os.listdir("audio_db"):
if user.endswith(".npy"):
db_feat = np.load(f"audio_db/{user}")
score = similarity_score(query_feat.numpy(), db_feat)
if score > max_score:
max_score = score
best_user = user[:-4]
return best_user, max_score
性能指标¶
- 训练集:准确率 > 95%
- 测试集:EER < 5%
- 模型大小:~8MB
- 推理速度:单音频 < 100ms
可视化监控¶
visualdl --logdir=log --host=0.0.0.0
扩展功能¶
- 实时声纹识别:修改
infer_recognition_gui.py支持实时录音 - API服务:使用Flask/FastAPI封装识别接口
- 多模态融合:结合文本、图像特征提升识别鲁棒性
项目特点¶
- 高性能:ECAPA-TDNN模型实现高精度特征提取
- 易部署:支持CPU/GPU多平台部署
- 可扩展:支持多种模型和数据集
参考资料¶
通过以上步骤,您可以快速搭建一个完整的声纹识别系统,实现从数据准备、模型训练到最终应用的全流程。如需进一步优化,可尝试调整模型参数、增加数据增强或使用预训练模型进行迁移学习。