主要内容

基于小波散射和深度学习的语音数字识别

这个例子展示了如何使用机器和深度学习技术对语音数字进行分类。在本例中,使用支持向量机(SVM)和长短期记忆(LSTM)网络使用小波时间散射进行分类。金宝app您还可以应用贝叶斯优化来确定合适的超参数,以提高LSTM网络的精度。此外,该示例说明了一种使用深度卷积神经网络(CNN)和梅尔频率谱图的方法。

数据

克隆或下载免费口语数字数据集(FSDD),可在https://github.com/jakobovski/free-spoken-digit-dataset中获得。FSDD是一个打开的数据集,这意味着它可以随着时间的推移而增长。此示例使用2019年1月29日提交的版本,该版本由2000年英文中的2000次录制组成,从四位发言者获得的数字0到9。在这个版本中,两个发言者是美国英语的母语人士,一个发言者是一个与比利时法国口音的英语扬声器,一位发言者是一个德国口音的非英语扬声器。数据以8000 Hz采样。

使用音频数据存储管理数据访问并确保将记录随机划分为训练集和测试集。设置地点例如,您计算机上FSDD录制文件夹的位置:

pathToRecordingsFolder=fullfile(tempdir,'免费口语 -  DataSet-Master',“录音”);位置= pathToRecordingsFolder;

指向音频数据存储去那个地方。

广告= audioDatastore(位置);

辅助功能助手标签从FSDD文件创建标签的分类数组。的源代码助手标签列在附录中。列出每个类中的类和示例的数量。

ads.Labels=帮助标签(ads);摘要(ads.Labels)
0 300 1 300 2 300 3 300 4 300 5 300 6 300 7 300 8 300 9 300

FSDD数据集由10个平衡类组成,每个类有200个记录。FSDD中的记录持续时间不相等。FSDD并不是非常大,因此请通读FSDD文件并构建信号长度的直方图。

LenSig=0(numel(ads.Files),1);nr=1;虽然Hasdata (ads) digit = read(ads);LenSig (nr) =元素个数(数字);nr = nr + 1;终止重置(广告)直方图(LenSig)网格在…上包含('信号长度(样本)')伊拉贝尔(“频率”)

直方图显示记录长度的分布是正偏态的。对于分类,本例使用8192个样本的公共信号长度,这是一个保守值,确保截断较长的录音不会切断语音内容。如果信号长度大于8192个采样点(1.024秒),则记录被截断为8192个采样点。如果信号长度小于8192个采样点,则对信号进行预加并对称地延迟加零至8192个采样点的长度。

小波时间散射

使用waveletScattering(小波工具箱)使用0.22秒的不变比例创建小波时间散射框架。在本例中,通过对所有时间样本的散射变换求平均值来创建特征向量。若要使每个时间窗口的散射系数达到足够的平均值,请设置OversamplingFactor为2,则每条路径的散射系数相对于临界下采样值增加四倍。

科幻小说= waveletScattering (“信号长度”, 8192,“InvarianceScale”, 0.22,...'采样频率',8000,“过采样因子”,2);

将FSDD分为训练集和测试集。将80%的数据分配给训练集,保留20%给测试集。训练数据用于基于散射变换训练分类器。测试数据用于验证模型。

rng默认的;广告= shuffle(广告);[adsTrain, adsTest] = splitEachLabel(广告,0.8);countEachLabel (adsTrain)
ans =.10×2表标签计数uuuuuuuuuuuuuuuuuu0 240 1 240 2 240 3 240 4 240 5 240 6 240 7 240 8 240 9 240
计数标签(adsTest)
ans =.10×2表标签计数_____ _____ 0 60 1 60 2 60 3 60 4 60 5 60 6 60 7 60 8 60 9 60

辅助功能HelperReadsData截断或填充长度为8192的数据,并按其最大值对每个记录进行规范化。的源代码HelperReadsData列在附录中。创建一个8192 × 1600矩阵,其中每一列都是语音数字录音。

Xtrain=[];scatts_Train=transform(adsTrain,@(x)helperReadSPData(x));虽然hasdata(scatts\u Train)smat=读取(scatts\u Train);Xtrain=cat(2,Xtrain,smat);终止

重复测试集的过程。得到的矩阵为8192-by-400。

Xtest=[];scatds_Test=转换(adsTest,@(x)helperReadSPData(x));虽然hasdata(scatts_测试)smat=read(scatts_测试);Xtest=cat(2,Xtest,smat);终止

