Speaker Recognition说话人识别(声纹识别)

说话人识别,又称声纹识别。从上世纪60年代开始到现在,声纹识别一直是生物识别技术研究的主题。从传统的基于模板匹配的方法,到早期基于统计学方法,直到基于深度学习的声纹识别技术成为主流。本项目给出一个从传统(基于GMM、GMM-UBM、GMM-SVM[3]、联合因子分析、i-vector的方法),到基于深度学习的声纹识别方法的实现。

1、基于GMM的声纹识别

1.1 测试环境:

操作系统:Windows10
代码环境:Python3.6
主要用到的开源库:sklearn、librosa、numpy
数据集:TIMIT语音识别数据集和我自己收集的有15个说话人,每个人6句话的小数据集(暂不公开)

1.2 在TIMIT数据集上进行测试

TIMIT语料库是为声学语音知识的获取(模型训练)以及自动语音识别系统(ASR)的评估(模型测试)而构建的,是由国防部赞助,在研究计划署(DARPA-ISTO)、麻省理工学院(MIT)、斯坦福研究院(SRI)、德州仪器(TI)共同努力下完成。说话人信息:由来自美国8个主要方言地区的630位说话者讲10个句子构成。10个句子分为:

**SA-**方言句子(Dialect sentence):由SRI设计,总共2句。每个人都会读SA1、SA2这两个句子,体现不同地区方言的差别。(因此可用于方言判断算法的数据集,而其他情况一般不用该类句子)

**SX-**音素紧凑的句子(Phondtically-compact sentence):由MIT设计,总共450句,目的是让句子中的音素分布平衡,尽可能的包含所有音素对。每个人读5个SX句子,并且每个SX句子被7个不同的人读。

**SI-**音素发散的句子(Phonetically-diverse sentence):由TI在现有语料库Brown Corpus与剧作家对话集(the Playwrights Dialog)挑选的,总共1890句。目的是增加句子类型和音素文本的多样性,使之尽可能的包括所有的等位语境(Allophonic context)。每个人读三个SI句子,并且每个SI句子仅被一个人读一次。

630个说话人被分为TRAIN(462人)和TEST(168人)。我只用到TRAIN的462个说话人语音数据。所以我的说话人样本数是462个。因为SA的两个句子是方言,所以我并没有用到这两个句子。其他8个句子,我是用SX的5个句子和SI的1个句子作为训练集,SI的另外2个句子作为测试集。并将6个训练句子合并为1个句子方便提取MFCC特征。

我自己在TIMIT数据集基础上划分的数据。[Baidu Driver | Google Driver]

也可下载TIMIT原始数据,根据你自己的情况划分数据。[Baidu Driver | Google Driver]

├─TEST(168人)
│ ├─DR1
│ │ ├─FCJF0
│ │ ├─FDAW0 .......
│ ├─DR2
│ │ ├─FAEM0
│ │ ├─FAJW0
......
│ ├─DR3
│ │ ├─FALK0
│ │ ├─FCKE0
......
├─TEST_MFCC(测试集提取MFCC,462人)
│ ├─spk_1
│ ├─spk_10
│ ├─spk_100
......
├─TRAIN(训练集数据,462人)
│ ├─DR1
│ │ ├─FCJF0
│ │ ├─FDAW0
......
│ ├─DR2
│ │ ├─MTJG0
......
│ ├─DR3
│ │ ├─FALK0
│ │ ├─FCKE0
......
└─TRAIN_MFCC(提取的训练集MFCC,462人)
├─spk_1
├─spk_10
├─spk_100
......

我使用Python实现的算法流程大致如下:

(1)提取24维MFCC特征。首先分别读入462个说话人的经过合并后的一段长语音(大概20s),MFCC特征提取过程与之前描述的在我自己小样本数据集上提取的过程一致,这里不再赘述。与之不同的主要有两点:第一,对于20s的语音提取MFCC之后特征维度大致为(2000,24)。因此需要将特征保存,避免重复提取。使用librosa提取的MFCC特征为numpy格式,因此我保存为.npy格式的文件,使用时load参数即可。第二,对462个说话人提取24维MFCC特征相当耗时,所以在实际代码实现时,我将462个说话人分为4批,对每一批分别开一个进程进行特征提取,运行效率提升了4倍左右。

(2)进行gmm训练。将每个说话人语音的24维MFCC特征参数作为输入,训练GMM。经过调参对比后,GMM的聚类数量设为3个,协方差矩阵选取full的效果最好。同样,gmm的训练过程也是多进行并行计算。

(3)测试说话人gmm模型。我使用SI中的1个句子作为测试数据(2s左右)。将2s语音作为输入,分别提取24维MFCC参数。然后分别将462个人的MFCC特征输入gmm模型,然后gmm对每一个输入进行打分。之后使用softmax将所有说话人的得分归一化到[0,1]区间,即得到每个说话人在当前gmm模型上的概率。概率最大的就是模型对应的说话人。

(4)测试结果:SI第一个句子的测试结果:验证正确的数量为294,验证错误的数量为168,识别准确率为63.6%。 SI第二个句子的测试结果为:验证正确的数量为204,验证错误的数量为258,识别准确率为44.2%。

