主要内容

使用音高和MFCC识别说话人

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

介绍

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

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

用于分类的特征

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

球场

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

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

[audioIn,fs]=音频读取(“Counting-16-44p1-mono-15secs.wav”);twoStart = 110年e3;twoStop = 135年e3;audioIn = audioIn (twoStart: twoStop);timeVector = linspace ((twoStart / fs), (twoStop / fs),元素个数(audioIn));sound(audioIn,fs) figure plot(timeVector,audioIn) axis([(twoStart/fs) (twoStop/fs) -1 1]) ylabel(“振幅”)包含(‘时间’)头衔(“话语-二”

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

窗长=圆形(0.03*fs);重叠长度=圆形(0.025*fs);f0=音高(音频输入,fs,“窗口长度”,窗长,“OverlapLength”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,‘*’) axis([(110e3/fs) (135e3/fs) min(f0) max(f0)]) ylabel(“音高(Hz)”)包含(‘时间’)头衔(“俯仰轮廓”

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

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

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

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

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

voicedSpeech = isSpeech & is浊;

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

f0 (~ voicedSpeech) =南;figure subplot(2,1,1) plot(timeVector,audioIn) axis([(110e3/fs) (135e3/fs) -1 1]) axisylabel (“振幅”)包含(‘时间’)头衔(“话语-二”次要情节(2,1,2)情节(timeVectorPitch f0,‘*’) axis([(110e3/fs) (135e3/fs) min(f0) max(f0)]) ylabel(“音高(Hz)”)包含(‘时间’)头衔(“俯仰轮廓”

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

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

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

虽然MFCC的计算没有严格的标准,但基本步骤由图所示。

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

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

数据集

本例使用CMU鲁棒语音识别组的人口普查数据库(也称为AN4数据库)[1].该数据集包含男性和女性受试者说话的录音和数字。本节中的helper函数为您下载它,并将原始文件转换为FLAC。语音文件根据发言者对应的标签被划分为子目录。如果你无法下载它,你可以加载一个功能表HelperAN4TrainingFeatures.mat然后直接去训练一个分类器部分。这些特征是从同一数据集中提取出来的。

下载并提取10位发言者(5位女性和5位男性)的语音文件到临时目录中HelperAN4Download函数。

dataDir = HelperAN4Download;

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

广告= audioDatastore (dataDir,“IncludeSubfolders”,真的,...“FileExtensions”“.flac”...“LabelSource”“foldernames”
ads = audioDatastore与属性:文件:{'…\涂鸦\AppData\Local\Temp\an4\wav\flacData\fejs\an36-fejs-b.f ac';’……当地\ Temp \ scrawfor \ AppData \ \ an4 \ wav \ flacData \ fejs \ an37-fejs-b.flac”;“…当地\ Temp \ scrawfor \ AppData \ \ an4 \ wav \ flacData \ fejs \ an38-fejs-b。flac的……{'C:\Users\ scrifor \AppData\Local\Temp\an4\wav\flacData'}标签:[fejs;fejs;fejs……alteratefilesystemroots: {} OutputDataType: 'double' SupportedOutputFormats: ["w金宝appav" "flac" "ogg" "mp4" "m4a"] DefaultOutputFormat: "wav"

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
trainDatastoreCount = countEachLabel (adsTrain)
列车数据存储计数=10×2表标签计数u_______;fejs 10 fmjd 10 fsrb 10 ftmj 10 FWX 10 mcen 10 mrcb 10 msjm 10 msjr 10 MSN 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 =圆(0.03 * fs);overlapLength =圆(0.025 * fs);特点= [];标签= [];hasdata(adsTrain) [audioIn,dsInfo] = read(adsTrain);melC = mfcc (audioIn fs,“窗口”汉明(windowLength“周期”),“OverlapLength”, overlapLength);f0 =音高(audioIn fs,“窗口长度”,窗长,“OverlapLength”, overlapLength);壮举= (melC, f0);voicedSpeech = isVoicedSpeech (audioIn fs, windowLength overlapLength);壮举(~ voicedSpeech,:) = [];标签= repelem (dsInfo.Label、尺寸(功绩,1));特点=(功能;壮举);标签=(标签,标签);结束

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

M =意味着(功能,1);S =性病(特性,[],1);特点= (features-M)。/ S;

训练一个分类器

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

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

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

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

执行交叉验证。

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

计算验证精度。

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

可视化混乱图表。

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

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

测试分类器

在本节中,您将使用来自10个发言者的语音信号测试经过训练的KNN分类器,以查看它在使用未用于训练它的信号时表现如何。

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

特点= [];标签= [];numVectorsPerFile = [];hasdata(adsTest) [audioIn,dsInfo] = read(adsTest);melC = mfcc (audioIn fs,“窗口”汉明(windowLength“周期”),“OverlapLength”, overlapLength);f0 =音高(audioIn fs,“窗口长度”,窗长,“OverlapLength”重叠长度);专长=[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.摘要=“column-normalized”;厘米。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.摘要=“column-normalized”;厘米。RowSummary =“row-normalized”

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

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

金宝app支持功能

函数= isVoicedSpeech(x,fs,windowLength,overlapLength) pwrThreshold = -40;(段,~)=缓冲区(x, windowLength overlapLength,“nodelay”);压水式反应堆= pow2db (var(段));isSpeech = (pwr > pwrThreshold);zcrThreshold = 1000;zeroLoc = (x = = 0);crossedZero =逻辑([0;diff(符号(x))));crossedZero (zeroLoc) = false;[crossedZeroBuffered, ~] =缓冲区(crossedZero、windowLength overlapLength,“nodelay”); zcr=(总和(交叉零缓冲,1)*fs)/(2*窗长);isVoiced=(zcr结束

参考文献

[1] “CMU斯芬克斯集团-音频数据库”,于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