主要内容

基于基音和MFCC的说话人识别

这个例子演示了一种机器学习方法,基于从记录的语音中提取的特征来识别人。用于训练分类器的特征是语音浊音段的音高和mel频率倒频谱系数(MFCC)。这是一个封闭的扬声器识别:将被测扬声器的音频与所有可用的扬声器模型(有限集)进行比较,并返回最接近的匹配。

介绍

图中显示了本例中用于识别说话人的方法。

音高和MFCC是从10个扬声器记录的语音信号中提取的。这些特征被用来训练k -最近邻(KNN)分类器。然后,对新的需要分类的语音信号进行相同的特征提取。经过训练的KNN分类器预测10个扬声器中哪一个最接近匹配。

用于分类的特征

本节讨论音高和MFCC,这两个特性是用来对扬声器进行分类的。

球场

言语可以大致分为表达了无声的.在发声的情况下,来自肺部的空气被声带调节并产生准周期的兴奋。由此产生的声音由一个相对较低的频率振荡支配,称为.在语音不清的情况下,来自肺部的空气通过声道的收缩,成为紊流,噪声样的兴奋。在语音的源-滤波模型中,激励称为源,声道称为滤波器。语音源的特征提取是语音系统特征提取的重要组成部分。

作为浊音和浊音语音的一个例子,考虑单词“two”(/T UW/)的时域表示。辅音/T/(清音)看起来像噪音,而元音/UW/(清音)的特点是基频很强。

[audioIn,fs]=音频读取(“计数-16-44p1-mono-15秒波形”); twoStart=110e3;twoStop=135e3;audioIn=audioIn(两次启动:两次停止);时间向量=linspace((twoStart/fs),(twoStop/fs),numel(audioIn));声音(audioIn,fs)图形绘制(时间向量,audioIn)轴([(twoStart/fs)(twoStop/fs)-11])ylabel(“振幅”)包含(‘时间’)头衔(“话语-二”)

语音信号本质上是动态的,会随着时间而变化。假设语音信号在短时间尺度上是平稳的,它们的处理在20-40毫秒的窗口内完成。这个例子使用了一个30毫秒的窗口和25毫秒的重叠。使用函数以查看俯仰如何随时间变化。

