说话人性别识别——语音检测初探

目录

一、任务背景和分析

二、特征抽取

librosa

wave

torchaudio

三、数据集

commonvoice [ 中文]

四、模型训练

1、频域信号+LSTM+2DCNN

2、频域信号+2DCNN

3、时域信号+1DCNN


一、任务背景和分析

        公司有项目需求,需要识别语音信号是男女性别以及是否是彩铃等。之前一直是做文本相关的NLP相关项目,为此也开始慢慢涉足语音领域了。语音领域和文本NLP领域是不一样的,我猜测——目前语音领域相关的预训练模型还不成熟,端到端的方案还不足以满足商用的需求,比如ASR或者SST语音自动识别的方案HUBERT和wav2vec等——否则大家都开始使用起来了,目前应该是采用一些比较传统的方案。

ASR任务目前对我们公司来说,自研还是非常困难的,就直接使用生态伙伴科大讯飞的算法;项目需求区分男女声和彩铃的声音,其实这个任务还是比较简单的,并没有语音识别或者声纹识别中那么复杂。在数据质量和场景简单的情况下,应该能取得不错的效果。

语音信号是时域信号,目前基于时域信息对语音进行分析的貌似不是特别多,没有比较好的模型直接提取到合适的特征;一般而言都是通过传统的信号处理方案来做的,把语音时域信号转化为时域信号后就能得到很多特征,比如:MFCC、Fbank、bark谱、基频、能量幅度、短时过零率之类的——详见语音特征小结。

区分男女性别以及彩铃信号这样的任务,主要的关键点在哪里呢?主要能找到区分它们三者的特征,就可以使用深度学习的模型或者机器学习的模型,或者直接使用规则来做。需要找到什么样的特征呢?

 录了自己和女同事的音频,得到时序和频谱图(上图女,下图男)。感觉就从频谱图上直接看,还是看不出来的。一般而言男女声音的音高也就是频率是不一样的,但是也有重叠的部分;同时彩铃一般含有音乐的声音,它和人说话也有很大不同,音色不同,这个感觉在数理上反映也是频率的不同——据个人不完全理解这里的不同应该就是频率的分布不一样了,所以具体什么样的特征能区分开来也不是十分清楚的。那这个时候就得想到了深度学习的方案了,让模型自己去抽取相应的特征,也不需要管什么频率具体的分布,谱质心、谱对比度、基音周期等等特征,直接抽取语音信号的Fbank、Mfcc等特征,它们具体的区别,我不是专业的不清楚——知乎高赞问答解释如下语音信号提取声学特征时,MFCC和PLP的区别是什么?,喂入模型中即可!

另一方面这是一个简单的分类任务,它们3个类直接本来就存在天然的差异,也不需要太复杂的模型,应该就能搞定。

所以基本的方案就是

1、抽取Mfcc或者Fbank特征

2、Mfcc或者Fbank特征喂入模型(CNN/Lstm/LSTM+CNN)

3、分类得出结果。

当然也可以采用语音领域的预训练方案,wvNet或者wav2Vec这样的预训练+finetune的方案,这个方案比较新还没来得及学习,后续会学习,然后验证。

二、特征抽取

librosa

由于librosa库提供的特征提取API比较丰富,便选择了该库进行Mfcc和Fbank的提取。这里没啥好聊的,原理部分mfcc和fbank计算过程比较复杂详见——语音信号处理之(四)梅尔频率倒谱系数(MFCC)和语音识别特征处理(MFCC,Fbank,PNCC)

,而我就当个调包侠吧(原理部分就多去看几遍吧)。主要对提取特征的API的一些参数和遇到的坑进行一些总结吧

librosa.load(wav_path, sr=sr)——音频文件加载

把字节流的音频文件加载为基于sr抽样率的采样点数据,浮点数float32,numpy.array

注意点,mp3格式的文件需要调用其他的库,需要pip install;sr不设置会已默认的sr=22050

librosa.util.frame(wav, frame_length=frame_length, hop_length=hop_length)——分帧

