主要内容

使用音高和MFCC识别说话人

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

介绍

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

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

用于分类的特征

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

球场

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

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

[audioIn, fs] = audioread(“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(“振幅”)包含(“时间(s)”)标题(的话语——两个

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

windowLength =圆(0.03 * fs);overlapLength =圆(0.025 * fs);f0 =音高(audioIn fs,“WindowLength”windowLength,“OverlapLength”overlapLength,“范围”[50250]);图subplot(2,1,1) plot(timeVector,audioIn) axis([(110e3/fs) (135e3/fs) -1 1]) ylabel(“振幅”)包含(“时间(s)”)标题(的话语——两个) subplot(2,1,2) timeVectorPitch = linspace((twoStart/fs),(twoStop/fs),numel(f0));情节(timeVectorPitch f0,‘*’) axis([(110e3/fs) (135e3/fs) min(f0) max(f0)]) ylabel(“音高(Hz)”)包含(“时间(s)”)标题(“基音轮廓”

球场函数估计每一帧的音调值。然而,音高仅在浊音区域是音源的特征。区分沉默和说话最简单的方法是分析短期力量。如果一个帧的能量高于给定的阈值,则声明该帧为speech。

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 = (sum (crossedZeroBuffered 1) * fs) / (2 * windowLength);is浊= (zcr < zcrThreshold);

结合isSpeechisVoiced确定一个帧是否包含语音。

voicedSpeech = isSpeech & is浊;

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

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

梅尔频率倒频谱系数(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] = splitachlabel (ads,0.8);

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

adsTrain
adsTrain = audioDatastore with properties: Files:{'…\ \涂鸦\AppData\Local\Temp\an4\wav\flacData\fejs\an36-fejs-b.flac';’……当地\ 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: ["金宝appwav" "flac" "ogg" "mp4" "m4a"] DefaultOutputFormat: "wav"
trainDatastoreCount = countEachLabel (adsTrain)
trainDatastoreCount =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] = read(adsTrain);声音(sampleTrain dsInfo.SampleRate)

从列车数据存储中读取数据会推入读取指针,以便您可以遍历数据库。重新设置列车数据存储,将读取指针返回到下面特征提取的起点。

重置(adsTrain)

特征提取

从训练数据存储中对应于发声语音的每一帧中提取基音和MFCC特征。支持函数金宝app,isVoicedSpeech,执行中概述的语音检测基音特征提取的描述

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,“WindowLength”windowLength,“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 (...的特性,...标签,...“距离”“欧几里得”...“NumNeighbors”5,...“DistanceWeight”“squaredinverse”...“标准化”假的,...“类名”独特的(标签));

执行交叉验证。

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

计算验证精度。

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

可视化混乱图表。

validationPredictions = kfoldPredict (partitionedModel);figure cm = confusionchart(标签,验证,预测,“标题”“验证准确性”);厘米。ColumnSummary =“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,“WindowLength”windowLength,“OverlapLength”, overlapLength);壮举= (melC, f0);voicedSpeech = isVoicedSpeech (audioIn fs, windowLength overlapLength);壮举(~ voicedSpeech,:) = [];numVec =大小(功绩,1);标签= repelem (dsInfo.Label numVec);numVectorsPerFile = [numVectorsPerFile, numVec];特点=(功能;壮举);标签=(标签,标签);结束特点= (features-M)。/ S;

通过调用预测每个帧的标签(扬声器)预测trainedClassifier

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

可视化混乱图表。

图(“单位”“归一化”“位置”,[0.4 0.4 0.4]) cm = confusionchart(标签,预测,“标题”“测试准确度(每帧)”);厘米。ColumnSummary =“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 = confusionchart(adsTest。标签,r2,“标题”“测试准确度(每个档案)”);厘米。ColumnSummary =“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 = (sum (crossedZeroBuffered 1) * fs) / (2 * windowLength);is浊= (zcr < zcrThreshold);voicedSpeech = isSpeech & is浊;结束

参考文献

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