2、基于self-attention的说话人识别

2.1 测试环境:
google colab(Telsa T4 -16G)

Pytorch 1.7.1

数据集:VoxCeleb数据集(选取其中600个说话人)

主要参考李宏毅2021年深度学习课程作业HW4。使用开源的声纹识别数据集VoxCeleb1,我们从中选取了其中600个说话人的数据,然后分别对这600个人的语音使用mel滤波器组提取40维特征,作为神经网络的输入。

网络结构部分,我们使用self-attention机制。下图是《attention is all you need》论文中提出的Transformer结构。主要分为编码器encoder和解码器decoder两部分。对于本网络只用到左侧的encoder部分。

简单介绍一下Transformer的encoder。Encoder可以由下面一组串联的Block组成。每一个Block是一个self-attention。

这里的self-attention的输出比传统的self-attention在输出之后又加了对应的输入。然后对相加后的结果做了Layer Norm。Layer Norm不同于Batch Norm。Batch Norm是对不同样本的同一个维度的不同特征计算mean和std。Layer Norm是计算同一个样本不同维度的相同特征计算mean和std,然后计算norm。之后再对做了norm的输出通过FC,然后相加,再做Layer Norm,然后输出。

说话人识别网络结构代码:

class Classifier(nn.Module):def __init__(self, d_model=80, n_spks=600, dropout=0.1):super().__init__()# Project the dimension of features from that of input into d_model.self.prenet = nn.Linear(40, d_model)self.encoder_layer = nn.TransformerEncoderLayer(d_model=d_model, dim_feedforward=256, nhead=2)self.encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=2)# Project the the dimension of features from d_model into speaker nums.self.pred_layer = nn.Sequential(nn.Linear(d_model, n_spks),)def forward(self, mels):"""args:mels: (batch size, length, 40)return:out: (batch size, n_spks)"""# out: (batch size, length, d_model)out = self.prenet(mels)# out: (length, batch size, d_model)out = out.permute(1, 0, 2)# The encoder layer expect features in the shape of (length, batch size, d_model).out = self.encoder(out)# out: (batch size, length, d_model)out = out.transpose(0, 1)# mean poolingstats = out.mean(dim=1)# out: (batch, n_spks)out = self.pred_layer(stats)return outnet = Classifier()
summary(net.to("cuda"), (2,40), device="cuda")

 网络结构如下图所示:

接下来划分训练集和验证集。将90%的数据用于train,10%的数据用于validation。

由于说话人识别是一个分类问题,所以定义损失函数为CrossEntropyLoss(),在Pytorch中交叉熵损失把softmax和CrossEntropy都定义在nn.CrossEntropyLoss(),因此不需要再定义softmax,只需要将模型的输出和labels输入CrossEntropyLoss()即可。定义优化函数为AdamW,这是Adam的改进版本,有更好的优化效果。

训练过程如下图所示。训练过程共迭代70000次,每2000次做一次validation。从结果可以看出,训练集上的损失在不断下降,准确率在不断上升,训练结束时的准确率为91%,验证集的准确率为80%。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/3564.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot篇(简化操作的原理)

目录 一、代码位置 二、统一版本管理(parent) 三、提供 starter简化 Maven 配置 四、自动配置 Spring(引导类) 五、嵌入式 servlet 容器 一、代码位置 二、统一版本管理(parent) SpringBoot项目都会继…

华为HarmonyOS借助AR引擎帮助应用实现虚拟与现实交互的能力3-获取设备位姿

设备位姿描述了物体在真实世界中的位置和朝向。AR Engine提供了世界坐标下6自由度(6DoF)的位姿计算,包括物体的位置(沿x、y、z轴方向位移)和朝向(绕x、y、z轴旋转)。通过AR Engine,您…

【Git】Git常用命令

目录 1 前言2 git命令2.1 branch2.2 checkout2.3 pull and push2.4 config2.4.1 Proxy 2.5 tag2.6 rebase2.7 patch2.8 remote2.9 submodule2.10 rm2.10 gitignore2.11 某个commit更改了哪些文件2.12 clean 3 结束语 1 前言 本章记录总结在使用git过程中常用的一些命令&#x…

cgroup2版本下使用cgroups对内存/cpu进行控制

先查看cgroups的版本支持: cat /proc/filesystems | grep cgroup 运行结果: 如上表示支持cgroup2版本 一、对内存进行控制 cgroup版本对于内存控制是单独使用/sys/fs/cgroup/memory路径控制的,而在cgroup2版本中是统一管理,所以没有该路径,所以只需先进入该路径: cd /sys/…

安卓应用跳转回流的统一和复用

本文字数:6799字 预计阅读时间:35分钟 作为一个功能复杂的应用,无法避免地需要支持众多路径的回流,比如从Launcher、从Push通知、从端外H5、从合作第三方App以及从系统资源分享组件等。 我们知道,不同的回流路径会通过…

C3.【C++ Cont】名字空间、注释和变量