窗长=圆形(0.03*fs);重叠长度=圆形(0.025*fs);f0=音高(音频输入,fs,“窗口长度”,窗长,“重叠长度”overlapLength,“范围”[50250]);图subplot(2,1,1) plot(timeVector,audioIn) axis([(110e3/fs) (135e3/fs) -1 1]) ylabel(“振幅”)包含(‘时间’)头衔(“话语-二”)子地块(2,1,2)时间矢量间距=linspace((两个开始/fs),(两个停止/fs),numel(f0));地块(时间矢量间距,f0,'*')轴([(110e3/fs)(135e3/fs)最小(f0)最大(f0)]ylabel(“音高(Hz)”)包含(‘时间’)头衔(“俯仰轮廓”)

这个函数估计每一帧的基音值。但是,基音是语音区域中源的唯一特征。区分静音和语音的最简单方法是分析短期功率。如果一帧中的功率高于给定阈值,则将该帧声明为语音。

pwrThreshold = -20;(段,~)=缓冲区(audioIn、windowLength overlapLength,“诺德利”);压水式反应堆= pow2db (var(段));isSpeech = (pwr > pwrThreshold);

区分浊音和清音的最简单方法是分析过零率。大量过零意味着不存在主导低频振荡。如果帧的过零率低于给定阈值,则将其声明为浊音。

zcrThreshold = 300;zeroLoc = (audioIn = = 0);crossedZero =逻辑([0;diff(标志(audioIn))));crossedZero (zeroLoc) = false;[crossedZeroBuffered, ~] =缓冲区(crossedZero、windowLength overlapLength,“诺德利”);zcr=(和(交叉零缓冲,1)*fs)/(2*窗长);isVoiced=(zcr
              

结合isSpeechisVoiced确定帧是否包含浊音。

voicedSpeech = isSpeech & is浊;

从音高估计和图中去除不对应语音的区域。

f0(~voicedSpeech)=NaN;图子图(2,1,1)绘制(时间向量,音频输入)轴([(110e3/fs)(135e3/fs)-1])牢固的ylabel (“振幅”)包含(‘时间’)头衔(“话语-二”次要情节(2,1,2)情节(timeVectorPitch f0,'*')轴([(110e3/fs)(135e3/fs)最小(f0)最大(f0)]ylabel(“音高(Hz)”)包含(‘时间’)头衔(“俯仰轮廓”)

梅尔频率倒频谱系数(MFCC)

MFCC是从语音信号中提取的常用特征,用于识别任务。在语音的源滤波器模型中,MFCC被理解为表示滤波器(声道).声道的频率响应相对平滑,而浊音的来源可以建模为脉冲序列。结果是,声道可以通过语音段的频谱包络进行估计。

MFCC的激励思想是基于对耳蜗的理解,将声道的信息(平滑频谱)压缩成少量的系数。

虽然没有计算MFCC的硬标准,但图中概述了基本步骤。

mel滤波器组线性空间前10个三角形滤波器和对数空间的其余滤波器。单个波段的能量是均匀的。该图代表了一个典型的mel滤波器组。

这个示例使用mfcc计算每个文件的MFCC。

数据集

本例使用CMU鲁棒语音识别组的人口普查数据库(也称为AN4数据库)[1.].该数据集包含男性和女性受试者说话的录音和数字。本节中的helper函数为您下载它,并将原始文件转换为FLAC。语音文件根据发言者对应的标签被划分为子目录。

下载并提取10位发言者(5位女性和5位男性)的语音文件到临时目录中HelperAN4Download函数。当您打开这个示例时,该函数被放置在当前文件夹中。

dataDir = HelperAN4Download;

创建一个audioDatastore目的是为培训管理这个数据库。数据存储允许您收集必要的文件格式的文件并读取它们。

ads=音频数据存储(数据目录,“包含子文件夹”符合事实的...“FileExtensions”,“弗拉克先生”,...“LabelSource”,“foldernames”)
ads=audioDatastore,具有以下属性:文件:{'.\scrawfor\AppData\Local\Temp\an4\wav\flacData\fejs\an36-fejs-b.flac';'.''.\scrawfor\AppData\Local\Temp\an4\wav\flacData\fejs\an37-fejs-b.flac';'.'.'.\scrawfor\AppData\Local\Temp\an4\wav\flacData\flacData\fejs\an38-fejs-b.flac'.'和122个以上}文件夹:{'C:\Users\scrawfor\AppData\Local\Temp\an4\wav\flacData'}标签:[fejs;fejs;fejs…和122个更分类的]AlternateFileSystemRoots:{}输出数据类型:'double'支持的输出格式:[“wav”“flac”“ogg”“mp4”“m4a”]默认输出格式:“wav”金宝app

这个splitEachLabel的函数audioDatastore将数据存储分割为两个或多个数据存储。结果数据存储具有来自每个标签的指定比例的音频文件。在本例中,数据存储被分成两部分。每个标签80%的数据用于训练,剩下的20%用于测试。这个countEachLabel的方法audioDatastore用于计算每个标签的音频文件数。在本例中,标签标识扬声器。

[adsTrain,adsTest]=拆分每个标签(ads,0.8);

显示数据存储和列车数据存储中的扬声器数量。

adsTrain
adsTrain=audioDatastore,具有以下属性:文件:{''.\scrawfor\AppData\Local\Temp\an4\wav\flacData\fejs\an36-fejs-b.flac';'.''.\scrawfor\AppData\Local\Temp\an4\wav\flacData\fejs\an37-fejs-b.flac';'.'.'.'.\scrawfor\AppData\Local\Temp\an4\wav\flacData\flacData\fejs\an38-fejs-b.flac'.'和更多文件夹:{'C:\Users\scrawfor\AppData\Local\Temp\an4\wav\flacData'}标签:[fejs;fejs;fejs…和94个更分类的]AlternateFileSystemRoots:{}输出数据类型:'double'支持的输出格式:[“wav”“flac”“ogg”“mp4”“m4a”]默认输出格式:“wav”金宝app
列车数据存储计数=计数每个标签(adsTrain)
列车数据存储计数=10×2表标签计数_____ _____ fejs 10 fmjd 10 fsrb 10 ftmj 10 fwxs 10 mcen 10 mrcb 10 msjm 10 msjr 10 msmn 7

显示数据存储和测试数据存储中的扬声器数量。

adsTest
adsTest = audioDatastore与属性:文件:{'…\ \涂鸦\AppData\本地\Temp\an4\wav\flacData\fejs\cen6-fejs- b.l ac';’……当地\ Temp \ scrawfor \ AppData \ \ an4 \ wav \ flacData \ fejs \ cen7-fejs-b.flac”;“…当地\ Temp \ scrawfor \ AppData \ \ an4 \ wav \ flacData \ fejs \ cen8-fejs-b。flac的……{'C:\Users\ scrifor \AppData\Local\Temp\an4\wav\flacData'}标签:[fejs;fejs;fejs……alteratefilesystemroots: {} OutputDataType: 'double' SupportedOutputFormats: ["金宝appwav" "flac" "ogg" "mp4" "m4a"] DefaultOutputFormat: "wav"
testDatastoreCount=countEachLabel(adsTest)
testDatastoreCount =10×2表标签计数_____ _____ fejs 3 fmjd 3 fsrb 3 ftmj 3 fwxs 2 mcen 3 mrcb 3 msjm 3 msjr 3 msmn 2

要预览数据存储的内容,请读取一个示例文件并使用默认音频设备播放它。

[sampleTrain,dsInfo]=读取(adsTrain);声音(sampleTrain,dsInfo.SampleRate)

从列车数据存储中读取将推动读取指针,以便您可以在数据库中进行迭代。重置列车数据存储以将读取指针返回到开始位置,以便进行以下特征提取。

重置(adsTrain)

特征提取

从训练数据存储中对应于浊音语音的每一帧中提取基音和MFCC特征,金宝appiVoicedSpeech,执行中概述的语音检测基音特征提取的描述

fs=dsInfo.SampleRate;windowLength=round(0.03*fs);overlapLength=round(0.025*fs);features=[];labels=[];虽然hasdata(adsTrain)[audioIn,dsInfo]=read(adsTrain);melC=mfcc(audioIn,fs,“窗口”,汉明(窗长,“周期性”),“重叠长度”, overlapLength);f0 =音高(audioIn fs,“窗口长度”,窗长,“重叠长度”重叠长度);专长=[melC,f0];voicedSpeech=isVoicedSpeech(音频输入、fs、窗口长度、重叠长度);专长(~voicedSpeech,:)=[];label=repelem(dsInfo.label,大小(专长,1));特征=[特征;专长];标签=[标签,标签];结束

Pitch和MFCC的规模并不相同。这将偏向分类器。通过减去平均值和除以标准差使特征归一化。

M=平均值(特征,1);S=标准值(特征,[],1);特征=(特征-M)。/S;

训练分类器

现在您已经收集了所有10个扬声器的特征,您可以基于它们训练分类器分类器。KNN是一种自然适合于多类分类的分类技术。最近邻分类器的超参数包括最近邻数、用于计算到相邻距离的距离度量以及距离度量的权重。超参数用于优化验证测试集的准确性和性能。在本例中,邻居数设置为5,所选距离的度量为平方逆加权欧氏距离。有关分类器的更多信息,请参阅fitcknn(统计和机器学习工具箱)

训练分类器并打印交叉验证的准确性。克罗斯瓦尔(统计和机器学习工具箱)kfoldLoss(统计和机器学习工具箱)用于计算KNN分类器的交叉验证精度。

指定所有分类器选项并训练分类器。

trainedClassifier = fitcknn (...特征,...标签,...“距离”,“欧几里得”,...“纽曼尼斯堡”5,...“距离重量”,“squaredinverse”,...“标准化”假的,...“类名”独特的(标签));

执行交叉验证。

k = 5;组=标签;c = cvpartition(集团“KFold”,k);%5倍分层交叉验证partitionedModel=crossval(trainedClassifier,“CVPartition”(c);

计算验证精度。

validationAccuracy = 1 - kfoldLoss(partitionedModel,“LossFun”,“ClassifError”);流(“\n验证精度=%.2f%%\n”,验证准确度*100);
验证精度= 97.64%

可视化混乱图表。

validationPredictions=kfoldPredict(partitionedModel);图cm=混淆图(标签、验证预测、,“标题”,“验证准确性”); cm.摘要=“列规格化”;厘米。RowSummary =“row-normalized”

你也可以用the分类学习者(统计和机器学习工具箱)应用程序来尝试和比较各种分类器与您的功能表。

测试分类器

在本节中,您将使用来自10个说话人中每个人的语音信号测试经过训练的KNN分类器,以查看它在未用于训练它的信号中表现得有多好。

读取文件,从测试集中提取特性,并将它们规范化。

特征=[];标签=[];numVectorsPerFile=[];虽然hasdata(adsTest) [audioIn,dsInfo] = read(adsTest);melC = mfcc (audioIn fs,“窗口”,汉明(窗长,“周期性”),“重叠长度”, overlapLength);f0 =音高(audioIn fs,“窗口长度”,窗长,“重叠长度”重叠长度);专长=[melC,f0];voicedSpeech=isVoicedSpeech(音频输入、fs、窗口长度、重叠长度);专长(~voicedSpeech,:)=[];numVec=大小(专长,1);label=repelem(dsInfo.label,numVec);numVectorsPerFile=[numVectorsPerFile,numVec];特征=[特征;专长];标签=[标签,标签];结束特点= (features-M)。/ S;

通过调用预测trainedClassifier

预测=预测(trainedClassifier、特点);预测=分类(string(预测);

可视化混乱图表。

图(“单位”,“归一化”,“位置”,[0.4 0.4 0.4 0.4])cm=混淆图(标签、预测、,“标题”,'测试精度(每帧)'); cm.摘要=“列规格化”;厘米。RowSummary =“row-normalized”

对于给定的文件,将对每一帧进行预测。确定每个文件的预测模式,然后绘制混淆图。

r2 =预测(1:元素个数(adsTest.Files));idx = 1;ii = 1: numVectorsPerFile(ii) = mode(预测(idx:idx+numVectorsPerFile(ii)-1));idx = idx + numVectorsPerFile(ii);结束图(“单位”,“归一化”,“位置”,[0.4 0.4 0.4 0.4])cm=混淆图(adsTest.Labels,r2,“标题”,'测试精度(每个文件)'); cm.摘要=“列规格化”;厘米。RowSummary =“row-normalized”

预测的扬声器与测试中的所有文件的预期扬声器相匹配。

使用内部开发的数据集重复了这个实验。该数据集由20位发言者组成,每个发言者说的多个句子来自哈佛句子列表[2.].对于20位演讲者,验证准确率为89%。

金宝app辅助功能

作用voicedSpeech=isVoicedSpeech(x,fs,windowLength,OverlappLength)pwrThreshold=-40;[segments,~]=buffer(x,windowLength,OverlappLength,“诺德利”); 压水堆=功率2dB(var(分段));isSpeech=(pwr>pwrThreshold);zcrThreshold=1000;zeroLoc=(x==0);crossedZero=逻辑([0;diff(符号(x))]);crossedZero(zeroLoc)=假;[crossedZeroBuffered,~]=缓冲区(crossedZero,windowLength,OverlappedLength,“诺德利”); zcr=(总和(交叉零缓冲,1)*fs)/(2*窗长);isVoiced=(zcr结束

参考文献

CMU Sphinx集团音频数据库。已于2019年12月19日生效。http://www.speech.cs.cmu.edu/databases/an4/。

[2]“哈佛的句子。”维基百科2019年8月27日。维基百科,https://en.wikipedia.org/w/index.php?title=Harvard_sentences&oldid=912785385