将小波散射变换应用到训练集和测试集。

应变= sf.featureMatrix (Xtrain);圣= sf.featureMatrix (Xtest);

获取训练集和测试集的平均散射特征。排除零阶散射系数。

列车特征=应变(2:端部,:,:);列车特征=挤压(平均值(列车特征,2));TestFeatures=Stest(2:end,:,:);TestFeatures=挤压(平均值(TestFeatures,2));

支持向量机分类器

现在,每个记录的数据都已缩减为一个特征向量,下一步是使用这些特征对记录进行分类。创建一个具有二次多项式核的SVM学习者模板。将SVM与训练数据相匹配。

template=templateSVM(...“内核函数”,“多项式”,...“PolynomialOrder”2,...'kernelscale',“自动”,...“BoxConstraint”,1...“标准化”,true);classificationSVM=FitCecc(...TrainFeatures,...adsTrain。标签,...“学习者”样板...“编码”,“onevsone”,...“类名”,分类({'0''1''2''3''4''5''6''7''8''9'}));

基于训练数据,使用k-折叠交叉验证预测模型的泛化精度。将训练集分成五组。

partitionedmodel = crossval(分类vm,'kfold'5);[validationPredictions, validationScores] = kfoldPredict(partitionedModel);validationAccuracy = (1 - kfoldLoss(partitionedModel,“LossFun”,“ClassifError”))* 100
validationAccuracy = 97.4167

估计的泛化精度约为97%。使用训练的SVM预测测试集中的发言位类。

predLabels=predict(classificationSVM,TestFeatures);testAccuracy=sum(predLabels==adsTest.Labels)/numel(predLabels)*100
testAccuracy = 97.1667

使用混淆图总结测试集中模型的性能。使用列和行摘要显示每个类别的精度和召回率。混淆图底部的表格显示每个类别的精度值。混淆图右侧的表格显示召回率值。

身材(“单位”,“正常化”,“位置”,[0.2 0.2 0.5 0.5]);ccscat = confusionchart(adstest.labels,predlabels);ccscat.title =.“小波散射分类”;ccscat。ColumnSummary =“列规格化”;ccscat。RowSummary =“row-normalized”

散射变换结合SVM分类器对测试集中的语音数字进行分类,准确率为98%(或2%的错误率)。

长短时记忆(LSTM)网络

LSTM网络是一种复发性神经网络(RNN)。RNN是神经网络,专门用于使用诸如语音数据的顺序或时间数据。因为小波散射系数是序列,所以它们可以用作LSTM的输入。通过使用散射功能而不是原始数据,您可以降低网络需要了解的可变性。

修改用于LSTM网络的训练和测试散射特征。排除零阶散射系数,并将特征转换为单元阵列。

训练=菌株(2:结束,:,:);训练训练=挤压(Num2cell(训练治疗,[1 2]));testfeatures =最好(2:结束,:,:);testfeatures =挤压(Num2cell(Testfeatures,[1 2]));

构建一个具有512个隐藏层的简单LSTM网络。

[inputSize, ~] = size(TrainFeatures{1});YTrain = adsTrain.Labels;numHiddenUnits = 512;numClasses =元素个数(独特(YTrain));层= [...sequenceInputLayer(InputSize)LSTMLAYER(NUMHIDNEDURITS,'OutputMode',“最后”)fullyConnectedLayer(numClasses)softmaxLayer classificationLayer];

设置超参数。使用Adam优化和最小批量大小50。将最大历元数设置为300。使用1e-4的学习速率。如果不想使用绘图跟踪进度,可以关闭培训进度绘图。默认情况下,如果有GPU可用,培训将使用GPU。否则,它将使用CPU。有关更多信息,请参阅see培训选项

maxEpochs = 300;miniBatchSize=50;选项=培训选项('亚当',...“初始学习率”,0.0001,...“MaxEpochs”maxEpochs,...'minibatchsize',小匹马,...“SequenceLength”,“最短”,...'洗牌',“每个时代”,...'verbose', 错误的,...“情节”,“训练进步”);

培训网络。

网= trainNetwork (TrainFeatures、YTrain层,选择);
predLabels =分类(净,TestFeatures);testAccuracy = (predLabels = = adsTest.Labels) /元素个数之和(predLabels) * 100
测试精度=96.3333

贝叶斯优化