目录 1.回顾 2.名字空间(也称命名空间) 介绍 代码示例 3.注释 4.练习 B2003 输出第二个整数 方法1 方法2 1.回顾 在C1.【C Cont】准备中提到了名字空间(namespace)语句 using namespace std; 2.名字空间(也称命名空间) 介绍 1.处在在同一个空间内的,若有重名则会名…

常见自动化测试框架分层架构

作为一名专业的测试人员,搭建一个高级的自动化测试框架需要考虑多个因素。以下是一些步骤和指导,帮助你构建一个强大且灵活的自动化测试框架: 1. 理解框架的概念: - 首先,我们需要明确什么是“框架”。在自动化测试中…

103 - Lecture 2 Table and Data Part 1

SQL - Tables and Data Part 1 Relational Database Management System(RDBMS) 关系型数据库管理系统(RDBMS)是基于关系模型的数据库系统,它支持多种关系操作。关系模型是一种数据存储和检索的模型,它使用表格来组织数据&#x…

NestJS vs Fastify:Node.js框架的性能对决

在Node.js的世界中,框架的选择对于应用的性能和可维护性有着至关重要的影响。NestJS和Fastify是两个备受瞩目的框架,它们各自以其独特的优势在开发者社区中赢得了声誉。本文将深入探讨这两个框架的性能特点,并分析它们在不同场景下的适用性。…

【NOIP普及组】明明的随机数

【NOIP普及组】明明的随机数 C语言实现C实现Java实现Python实现 💐The Begin💐点点关注,收藏不迷路💐 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随…

python中t是什么意思

python中t是什么意思? python中t指的是“\r”:回车符,返回到这一行的开头,return的意思。 其他相关: \n:换行符,到下一行的同一位置,纵坐标相同,new line的意思。 \t…

OracleJDK与OpenJDK的区别(附带win11下多版本jdk安装)

OracleJDK与OpenJDK的区别(附带win11下多版本jdk安装) 在Java开发领域,OracleJDK与OpenJDK是两个常被提及的名词,它们都是Java开发工具包(JDK)的实现,但各自具有不同的特点和优势。在早期的jav…

代码随想录算法训练营第三十一天 | 56.合并区间 738.单调递增的数字 968.监控二叉树

LeetCode 56.合并区间: 文章链接 题目链接:56.合并区间 思路: ① 合并所有重叠的区间,合并后的区间数组不重叠,因此下面两种多区间重叠,其中的区间都要进行合并 ② 合并区间:因为情况2也算作…

[ComfyUI]FaceAging:太好玩啦!FaceAging终于装好了!负50到正100岁随心调整!超强又难装的节点安装教程来了! Comfyui教程

大家好!今天我要向大家介绍一个超级有趣的话题——[ComfyUI]FaceAging!这个工具能够让你轻松实现人脸年龄的调整,从负50岁到正100岁,让你的创作更加有趣和独特。 想象一下,你有一个强大的AI助手,它能够根据…

蓝桥杯真题——乐乐的序列和(C语言)

问题描述 乐乐在玩一个游戏,她有一排宝石,每个宝石上都刻有一个整数值。她的目标是从中挑选出一些宝石,使得选出的宝石数量为偶数,且这些宝石上的数字总和最大。如果不选任何宝石(即选出宝石数量为 00,也是…

猫用宠物空气净化器哪个牌子好?求噪音小的宠物空气净化器推荐!

最近真是烦躁到了顶峰!猫咪换毛季太折磨人了,白天上班累的要死,晚上回家还要和猫毛斗争。每天回家都是一场豪赌,需要花费的清理时间取决于家里的猫毛散落程度。有时候忙起来完全不想管,回到家只想躺着。 但最近身体出…

redis7学习笔记

文章目录 1. 简介1.1 功能介绍1.1.1 分布式缓存1.1.2 内存存储和持久化(RDBAOF)1.1.3 高可用架构搭配1.1.4 缓存穿透、击穿、雪崩1.1.5 分布式锁1.1.6 队列 1.2 数据类型StringListHashSetZSetGEOHyperLogLogBitmapBitfieldStream 2. 命令2.1 通用命令copydeldumpexistsexpire …

32位汇编——通用寄存器

通用寄存器 什么是寄存器呢? 计算机在三个地方可以存储数据,第一个是把数据存到CPU中,第二个把数据存到内存中,第三个把数据存到硬盘上。 那这个所谓的寄存器,就是CPU中用来存储数据的地方。那这个寄存器有多大呢&a…

1.1 OpenCV准备工作

介绍了如何在Windows系统中配置Python和Anaconda环境,并安装OpenCV库。首先从Python官网下载并安装Python,然后配置环境变量。接着安装Anaconda,并通过Anaconda Navigator或Prompt管理包。最后,在Anaconda Prompt中使用pip命令安装…

在gitlab,把新分支替换成master分支

1、备份master分支,可以打tag 2、删除master分支 正常情况下,master分支不允许删除,需要做两个操作才能删除 a、变更项目默认分支为非master分支,可以先随便选择 b、取消master为非保护分支 操作了上述两步,就可以删…