基于PaddlePaddle实现的EcapaTdnn声纹识别模型
前言
本项目使用了EcapaTdnn模型实现的声纹识别,不排除以后会支持更多模型,同时本项目也支持了多种数据预处理方法,损失函数参考了人脸识别项目的做法PaddlePaddle-MobileFaceNets ,使用了ArcFace Loss,ArcFace loss:Additive Angular Margin Loss(加性角度间隔损失函数),对特征向量和权重归一化,对θ加上角度间隔m,角度间隔比余弦间隔在对角度的影响更加直接。
源码地址:VoiceprintRecognition-PaddlePaddle(V1)
使用环境:
- Python 3.7
- PaddlePaddle 2.2.2
模型下载
模型 | 预处理方法 | 数据集 | 类别数量 | 分类准确率 | 两两对比准确率 | 模型下载地址 |
---|---|---|---|---|---|---|
EcapaTdnn | melspectrogram | 中文语音语料数据集 | 3242 | 0.9608 | 0.99980 | 点击下载 |
EcapaTdnn | spectrogram | 中文语音语料数据集 | 3242 | 0.9617 | 0.99980 | 点击下载 |
EcapaTdnn | melspectrogram | 更大的数据集 | 6355 | 0.9109 | 0.99990 | 点击下载 |
EcapaTdnn | spectrogram | 更大的数据集 | 6355 | 0.9105 | 0.99990 | 点击下载 |
EcapaTdnn | melspectrogram | 超大的数据集 | 13718 | 0.9337 | 0.99995 | 点击下载 |
EcapaTdnn | spectrogram | 超大的数据集 | 13718 | 0.9326 | 0.99995 | 点击下载 |
安装环境
- 安装PaddlePaddle的GPU版本,如果已经安装过PaddlePaddle,测无需再次安装。
pip install paddlepaddle-gpu==2.2.2 -i https://mirrors.aliyun.com/pypi/simple/
- 安装其他依赖库,命令如下,注意librosa的版本是0.9.1,旧版本的梅尔频谱计算方式不一样。
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
注意: libsora和pyaudio安装出错解决办法
创建数据
本教程笔者使用的是中文语音语料数据集 ,这个数据集一共有3242个人的语音数据,有1130000+条语音数据,下载之前要全部解压数据集。如果读者有其他更好的数据集,可以混合在一起使用,但最好是要用python的工具模块aukit处理音频,降噪和去除静音。
首先是创建一个数据列表,数据列表的格式为<语音文件路径\t语音分类标签>
,创建这个列表主要是方便之后的读取,也是方便读取使用其他的语音数据集,语音分类标签是指说话人的唯一ID,不同的语音数据集,可以通过编写对应的生成数据列表的函数,把这些数据集都写在同一个数据列表中。
在create_data.py
写下以下代码,因为中文语音语料数据集 这个数据集是mp3格式的,作者发现这种格式读取速度很慢,所以笔者把全部的mp3格式的音频转换为wav格式,在创建数据列表之后,可能有些数据的是错误的,所以我们要检查一下,将错误的数据删除。执行下面程序完成数据准备。
python create_data.py
执行上面的程序之后,会生成以下的数据格式,如果要自定义数据,参考如下数据列表,前面是音频的相对路径,后面的是该音频对应的说话人的标签,就跟分类一样。
dataset/zhvoice/zhmagicdata/5_895/5_895_20170614203758.wav 3238
dataset/zhvoice/zhmagicdata/5_895/5_895_20170614214007.wav 3238
dataset/zhvoice/zhmagicdata/5_941/5_941_20170613151344.wav 3239
dataset/zhvoice/zhmagicdata/5_941/5_941_20170614221329.wav 3239
dataset/zhvoice/zhmagicdata/5_941/5_941_20170616153308.wav 3239
dataset/zhvoice/zhmagicdata/5_968/5_968_20170614162657.wav 3240
dataset/zhvoice/zhmagicdata/5_968/5_968_20170622194003.wav 3240
dataset/zhvoice/zhmagicdata/5_968/5_968_20170707200554.wav 3240
dataset/zhvoice/zhmagicdata/5_970/5_970_20170616000122.wav 3241
训练模型
使用train.py
训练模型,本项目支持多个音频预处理方式,通过参数feature_method
可以指定,melspectrogram
为梅尔频谱,spectrogram
为声谱图。通过参数augment_conf_path
可以指定数据增强方式。训练过程中,会使用VisualDL保存训练日志,通过启动VisualDL可以随时查看训练结果,启动命令visualdl --logdir=log --host 0.0.0.0
# 单卡训练
CUDA_VISIBLE_DEVICES=0 python train.py
# 多卡训练
python -m paddle.distributed.launch --gpus '0,1' train.py
训练输出日志:
----------- Configuration Arguments -----------
augment_conf_path: configs/augment.yml
batch_size: 64
feature_method: melspectrogram
learning_rate: 0.001
num_epoch: 30
num_speakers: 3242
num_workers: 4
pretrained_model: None
resume: None
save_model_dir: models/
test_list_path: dataset/test_list.txt
train_list_path: dataset/train_list.txt
use_model: ecapa_tdnn
------------------------------------------------
I0424 08:57:03.707505 3377 nccl_context.cc:74] init nccl context nranks: 2 local rank: 0 gpu id: 0 ring id: 0
W0424 08:57:03.930370 3377 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 7.5, Driver API Version: 11.6, Runtime API Version: 10.2
W0424 08:57:03.932493 3377 device_context.cc:465] device: 0, cuDNN Version: 7.6.
I0424 08:57:05.431638 3377 nccl_context.cc:107] init nccl context nranks: 2 local rank: 0 gpu id: 0 ring id: 10
······
[2022-04-24 09:25:10.481272] Train epoch [0/30], batch: [7500/8290], loss: 9.03724, accuracy: 0.33252, lr: 0.00100000, eta: 14:58:26
[2022-04-24 09:25:32.909873] Train epoch [0/30], batch: [7600/8290], loss: 9.00004, accuracy: 0.33600, lr: 0.00100000, eta: 15:09:07
[2022-04-24 09:25:55.321806] Train epoch [0/30], batch: [7700/8290], loss: 8.96284, accuracy: 0.33950, lr: 0.00100000, eta: 15:13:13
[2022-04-24 09:26:17.836304] Train epoch [0/30], batch: [7800/8290], loss: 8.92626, accuracy: 0.34294, lr: 0.00100000, eta: 14:57:15
[2022-04-24 09:26:40.306800] Train epoch [0/30], batch: [7900/8290], loss: 8.88968, accuracy: 0.34638, lr: 0.00100000, eta: 14:51:06
[2022-04-24 09:27:02.778450] Train epoch [0/30], batch: [8000/8290], loss: 8.85430, accuracy: 0.34964, lr: 0.00100000, eta: 15:00:36
[2022-04-24 09:27:25.240278] Train epoch [0/30], batch: [8100/8290], loss: 8.81858, accuracy: 0.35294, lr: 0.00100000, eta: 14:51:58
[2022-04-24 09:27:47.690570] Train epoch [0/30], batch: [8200/8290], loss: 8.78368, accuracy: 0.35630, lr: 0.00100000, eta: 14:55:41
======================================================================
[2022-04-24 09:28:12.084404] Test 0, accuracy: 0.76057 time: 0:00:04
======================================================================
[2022-04-24 09:28:12.909394] Train epoch [1/30], batch: [0/8290], loss: 5.83753, accuracy: 0.68750, lr: 0.00099453, eta: 2 days, 3:47:48
[2022-04-24 09:28:35.346418] Train epoch [1/30], batch: [100/8290], loss: 5.80430, accuracy: 0.64527, lr: 0.00099453, eta: 15:00:01
[2022-04-24 09:28:57.873686] Train epoch [1/30], batch: [200/8290], loss: 5.78946, accuracy: 0.64218, lr: 0.00099453, eta: 14:46:39
······
VisualDL页面:
数据增强
本项目提供了几种音频增强操作,分布是随机裁剪,添加背景噪声,调节语速,调节音量,和SpecAugment。其中后面4种增加的参数可以在configs/augment.yml
修改,参数prob
是指定该增强操作的概率,如果不想使用该增强方式,可以设置为0。要主要的是,添加背景噪声需要把多个噪声音频文件存放在dataset/noise
,否则会跳过噪声增强
noise:min_snr_dB: 10max_snr_dB: 30noise_path: "dataset/noise"prob: 0.5
评估模型
训练结束之后会保存预测模型,我们用预测模型来预测测试集中的音频特征,然后使用音频特征进行两两对比,阈值从0到1,步长为0.01进行控制,找到最佳的阈值并计算准确率。
python eval.py
输出类似如下:
----------- Configuration Arguments -----------
feature_method: melspectrogram
list_path: dataset/test_list.txt
num_speakers: 3242
resume: models/
use_model: ecapa_tdnn
------------------------------------------------
W0425 08:27:32.057426 17654 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 7.5, Driver API Version: 11.6, Runtime API Version: 10.2
W0425 08:27:32.065165 17654 device_context.cc:465] device: 0, cuDNN Version: 7.6.
成功加载模型参数和优化方法参数:models/ecapa_tdnn/model.pdparams
开始提取全部的音频特征...
167it [00:15, 10.70it/s]
分类准确率为:0.9608
开始两两对比音频特征...
100%|███████████████████████████| 5332/5332 [00:05<00:00, 1027.83it/s]
找出最优的阈值和对应的准确率...
100%|███████████████████████████| 100/100 [00:06<00:00, 16.54it/s]
当阈值为0.58, 两两对比准确率最大,准确率为:0.99980
声纹对比
下面开始实现声纹对比,创建infer_contrast.py
程序,编写infer()
函数,在编写模型的时候,模型是有两个输出的,第一个是模型的分类输出,第二个是音频特征输出。所以在这里要输出的是音频的特征值,有了音频的特征值就可以做声纹识别了。我们输入两个语音,通过预测函数获取他们的特征数据,使用这个特征数据可以求他们的对角余弦值,得到的结果可以作为他们相识度。对于这个相识度的阈值threshold
,读者可以根据自己项目的准确度要求进行修改。
python infer_contrast.py --audio_path1=audio/a_1.wav --audio_path2=audio/b_2.wav
输出类似如下:
----------- Configuration Arguments -----------
audio_path1: audio/a_1.wav
audio_path2: audio/b_2.wav
feature_method: melspectrogram
resume: models/
threshold: 0.5
use_model: ecapa_tdnn
------------------------------------------------
W0425 08:29:10.006249 21121 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 7.5, Driver API Version: 11.6, Runtime API Version: 10.2
W0425 08:29:10.008555 21121 device_context.cc:465] device: 0, cuDNN Version: 7.6.
成功加载模型参数和优化方法参数:models/ecapa_tdnn/model.pdparams
audio/a_1.wav 和 audio/b_2.wav 不是同一个人,相似度为:-0.09565544128417969
声纹识别
在上面的声纹对比的基础上,我们创建infer_recognition.py
实现声纹识别。同样是使用上面声纹对比的infer()
预测函数,通过这两个同样获取语音的特征数据。 不同的是笔者增加了load_audio_db()
和register()
,以及recognition()
,第一个函数是加载声纹库中的语音数据,这些音频就是相当于已经注册的用户,他们注册的语音数据会存放在这里,如果有用户需要通过声纹登录,就需要拿到用户的语音和语音库中的语音进行声纹对比,如果对比成功,那就相当于登录成功并且获取用户注册时的信息数据。第二个函数register()
其实就是把录音保存在声纹库中,同时获取该音频的特征添加到待对比的数据特征中。最后recognition()
函数中,这个函数就是将输入的语音和语音库中的语音一一对比。
有了上面的声纹识别的函数,读者可以根据自己项目的需求完成声纹识别的方式,例如笔者下面提供的是通过录音来完成声纹识别。首先必须要加载语音库中的语音,语音库文件夹为audio_db
,然后用户回车后录音3秒钟,然后程序会自动录音,并使用录音到的音频进行声纹识别,去匹配语音库中的语音,获取用户的信息。通过这样方式,读者也可以修改成通过服务请求的方式完成声纹识别,例如提供一个API供APP调用,用户在APP上通过声纹登录时,把录音到的语音发送到后端完成声纹识别,再把结果返回给APP,前提是用户已经使用语音注册,并成功把语音数据存放在audio_db
文件夹中。
python infer_recognition.py
输出类似如下:
----------- Configuration Arguments -----------
audio_db: audio_db
feature_method: melspectrogram
resume: models/
threshold: 0.5
use_model: ecapa_tdnn
------------------------------------------------
W0425 08:30:13.257884 23889 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 7.5, Driver API Version: 11.6, Runtime API Version: 10.2
W0425 08:30:13.260191 23889 device_context.cc:465] device: 0, cuDNN Version: 7.6.
成功加载模型参数和优化方法参数:models/ecapa_tdnn/model.pdparams
Loaded 沙瑞金 audio.
Loaded 李达康 audio.
请选择功能,0为注册音频到声纹库,1为执行声纹识别:0
按下回车键开机录音,录音3秒中:
开始录音......
录音已结束!
请输入该音频用户的名称:夜雨飘零
请选择功能,0为注册音频到声纹库,1为执行声纹识别:1
按下回车键开机录音,录音3秒中:
开始录音......
录音已结束!
识别说话的为:夜雨飘零,相似度为:0.920434
其他版本
- Tensorflow:VoiceprintRecognition-Tensorflow
- Pytorch:VoiceprintRecognition-Pytorch
- Keras:VoiceprintRecognition-Keras
参考资料
- https://github.com/PaddlePaddle/PaddleSpeech
- https://github.com/yeyupiaoling/PaddlePaddle-MobileFaceNets
- https://github.com/yeyupiaoling/PPASR
基于PaddlePaddle实现的EcapaTdnn声纹识别模型相关推荐
- 基于Pytorch实现的EcapaTdnn声纹识别模型
前言 本项目使用了EcapaTdnn模型实现的声纹识别,不排除以后会支持更多模型,同时本项目也支持了多种数据预处理方法,损失函数参考了人脸识别项目的做法PaddlePaddle-MobileFaceN ...
- 基于Tensorflow2实现的中文声纹识别
前言 本章介绍如何使用Tensorflow实现简单的声纹识别模型,首先你需要熟悉音频分类,没有了解的可以查看这篇文章<基于Tensorflow实现声音分类> .基于这个知识基础之上,我们训 ...
- 基于Pytorch实现的声纹识别模型
前言 本章介绍如何使用Pytorch实现简单的声纹识别模型,本项目参考了人脸识别项目的做法Pytorch-MobileFaceNet ,使用了ArcFace Loss,ArcFace loss:Add ...
- 基于Tensorflow实现声纹识别
前言 本章介绍如何使用Tensorflow实现简单的声纹识别模型,首先你需要熟悉音频分类,没有了解的可以查看这篇文章<基于Tensorflow实现声音分类>.基于这个知识基础之上,我们训练 ...
- android声纹识别技术,基于Android平台的声纹识别系统的研究与实现
摘要: 社会的发展越来越快,计算机技术的应用也愈来愈广,已经渗透到生活的各个方面.在快节奏.信息化的时代,需要识别和交互的应用日益广泛,要求验证身份的场合越来越多,迅速判定一个人的身份是一个非常重要的 ...
- 业界首个声纹识别与音频检索系统上线,10分钟搭建产业级应用
随着深度学习技术的升级与产业的发展,智能语音交互已成为了我们日常生活中一个重要的组成部分,并广泛应用在地图导航播报.智能客服回访.手机语音输入以及各类智能助手等应用场景中,可以说语音已成为了人与机器之 ...
- 业界首个声纹识别与音频检索系统,10分钟搭建产业级应用
随着深度学习技术的升级与产业的发展,智能语音交互已成为了我们日常生活中一个重要的组成部分,并广泛应用在地图导航播报.智能客服回访.手机语音输入以及各类智能助手等应用场景中,可以说语音已成为了人与机器之 ...
- 人工智能Java SDK:声纹识别
声纹识别 所谓声纹(Voiceprint),是用电声学仪器显示的携带言语信息的声波频谱.人类语言的产生是人体语言中枢与发音器官之间一个复杂的生理物理过程, 人在讲话时使用的发声器官–舌.牙齿.喉头.肺 ...
- 使用Tensorflow实现声纹识别
原文博客:Doi技术团队 链接地址:https://blog.doiduoyi.com/authors/1584446358138 初心:记录优秀的Doi技术团队学习经历 本文链接:使用Tensorf ...
最新文章
- BZOJ1251: 序列终结者
- Centos7.2搭建Openstack的Swift组件,查看状态:No such file or directory
- Flutter实战(一)写一个天气查询的APP
- 【CV】带你入门多目标跟踪(一)领域概述
- 简易的CRM系统案例之SpringMVC+JSP+MySQL+hibernate框架版本
- Hadoop赠品–综述
- httpservletrequest获取不到登录的session_cookie和session是怎么交互的?
- 真正的Go编译器与链接器在哪里?
- 你的押金在这?ofo发文曝光多起贪腐案:总涉案金额达数百万元
- IDEA中用maven打出的jar包只有一个META-INF文件夹,没有java的源码???
- php派车系统,公务用车管理系统
- atomic 内存序_C++11的原子量与内存序浅析
- macOS上显示隐藏文件
- 计算机没有显示插入的移动硬盘,电脑插入移动硬盘没有显示的解决办法
- 单层石墨烯工业化量产科研成果及工业化量产基地落地
- [朝气蓬勃][22H2]Win11.0.22622.450专工-微创-优化
- CRM系统概念与项目开发流程
- 解决element-ui数字输入框的问题
- PPT形状的多种玩法
- 需求分析中适应性怎么写_需求文档,怎么写才不会被打?
热门文章
- 单体架构(Monolith)与微服务架构(MicroService)
- 【解决方案 七】---Git Merge时“交换文件.MERGE_MSG.swp已经存在”的问题
- 移动宽带配置ipv6
- 山水画看腻了?PaddleGan带你灵魂转换!
- Win32 鼠标消息 - 客户区鼠标消息、非客户区鼠标消息、击中测试、鼠标滚轮
- 百度还是知乎,这一次你选对了吗?
- An operation is not implemented: not implemented被坑之路[Kotlin]
- 共建共享做大5G“蛋糕”
- 计算机基础:(计算机的起源与发展)
- Python基础入门教程