确定合适的超参数设置通常是训练深度网络最困难的部分之一。为了缓解这一问题,您可以使用贝叶斯优化。在本例中,您使用贝叶斯技术优化隐藏层的数量和初始学习率。创建一个新目录来存储包含信息的MAT文件有关超参数设置和网络以及相应错误率的说明。

YTrain = adsTrain.Labels;欧美= adsTest.Labels;如果~ (“结果/”,“dir”)MKDIR.结果终止

初始化要优化的变量以及它们的值范围。因为隐藏图层的数量必须是整数,所以“类型”“整数”

Optvars = [优化不变(“初始学习率”,[1e-5,1e-1],“转换”,“日志”)优化变量('numhidendunits',[10, 1000],'类型',“整数”)];

贝叶斯优化是计算密集型的,可能需要几个小时才能完成。对于本示例,请使用setoptimizeCondition错误的下载和使用预先确定的优化超参数设置。如果你设置optimizeCondition符合事实的,目标函数helperBayesOptLSTM使用贝叶斯优化最小化。目标函数,列在附录中,是给定特定超参数设置的网络的错误率。加载设置的目标函数最小值为0.02(2%的错误率)。

ObjFcn=HelperBayesTopLstm(列车特征、YTrain、TestFeatures、YTest);optimizeCondition=false;如果BayesObject = bayesopt(ObjFcn,optVars,...“MaxObjectiveEvaluations”15,...'IsobjectiveDeterministic'错误的...“使用并行”,真正的);其他的url ='http://ssd.mathworks.com/金宝appsupportfiles/audio/SpokenDigitRecognition.zip';downloadNetFolder = tempdir;netFolder = fullfile (downloadNetFolder,'发言人');如果~exist(netFolder,“dir”)disp('下载预训练网络(1文件- 12mb)…')解压缩(URL,DownloadNetFolder)终止load(fullfile(netfolder,“0.02.mat”));终止
正在下载预训练网络(1个文件-12 MB)。。。

如果执行贝叶斯优化,则生成类似于以下内容的数字以跟踪具有相应的超参数值和迭代次数的目标函数值。您可以增加贝叶斯优化迭代的数量,以确保达到目标函数的全局最小值。

使用隐藏单元数和初始学习率的优化值,并重新训练网络。

numHiddenUnits=768;numClasses=numel(唯一(YTrain));层=[...sequenceInputLayer(InputSize)LSTMLAYER(NUMHIDNEDURITS,'OutputMode',“最后”)fullyConnectedLayer(numClasses)softmaxLayer classificationLayer];maxEpochs=300;miniBatchSize=50;options=trainingOptions('亚当',...“初始学习率”,2.198827960269379e-04,...“MaxEpochs”maxEpochs,...'minibatchsize',小匹马,...“SequenceLength”,“最短”,...'洗牌',“每个时代”,...'verbose', 错误的,...“情节”,“训练进步”);网= trainNetwork (TrainFeatures、YTrain层,选择);predLabels =分类(净,TestFeatures);testAccuracy = (predLabels = = adsTest.Labels) /元素个数之和(predLabels) * 100
测试精度=97.5000

随着幽灵节目,使用贝叶斯优化,高精度产生LSTM。

基于Mel频谱图的深卷积网络

作为语音数字识别的另一种方法,使用基于梅尔频谱图的深度卷积神经网络(DCNN)对FSDD数据集进行分类。使用与散射变换相同的信号截断/填充过程。类似地,通过将每个信号样本除以最大绝对值对每个记录进行归一化。为了一致性,使用与散射变换相同的训练和测试集。

设置熔体频谱图的参数。使用相同的窗口或帧,持续时间在散射变换中,0.22秒。将Windows之间的跃点设置为10毫秒。使用40个频段。

分段持续时间=8192*(1/8000);帧持续时间=0.22;跃点持续时间=0.01;数量=40;

重置培训和测试数据存储。

重置(adsTrain);重置(adsTest);

辅助功能助手语音谱图,在本例末尾定义,使用melSpectrogram在记录长度标准化和振幅标准化后获得mel频谱图。使用mel频谱图的对数作为DCNN的输入。为避免取零的对数,在每个元素上添加一个小ε。