设置帧长和帧移,这不是时间单位,而是采样点个数。比如采样率16000,1s内采样16000个数据点;frame_length 30ms应该就是480个采样点frame_length=480

fbank = librosa.feature.melspectrogram(y=wav, sr=sr, n_fft=frame_length, hop_length=hop_length, center=False,n_mels=128) fbank = fbank.T fbank = librosa.power_to_db(fbank)——梅尔频谱

n_fft短时傅里叶窗口长度,和帧长是一致的;n_mels采用多少个mel滤波器,最后得到的特征就是多少维度的;center参数需要进入源码去看,如果为True,表示音频会做padding,会使得帧D[:, t]的中心为信号  y[t * hop_length];而center=False的时候,不采用padding;要使得分帧后抽取特征再把特征cat起来和不分帧直接抽取特征的结果一致的话,就得采用center=False。

librosa.feature.mfcc(y=wav, sr=sr, n_mfcc=13, n_fft=frame_length, hop_length=hop_length, center = False, win_length = frame_length)——mel倒谱系数

librosa.feature.spectral_centroid(y=wav, sr=sr, n_fft=frame_length, hop_length=hop_length,center = False)——频谱中心

librosa.feature.spectral_contrast(y=wav, sr=sr, n_fft=frame_length, hop_length=hop_length, n_bands=4,center = False)——频谱对比度

librosa.core.piptrack(y=wav, sr=sr, S=None, n_fft=frame_length, hop_length=hop_length,center = False)

wave

读取语音的字节流和librosa中提取特征的不同

def read_wave(path):"""Reads a .wav file.Takes the path, and returns (PCM audio data, sample rate)."""with contextlib.closing(wave.open(path, 'rb')) as wf:num_channels = wf.getnchannels()assert num_channels == 1sample_width = wf.getsampwidth()assert sample_width == 2sample_rate = wf.getframerate()assert sample_rate in (8000, 16000, 32000, 48000)pcm_data = wf.readframes(wf.getnframes())params = wf.getparams()nchannels, sampwidth, framerate, nframes = params[:4]return pcm_data, sample_rate

wave读出来的是16bit的字节流,pcm编码数据,形如:

 一般而言,采样率sr = 16000的话,1s音频采样数据点就为16000个,而得到的pcm字节流就是32000个。这个时候需要分别存储模型是小端模式还是大端模式,可以把16bit的byte转化为int型和float型,神经网络中需要处理float32型数据。处理就是把2个长度的byte传化为1个int或者float:

#把bytes转化为int
for k in range(0,int(len(frame_byte)/2)):pcmInt.append(int.from_bytes(frame_byte[k * 2:k * 2 + 2], byteorder='little', signed=True))
# 再转化为float32
feature = np.array(pcmInt)/0x7fff

使用struct.unpack()转化——把16进制的2个byte字节流转化为float

pcmFloat = []
for k in range(0, int(len(frame_byte) / 2)):pcmFloat.append(struct.unpack('h', frame_byte[index * 2:index * 2 + 2])[0] / ((2 ** 15) - 1))

最后一种直接把一长串的16进制字节流转化为short int型,然后再做除法,得到最后的float32型数据np.frombuffer():

feature = np.frombuffer(frame_byte, ctypes.c_short)/0x7fff

以上3中方法,其中最后一种最好,CPU占用最少。

torchaudio

torchaudio 支持以 wav 和 mp3 格式加载声音文件

metadata = torchaudio.info(SAMPLE_WAV_PATH)//查看音频信息
waveform, sample_rate = torchaudio.load(SAMPLE_WAV_SPEECH_PATH)//加载音频返回的是张量
torchaudio提供了Spectrogram,MelSpectrogram,MFCC等特征的提取
specgram = torchaudio.transforms.Spectrogram()(waveform)
specgram = torchaudio.transforms.MelSpectrogram()(waveform)

三、数据集

由于是前期预研,验证方案的可行性,数据集采用了公共数据集

commonvoice [ 中文]

四、模型训练

1、频域信号+LSTM+2DCNN