epsil = 1 e-6;XTrain = helperspeechSpectrograms (adsTrain segmentDuration、frameDuration hopDuration, numBands);
计算语音频谱图…处理2400个文件中的500个文件处理2400个文件中的1000个文件处理2400个文件中的1500个文件处理2400个文件中的2000个文件…完成
XTrain = log10(Xtrain + Epsil);xtest = elplerspeathspectogregs(adstest,semmenture,frameduration,hopduration,numband);
计算语音谱图……处理了600个文件中的500个…完成了
XTest = log10(XTest + epsil);YTrain = adsTrain.Labels;欧美= adsTest.Labels;

定义DCNN架构

构造一个小的DCNN作为层的数组。使用卷积和批处理归一化层,并使用最大池化层对特征映射进行向下采样。为了减少网络记忆训练数据的特定特征的可能性,在最后一个完全连接层的输入中添加少量的dropout。

sz=尺寸(XTrain);specSize=sz(1:2);imageSize=[specSize 1];numClasses=numel(类别(YTrain));dropoutProb=0.2;numF=12;layers=[imageInputLayer(imageSize)卷积2dLayer(5,numF,'填充',“一样”)batchNormalizationLayer reluLayer MaxPoolig2dLayer(3,“大步走”2,'填充',“一样”)卷积2层(3,2*numF,'填充',“一样”)batchNormalizationLayer reluLayer MaxPoolig2dLayer(3,“大步走”2,'填充',“一样”)卷积2层(3,4*numF,'填充',“一样”)batchNormalizationLayer reluLayer MaxPoolig2dLayer(3,“大步走”2,'填充',“一样”)卷积2层(3,4*numF,'填充',“一样”)batchNormalizationLayer reluLayer卷积2Dlayer(3,4*numF,'填充',“一样”) batchNormalizationLayer reluLayer maxPooling2dLayer(2) dropoutLayer(dropoutProb) fulllyconnectedlayer (numClasses) softmaxLayer classificationLayer(“班级”,分类(YTrain));];

设置用于训练网络的超参数。使用50个小批量和1e-4的学习速率。指定亚当优化。因为本例中的数据量相对较小,所以将执行环境设置为“cpu”您还可以通过将执行环境设置为“图形”“自动”.有关更多信息,请参见培训选项

miniBatchSize=50;选项=培训选项('亚当',...“初始学习率”1的军医,...“MaxEpochs”,30,...'minibatchsize',小匹马,...'洗牌',“每个时代”,...“情节”,“训练进步”,...'verbose'错误的...“执行环境”,“cpu”);

培训网络。

trainedNet = trainNetwork (XTrain、YTrain层,选择);

使用经过训练的网络来预测测试集的数字标签。

[YERPREDITED,PROPS] =分类(TRAIRATIONNET,XTEST,“执行环境”,“CPU”);cnnaccuracy = sum(ypredicted == ytest)/ numel(ytest)* 100
cnnAccuracy = 98.1667

用混淆图总结训练网络在测试集上的性能。通过使用列和行摘要显示每个类的精度和召回率。混淆图底部的表格显示了精度值。混淆图右侧的表格显示了召回值。

身材(“单位”,“正常化”,“位置”,[0.2 0.2 0.5 0.5]);ccDCNN = confusionchart(欧美,Ypredicted);ccDCNN。Title =“DCNN的混淆图”;ccDCNN。ColumnSummary =“列规格化”;ccDCNN。RowSummary =“row-normalized”

使用熔融频谱图的DCNN作为输入对测试集中的口头数字进行了大约98%的准确率。

总结

此示例显示如何使用不同的机器和深度学习方法来对FSDD中的语音数字进行分类。示例说明了与SVM和LSTM配对的小波散射。贝叶斯技术用于优化LSTM HyperParameters。最后,该示例显示了如何使用具有熔体频谱图的CNN。

本示例的目标是演示如何使用MathWorks®工具以根本不同但互补的方式处理问题。所有工作流都使用音频数据存储管理来自磁盘的数据流,并确保适当的随机化。

本例中使用的所有方法在测试集上的表现都相当好。本例不打算在各种方法之间进行直接比较。例如,您也可以在CNN中使用贝叶斯优化进行超参数选择。这是一种额外的策略,在使用小训练集(如本版本)进行深度学习时非常有用FSDD的n是使用数据扩充。操作如何影响类并不总是已知的,所以数据扩充并不总是可行的。然而,对于语音,通过audioDataAugmenter

在小波时间散射的情况下,你也可以尝试一些修改。例如,您可以改变变换的不变尺度,改变每个滤波器组的小波滤波器数量,并尝试不同的分类器。

附录:辅助函数

作用Labels = HelpergenLabels(广告)%此函数仅用于小波工具箱示例。它可能是%在未来的释放中更改或删除。tmp =细胞(元素个数(ads.Files), 1);表达="[0-9]+_"对于nf=1:numel(ads.Files)idx=regexp(ads.Files{nf},表达式);tmp{nf}=ads.Files{nf}(idx);终止标签=分类(tmp);终止
作用x=helperReadSPData(x)%此函数仅供小波工具箱使用示例。它可能会改变%将在未来的版本中被删除。N=努美尔(x);如果N > 8192 x = x(1:8192);elseifN<8192 pad=8192-N;预垫=地板(垫/2);postpad=ceil(pad/2);x=[零(前置,1);x;零(后置,1)];终止x=x./最大值(abs(x));终止
作用x=帮助者YesOptLstm(x_-train,Y_-train,x_-val,Y_-val)%此功能仅在中使用%“与小波散射和深度学习的口语数字识别”%它可能会在将来的版本中更改或删除。x=@valerorfun;作用[valerror,cons,filename] = valerrorfun(Optvars)%%LSTM体系结构[inputSize ~] =大小(X_train {1});numClasses =元素个数(独特(Y_train));层= [...sequenceInputLayer inputSize bilstmLayer (optVars。NumHiddenUnits,'OutputMode',“最后”)%从优化变量中使用隐藏层的数量fullyConnectedLayer(numClasses)softmaxLayer classificationLayer];%训练期间未显示绘图选项=培训选项('亚当',...“初始学习率”,optVars.InitialLearnRate,...%使用优化变量的初始学习率值“MaxEpochs”,300,...'minibatchsize',30,...“SequenceLength”,“最短”,...'洗牌',“永远”,...'verbose', 错误的);%%培训网络net=列车网络(X\u列车、Y\u列车、层、选项);% %训练精度X_val_P = net.classify (X_val);accuracy_training = sum(X_val_P == Y_val)./numel(Y_val);valError = 1 - accuracy_training;%%在结果文件夹中的MAT文件中保存网络和选项以及错误值文件名= fullfile (“结果”num2str (valError) +“.mat”);保存(文件名,“净”,“瓦莱罗”,“选项”)缺点= [];终止%内部函数结束终止外部功能的%结束
作用X=助手语音频谱图(ads、分段持续时间、帧持续时间、跃点持续时间、数字)%此功能仅在中使用%“与小波散射和深度学习的口语数字识别”%它可能会在将来的版本中更改或删除。%%HelperSpeechSpectrams(ads、segmentDuration、frameDuration、hopDuration、Numband)%为数据存储广告中的文件计算语音谱图。% segmentDuration是语音片段的总时长,单位为秒,% frameDuration每个谱图帧的持续时间,hopDuration每个频谱图帧之间的百分比,NumBand数量%频带。disp (“计算语音谱图......”);numHops=ceil((分段持续时间-帧持续时间)/跳持续时间);numFiles=length(ads.Files);X=zero([numBands,numHops,1,numFiles],'单身的');对于i = 1:numfiles [x,Info] =读取(广告);x = normalizeandresize(x);FS = INFO.SAMPLEDE;frameLength = round(框架* fs);hoplength = round(hopduration * fs);spec = melspectroge(x,fs,...'窗户'汉明(frameLength“周期性”),...“OverlapLength”frameLength - hopLength...“FFTLength”, 2048,...“NumBands”numBands,...“FrequencyRange”,[50,4000]);%如果光谱图的宽度小于numHops,则将光谱图放入%X的中间。w =大小(规范,2);地板左= ((numHops-w) / 2) + 1;印第安纳州=左:左+ w1;X(:,印第安纳州,1,i) =规范;如果Mod (i,500) == 0“加工”+ I +“从中删除的文件”+(数字文件)终止终止disp (“……完成”);终止%--------------------------------------------------------------------------作用x=规格化EANDRESIZE(x)%此功能仅在中使用%“与小波散射和深度学习的口语数字识别”%它可能会在将来的版本中更改或删除。N=努美尔(x);如果N > 8192 x = x(1:8192);elseifN<8192 pad=8192-N;预垫=地板(垫/2);postpad=ceil(pad/2);x=[零(前置,1);x;零(后置,1)];终止x=x./最大值(abs(x));终止

版权所有2018,MathWorks公司。

另见

|

相关的话题