尝试的特征分为频域信号的MFCC和Fbank;模型层面首先采用的是LSTM和二维卷积以及残差二维卷积网络的组合。测试出来后的效果还可以,这里采用二维卷积网络的原因就是直接凭直觉把一帧一帧的语音信号,组合为一个语音图像,就类似图像分类,所以采用了这个网络。

简单的看看具体的流程:

MFCC

语音信号——》分帧——》过VAD——》判定is_speech,并用循环链表判定人声起始和结束点——》合并所有的frames注意去掉重复的——》librosa抽取各种特征包含{mffc、基音周期、谱质心和谱对比度}——》lstm+ nn.Linear

  • Fbank+CNN+resCNN+RNN(LSTM)

FBank

语音信号——》分帧——》过VAD——》判定is_speech,并用循环链表判定人声起始和结束点——》合并所有的frames注意去掉重复的——》librosa抽取各种特征包含{Fbank、基音周期、谱质心和谱对比度}——》lstm+ nn.Linear

  • Fbank+CNN+resCNN+RNN(LSTM)

以上方案的准确率有细微差别,大致在下面数据附近,当然也和采用的帧数有关

Test_acc:0.943867 Test_recal:0.857778 Test_f1:0.826552

模型代码如下:

class GenderRecogiCnnLstmModel(nn.Module):def __init__(self,n_class=2,rescnn_layers = 1,rnn_layers = 1,n_feats=128,dropout=0.1):super(GenderRecogiCnnLstmModel,self).__init__()self.cnn = nn.Conv2d(in_channels=1,out_channels=4,kernel_size=3,stride=1,padding=3//2)# n residual cnn layers with filter size of 32self.rescnn_layers = nn.Sequential(*[Residual2DCNN(4, 4, kernel=3, stride=1, dropout=dropout, n_feats=n_feats)for _ in range(rescnn_layers)])self.rnn_layers = nn.Sequential(*[  nn.LSTM(input_size=n_feats if i==0 else n_feats*2,hidden_size=n_feats,batch_first=True,bidirectional=True)for i in range(rnn_layers)])self.classifier = nn.Sequential(nn.Linear(n_feats * 2, n_feats),  # birnn returns rnn_dim*2nn.GELU(),nn.Dropout(dropout),nn.Linear(n_feats, n_class))def forward(self,embeddings,mask):# embeddings [B,L,D]x = embeddings.unsqueeze(1).permute(0,1,3,2)# [B,1,D,L]x = self.cnn(x) #[]x = self.rescnn_layers(x)x = x.view(x.shape[0],-1,x.shape[-2])x,_ = self.rnn_layers(x)# x = self.pooling(x, mask)x = torch.mean(x,dim=1)out = self.classifier(x)out = torch.softmax(out, dim=-1)return outdef pooling(self,embedding,mask):embedding_mask = mask.unsqueeze(-1).expand(embedding.size()).float()t = embedding * embedding_masksum_embeddings = torch.sum(t,dim=1)sum_mask = embedding_mask.sum(dim=1)# 限定每个元素的最小值是1e-9,保证分母不为0sum_mask = torch.clamp(sum_mask, min=1e-9)# output_vectors = []# output_vectors.append(sum_embeddings / sum_mask)## output_vectors = torch.cat(output_vectors, 1)output_vectors = sum_embeddings / sum_maskreturn output_vectors
class Residual2DCNN(nn.Module):"""Residual CNN inspired by https://arxiv.org/pdf/1603.05027.pdfexcept with layer norm instead of batch norm"""def __init__(self, in_channels, out_channels, kernel, stride, dropout, n_feats):super(Residual2DCNN, self).__init__()self.cnn1 = nn.Conv2d(in_channels, out_channels, kernel, stride, padding=kernel // 2)self.cnn2 = nn.Conv2d(out_channels, out_channels, kernel, stride, padding=kernel // 2)self.dropout1 = nn.Dropout(dropout)self.dropout2 = nn.Dropout(dropout)self.layer_norm1 = CNNLayerNorm(n_feats)self.layer_norm2 = CNNLayerNorm(n_feats)def forward(self, x):residual = x  # (batch, channel, feature, time)x = self.layer_norm1(x)x = F.gelu(x)x = self.dropout1(x)x = self.cnn1(x)x = self.layer_norm2(x)x = F.gelu(x)x = self.dropout2(x)x = self.cnn2(x)x += residualreturn x  # (batch, channel, feature, time)class CNNLayerNorm(nn.Module):"""Layer normalization built for cnns input"""def __init__(self, n_feats):super(CNNLayerNorm, self).__init__()self.layer_norm = nn.LayerNorm(n_feats)def forward(self, x):# x (batch, channel, feature, time)x = x.transpose(2, 3).contiguous()  # (batch, channel, time, feature)x = self.layer_norm(x)return x.transpose(2, 3).contiguous()  # (batch, channel, feature, time)

2、频域信号+2DCNN

由于上述方案中的模型比较复杂,训练和推理速度有点慢,又尝试了一维卷积+残差卷积的组合,不采用lstm。

  • Fbank+CNN+resCNN
  • 当然语音信号的前期处理,分帧VAD等操作都是需要的,另外一个就是调整帧数,到底需要采取多少帧,这个和线上业务以及性能要求有关系。
  • Test_acc:0.944560 Test_recal:0.937778 Test_f1:0.840637

模型代码如下:

class GenderReco1DCnnModel(nn.Module):def __init__(self,n_class=2,n_feats=128,dropout=0.2):super(GenderReco1DCnnModel,self).__init__()self.layerNorm = nn.LayerNorm(n_feats)self.cnn = nn.Sequential(nn.Conv1d(in_channels=n_feats,out_channels=64,kernel_size=8,stride=4,padding=2),nn.ReLU(),nn.Conv1d(in_channels=64,out_channels=32,kernel_size=4,stride=2,padding=2),nn.ReLU(),nn.Conv1d(in_channels=32, out_channels=16, kernel_size=2, stride=1,padding=2),nn.ReLU(),)def forward(self,embeddings,mask):x = embeddings[:, 0:100, :]  # embeddings [B,n,D]x = self.layerNorm(x)x = x.permute(0,2,1)x = self.cnn(x)  # []x = x.view(x.shape[0],-1,x.shape[1])x = torch.mean(x, dim=1)out = self.classifier(x)out = torch.softmax(out, dim=-1)return out

3、时域信号+1DCNN

实验的过程中发现,在上线的过程中,语音信号是流式的传输且需要单机支持并发5000路,在提取MFCC或者Fbank特征的时候CPU瓶颈是支持不了的。方案应该采取消耗资源更低的提取特征的方案,可以尝试时域信号,也就是直接把语音信号波形图经过处理后作为模型输入,同样是需要对信号进行分帧,vad检测等。分帧以后,可以把一帧一帧看做一个语音单位,那么就有点类型TextCNN的情形,可以借鉴一维卷积网络来做。

  • 时域信号+CNN+resCNN(一维卷积)

模型网络很简单,如下

class GenderRecoTimeDomainVoiceModel(nn.Module):def __init__(self, n_class=2, rescnn_layers=10, n_feats=128, dropout=0.1):super(GenderRecoTimeDomainVoiceModel, self).__init__()self.layerNorm = nn.LayerNorm(n_feats)self.cnn = nn.Conv1d(in_channels=n_feats,out_channels=64,kernel_size=8,stride=4,padding=2)# n residual cnn layers with filter size of 32self.rescnn_layers = nn.Sequential(*[Residual1DCNN(64, 64, kernel=3, stride=1, dropout=dropout, n_feats=25)for _ in range(rescnn_layers)])self.classifier = nn.Sequential(nn.Linear(64, 64),  # birnn returns rnn_dim*2nn.GELU(),nn.Dropout(dropout),nn.Linear(64, n_class))def forward(self, embeddings):# embeddings [B,L,D]x = embeddings[:, 0:100, :]  # embeddings [B,n,D]x = x.view(x.shape[0],-1,480)x = self.layerNorm(x)x = x.permute(0, 2, 1)x = self.cnn(x)  # []x = self.rescnn_layers(x)x = x.permute(0, 2, 1)x = torch.mean(x, dim=1)out = self.classifier(x)return out

最后的结果

 基本满足上线准确率需求,同时这个方案,经过工程化的优化,已经实现了单机5000路的并发。

以上就是本人第一个语音项目的探索,很简单,学习到了一定的语音领域的知识,后面再接再厉,好好学习ASR和TTS相关知识,争取成为NLP和语音算法工程师!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chatgpt赋能python:Python短信群发:如何优化短信营销?

Python短信群发:如何优化短信营销? 短信营销是一种广泛用于促进业务和品牌认可度的营销策略。随着移动设备的普及以及人们越来越依赖手机,短信营销的有效性也在不断提高。在短信营销中,最大的优势之一是短信可以迅速传递到用户的…

chatgpt赋能python:Python就业前景分析

Python就业前景分析 1. Python简介 Python是一种简单易学、操作灵活、功能丰富的高级编程语言。它被广泛应用于人工智能、大数据分析、网络爬虫、自动化测试、Web开发、游戏开发等众多领域。Python的开发者们致力于让Python语言能够简单、易读、易学,适用于各种领…

由 ChatGPT 带来的对低代码产品的思考

在之前的文章中多次提到我们在开发一款低代码平台,主要面向 ToB 企业,帮助企业完善信息化建设,给企业的数字化转型贡献一份力量。 数字化转型的目标是降本增效,同样,效率对我们来说也至关重要,主要体现在&a…

内容安全策略 Content-Security-Policy

一、作用: 1、限制资源获取:限制网页当中一系列的资源获取的情况,从哪里获取,请求发到哪个地方 限制方式: default-src限制全局的和链接有关的作用范围 根据资源类型(connect-src、img-src等&#xff0…

记一下怎样关闭windows defender安全中心

Win10系统中自带Windows Defender杀毒软件,有些用户非常排斥,其一是扫描的频率太高,占用大量CPU。其二是有些文件不经过任何提示就直接删除。那么如何彻底关闭windows defender安全中心。 第一步:首先按winR,输入gped…

ICML 2023禁止使用大型语言模型写论文!LeCun转发:中小型模型可以用吗?

点击下方卡片,关注“CVer”公众号 AI/CV重磅干货,第一时间送达 点击进入—>Transformer微信技术交流群 转载自:新智元 | 编辑:昕朋 David 【导读】AI顶会ICML征稿日在即,关于道德准则的新政策却引来网友不满&#x…

英文论文润色哪家好用比较好,有值得推荐的吗

英文论文润色 推荐 英文论文润色对于写作者来说是一项十分重要的任务,它可以帮助我们修改文章中的语法、标点和排版等问题,使论文更加准确和易读。在众多的英文润色软件中,147chatgpt改写润色软件是一款值得推荐的全自动批量图文润色、自动纠…

chatgpt赋能python:Python爬取电影简介

Python 爬取电影简介 随着互联网技术的逐步普及,越来越多的人已经建立了自己的个人网站或博客,而如何让自己的网站获得更好的 SEO 排名,吸引更多的流量就成了一个非常重要的问题。其中,内容的质量和数量是关键的,而提…

文案修改软件哪个好,AI模型有哪些?

文案修改软件哪个好?ChatGPT是一个聊天机器人,要想从产品形态上复现其实并不困难,过去的苹果Siri、微软小冰、各个平台的客服机器人都是类似形态。但ChatGPT与它们真正拉开差距,从“人工智障”到“人工智能”的关键一跃&#xff0…

目标检测算法——YOLOv5/YOLOv7改进|将IOU Loss替换为EIOU Loss

&#x1f496;&#x1f496;>>>加勒比海带&#xff0c;QQ2479200884<<<&#x1f496;&#x1f496; &#x1f340;&#x1f340;>>>【YOLO魔法搭配&论文投稿咨询】<<<&#x1f340;&#x1f340; ✨✨>>>学习交流 | 温澜潮…

目标检测算法——助力涨点 | YOLOv5改进结合Alpha-IoU

深度学习Tricks&#xff0c;第一时间送达 论文题目&#xff1a;《Alpha-IoU: A Family of Power Intersection over Union Losses for Bounding Box Regression》 论文地址&#xff1a; https://arxiv.org/abs/2110.13675v2 1.论文简介&#xff1a; 文中&#xff0c;作者将…

chatgpt赋能python:Python控制NI板卡

Python控制NI板卡 NI&#xff08;National Instruments&#xff09;是全球领先的测试、测量、控制和自动化解决方案提供商。它的硬件平台、软件工具和应用专业知识与工程师社区结合&#xff0c;形成了一系列完整的产品系列&#xff0c;可帮助工程师快速上手、快速构建各种应用…

基于51单片机的室内湿度加湿温度声光报警智能自动控制装置设计

【ChatGPT】前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击查看学习资料&#xff09; wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;单片机湿度 获取完整无…

LangChain:LLM应用程序开发(上)——Models、Prompt、Parsers、Memory、Chains

文章目录 一、Models、Prompt、Parsers1.1 环境配置&#xff08;导入openai&#xff09;1.2 辅助函数&#xff08;Chat API : OpenAI&#xff09;1.3 使用OpenAI API进行文本翻译1.4使用LangChain进行文本翻译1.5 使用LangChain解析LLM的JSON输出1.5.1 LangChain输出为string格…

全域电商服务手册(2023)

导读&#xff1a; 《手册》收录内容营销、数字化、代运营、短视频直播、用户运营、金融支付、物流仓储、合规发展、渠道&供应链等领域的优质合作伙伴&#xff0c;为品牌与商家解决全域电商布局过程中遇到的难题。 关注公众号&#xff1a;【互联互通社区】&#xff0c;回复【…

2022中国绿色资本市场绿皮书

导读&#xff1a; 绿色是建设银行新金融行动的生态底色&#xff0c;为充分发挥绿色领域专业优势、引领市场多元创新&#xff0c;建设银行与北京绿金院合作发布《中国绿色资本市场绿皮书》&#xff0c;总结绿色投融资市场实践经验、展望创新产品发展趋势&#xff0c;期待与广大市…

产业分析:2023年电商发展报告

导读&#xff1a; 3年疫情&#xff0c;电商行业风起云涌&#xff0c;直播电商、即时零售、社区团购等新兴电商业态在疫情期间强势崛起&#xff0c;各路玩家激烈角逐&#xff0c;平台更迭轮换速度史无前例&#xff0c;电商格局持续震荡&#xff1b;疫情后&#xff0c;行业形成多…

端到端大模型来袭,自动驾驶的最优解?

最近&#xff0c;人工智能领域最火的莫过于大模型了。 由美国初创企业OpenAI开发的聊天应用ChatGPT引爆市场&#xff0c;生成式AI成为科技市场热点&#xff0c;ChatGPT背后是深度学习大模型&#xff0c;其理解和生成文字的能力超过以往AI产品。全球主要云计算公司例如亚马逊等都…

2023年中国电竞行业研究报告

导读&#xff1a; 报告重点通过对电子竞技市场的电竞游戏产品、电竞赛事、电竞俱乐部、电竞营销、电竞用户等各个因素的分析&#xff0c;从政策及市场环境、市场动态等角度展开对电子竞技行业的洞察&#xff0c;切实反映中国电竞行业现状与未来发展趋势。希望能为相关企业与资本…

2023慕尼黑上海电子展12大科技趋势 技术为王创新为本新动力

“经济下行”、“需求疲弱”、“”信心不足“、”消费通缩“是所有行业绕不过的两座大山&#xff0c;电子行业亦不例外&#xff0c;从“抢芯片”变成“去库存”&#xff0c;凛冽寒气持续至今。整个产业链上下无不在寻找破局点&#xff0c;深挖各个领域能够带来业务增量的机会。…