主要内容

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

此示例显示如何使用机器和深度学习技术进行分类说话的数字。在该示例中,使用使用支持向量机(SVM)和长短期存储器(LSTM)网络来执行使用小波时间散射进行分类。万博1manbetx您还应用贝叶斯优化来确定合适的超参数,以提高LSTM网络的准确性。另外,该示例说明了使用深卷积神经网络(CNN)和熔融频谱图的方法。

数据

克隆或下载免费语音数字数据集(FSDD),可于https://github.com/Jakobovski/free-spoken-digit-dataset. FSDD是一个开放的数据集,这意味着它可以随着时间的推移而增长。本例使用2019年1月29日提交的版本,该版本包含2000条从四位发言者处获得的数字0到9的英语录音。在此版本中,两位发言者是本机sp说美式英语的人中,有一个说英语的非本族语者带有比利时法语口音,还有一个说英语的非本族语者带有德国口音。数据采样频率为8000 Hz。

使用audioDatastore管理数据访问并确保录制的随机分为培训和测试集。设定地方属性设置为计算机上FSDD recordings文件夹的位置,例如:

pathToRecordingsFolder = fullfile (tempdir,“自由语音数字数据集主机”“录音”);位置= PathtoreCordingsFolder;

audioDatastore到新位置。

广告= audiodatastore(位置);

辅助函数helpergenLabels从FSDD文件创建标签的分类数组helpergenLabels在附录中列出。列出每门课的类别和示例数量。

ads.Labels = helpergenLabels(广告);总结(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(元素个数(ads.Files), 1);nr = 1;hasdata(ads)数字=读取(ads);LenSig(nr)=numel(数字);nr=nr+1;结束重置(广告)直方图(Lensig)网格Xlabel(的信号长度(样本)) ylabel (“频率”

直方图显示记录长度的分布正倾斜。对于分类,此示例使用8192个样本的公共信号长度,这是一个保守值,可确保截断较长的记录不会切断语音内容。如果信号大于8192个样本(1.024秒)在长度上,记录被截断为8192个样本。如果信号长度小于8192个样本,则信号被对称地预加和后加,零输出的长度为8192个样本。

小波时间散射

使用小波发生器(小波工具箱)使用0.22秒的不变尺度创建小波时间散射框架。在本例中,通过对所有时间样本的散射变换进行平均来创建特征向量。为了使每个时间窗口有足够的散射系数的平均数,设置过度采伐物料到2,使每条路径的散射系数数量相对于临界下采样值增加四倍。

SF =小波示踪剂(“SignalLength”8192,“不变性刻度”,0.22,...“采样频率”, 8000,“OversamplingFactor”2);

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

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

辅助函数helperReadSPData将数据截断或填充到8192的长度,并按其最大值对每个记录进行规范化helperReadSPData在附录中列出。创建一个8192-by-1600矩阵,其中每列是发言的录制。

Xtrain = [];scatds_Train =变换(adsTrain @ (x) helperReadSPData (x));hasdata(scatds_Train) smat = read(scatds_Train);Xtrain =猫(2 Xtrain smat);结束

对测试集重复此过程。生成的矩阵为8192-x-400。

Xtest = [];scatds_Test =变换(adsTest @ (x) helperReadSPData (x));hasdata(scatds_Test) smat = read(scatds_Test);Xtest =猫(2 Xtest smat);结束

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

应变=sf.特征矩阵(Xtrain);应力=sf.特征矩阵(Xtest);

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

TrainFeatures =应变(2:,:,);TrainFeatures =挤压(平均(TrainFeatures, 2))的;TestFeatures =圣(2:,:,);TestFeatures =挤压(平均(TestFeatures, 2))的;

支持向量机分类器

现在数据已经被简化为每个记录的特征向量,下一步是使用这些特征对记录进行分类。创建一个二次多项式核的支持向量机学习模板。将支持向量机与训练数据进行拟合。

模板= templateSVM (...“KernelFunction”多项式的...“多项式序”2....“内核尺度”“汽车”...“BoxConstraint”1....'标准化',真正的);classificationSVM = fitcecoc (...训练疗法,...adstrain.labels,...“学习者”模板,...“编码”“一对一”...'classnames',分类的({' 0 '' 1 '' 2 '“3”“4”“5”“6”“7”“8”“9”}));

利用k-fold交叉验证,根据训练数据预测模型的泛化精度。将训练组分成五组。

partitionedModel=crossval(classificationSVM,“KFold”5);[验证预期,验证算法] = kfoldpredict(partitionedmodel);ValidationAccuracy =(1  -  Kfoldloss(PartitionedModel,“LossFun”“ClassifError”))*100
验证准确性=97.4167

估计的泛化精度约为97%。使用训练好的支持向量机预测测试集中的语音数字类。

predLabels =预测(classificationSVM TestFeatures);testAccuracy = (predLabels = = adsTest.Labels) /元素个数之和(predLabels) * 100
testaccuracy = 97.1667

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

图('单位'“归一化”'位置',[0.2 0.2 0.5 0.5]);ccscat=混淆图(adsTest.Labels,predLabels);ccscat.Title='小波散射分类';ccscat.columnsummary =“column-normalized”;ccscat.row摘要='行标准化'

耦合的散射变换与SVM分类器进行了测试集中的口头数字,精度为98%(或2%的错误率)。

长短期记忆(LSTM)网络

LSTM网络是一种递归神经网络(RNN).RNN是专门用于处理顺序或时间数据(如语音数据)的神经网络。由于小波散射系数是序列,因此可以将其用作LSTM的输入。通过使用与原始数据相反的散射特征,可以减少网络需要学习的可变性。

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

列车特征=应变(2:端部,:,:);TrainFeatures=挤压(num2单元(TrainFeatures[1,2]);TestFeatures=Stest(2:end,:,:);TestFeatures=挤压(num2cell(TestFeatures,[12]));

用512个隐藏层构造一个简单的LSTM网络。

[inputSize,~]=size(TrainFeatures{1});YTrain=adsTrain.Labels;numHiddenUnits=512;numClasses=numel(unique(YTrain));层=[...sequenceInputLayer(inputSize)lstmLayer(numHiddenUnits,“输出模式”“最后一次”) fulllyconnectedlayer (numClasses) softmaxLayer classificationLayer;

设置hyperparameters。使用Adam优化和50个小批量。设置最大周期数为300。使用1e-4的学习速率。如果不想使用图表跟踪进度,可以关闭培训进度图。训练默认使用GPU(如果有的话)。否则,使用CPU。有关更多信息,请参见trainingOptions(深度学习工具箱)

maxEpochs = 300;miniBatchSize = 50;选择= trainingOptions (“亚当”...“InitialLearnRate”, 0.0001,...“MaxEpochs”,maxEpochs,...“MiniBatchSize”,小匹马,...“SequenceLength”“最短”...“洗牌”“every-epoch”...“冗长”错误的...“阴谋”“培训进度”);

培训网络。

net=列车网络(列车特征、列车、图层、选项);
predLabels=Classification(net,TestFeatures);testAccuracy=sum(predLabels==adsTest.Labels)/numel(predLabels)*100
testAccuracy = 96.3333

贝叶斯优化

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

Ytrain = adstrain.labels;ytest = adstest.labels;如果~存在(“结果/”'dir')mkdir后果结束

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

optVars=[optimizableVariable(“InitialLearnRate”(1 e-5, 1 e 1),'转变'“日志”) optimizableVariable (“NumHiddenUnits”(1000),“类型”'整数') ];

贝叶斯优化是计算密集型的,可能需要几个小时才能完成优化条件下载和使用预定的优化的超参数设置。如果你设置了优化条件真正的,目标函数Helperbayesoptlstm.使用贝叶斯优化最小化。附录中列出的目标函数是网络给定特定的HyperParameter设置的错误率。加载的设置用于目标函数最小值为0.02(2%错误率)。

ObjFcn = helperBayesOptLSTM (TrainFeatures YTrain TestFeatures,欧美);optimizeCondition = false;如果optimizeCondition BayesObject=bayesopt(对象JFCN、optVars、,...“MaxObjectiveEvaluations”,15,...“等射确定性”假的,...“UseParallel”,对);其他的URL =.“http://ssd.mathworks.com/万博1manbetxsupportfiles/audio/SpokenDigitRecognition.zip”;downloadNetFolder=tempdir;netFolder=fullfile(downloadNetFolder,“SpokenDigitRecognition”);如果~存在(netFolder'dir') disp ('下载掠夺网络(1文件 -  12 MB)...')解压缩(url,下载NetFolder)结束加载(完整文件)(netFolder,“0.02.mat”));结束
下载预训练网络(1文件- 12mb)…

如果执行贝叶斯优化,将生成与以下类似的图,以跟踪目标函数值以及相应的超参数值和迭代次数。您可以增加贝叶斯优化迭代次数,以确保达到目标函数的全局最小值。

利用优化后的隐藏单元数和初始学习率,对网络进行再训练。

numHiddenUnits = 768;numClasses =元素个数(独特(YTrain));层= [...sequenceInputLayer(inputSize)lstmLayer(numHiddenUnits,“输出模式”“最后一次”) fulllyconnectedlayer (numClasses) softmaxLayer classificationLayer;maxEpochs = 300;miniBatchSize = 50;选择= trainingOptions (“亚当”...“InitialLearnRate”,2.198827960269379e-04,...“MaxEpochs”,maxEpochs,...“MiniBatchSize”,小匹马,...“SequenceLength”“最短”...“洗牌”“every-epoch”...“冗长”错误的...“阴谋”“培训进度”); net=列车网络(列车特征、列车、图层、选项);predLabels=分类(网络、测试特征);testAccuracy=sum(predLabels==adsTest.Labels)/numel(predLabels)*100
testAccuracy = 97.5000

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

使用梅尔频率谱图的深度卷积网络

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

设置mel频谱图的参数。使用与散射变换相同的窗口或帧,持续时间为0.22秒。将窗口之间的跳数设置为10毫秒。使用40个频带。

segmentDuration = 8192 * (1/8000);frameDuration = 0.22;hopDuration = 0.01;numBands = 40;

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

重置(adstrain);重置(adstest);

辅助函数helperspeechSpectrograms的定义,使用光谱图对记录长度进行标准化,对振幅进行标准化,得到梅尔频谱图。使用梅尔-频率谱图的对数作为输入到DCNN。为了避免对0取对数,在每个元素上加一个小的。

epsil=1e-6;XTrain=helperspeechSpectrograms(adsTrain、segmentDuration、frameDuration、hopDuration、numBands);
计算语音谱图……处理了500个文件2400个处理了1000个文件2400个处理了1500个文件2400个处理了2000个文件2400个…完成了
XTrain=log10(XTrain+epsil);XTest=帮助者语音频谱图(adsTest、segmentDuration、frameDuration、hopDuration、Numband);
计算语音频谱图…处理600个文件中的500个…完成
xtest = log10(xtest + epsil);Ytrain = adstrain.labels;ytest = adstest.labels;

定义DCNN体系结构

将小DCNN构造为层数组。使用卷积和批量归一化层,并使用MAX池层下映射特征映射。为了减少网络记忆训练数据的特定功能的可能性,将少量丢失添加到最后一个完全连接的图层。

深圳=大小(XTrain);specSize =深圳(1:2);imageSize = [specSize 1];numClasses =元素个数(类别(YTrain));dropoutProb = 0.2;numF = 12;[imageInputLayer(imageSize)卷积2dlayer (5,numF,“填充”“相同”maxPooling2dLayer(3,“步”2,“填充”“相同”) convolution2dLayer (3 2 * numF“填充”“相同”maxPooling2dLayer(3,“步”2,“填充”“相同”) convolution2dLayer(3、4 * numF,“填充”“相同”maxPooling2dLayer(3,“步”2,“填充”“相同”) convolution2dLayer(3、4 * numF,“填充”“相同”) batchNormalizationLayer reluLayer卷积2dlayer (3,4*numF,“填充”“相同”)BatchnormalizationLayer rululayer maxpooling2dlayer(2)oploutlayer(dropoutprob)全连接列(numclasses)softmaxlayer类层(“类”,类别(YTrain));];

设置用于训练网络的超参数。使用50的最小批量和1e-4的学习率。指定Adam优化。由于本例中的数据量相对较小,请将执行环境设置为“cpu”再现性。你也可以在可用的GPU上通过设置执行环境来训练网络'GPU'“汽车”。有关详细信息,请参阅trainingOptions(深度学习工具箱)

miniBatchSize = 50;选择= trainingOptions (“亚当”...“InitialLearnRate”,1e-4,...“MaxEpochs”30岁的...“MiniBatchSize”,小匹马,...“洗牌”“every-epoch”...“阴谋”“培训进度”...“冗长”假的,...“ExecutionEnvironment”“cpu”);

培训网络。

trainedNet=列车网络(XTrain、YTrain、图层、选项);

使用培训的网络预测测试集的数字标签。

[Ypredicted,probs]=分类(trainedNet,XTest,“ExecutionEnvironment”“CPU”);cnnAccuracy=sum(yppredicted==YTest)/numel(YTest)*100
cnnAccuracy=98.1667

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

图('单位'“归一化”'位置',[0.2 0.2 0.5 0.5]);ccdcnn = confusionchart(ytest,ypreedicte);ccdcnn.title =“DCNN的困惑图”;ccdcnn.columnsummary =“column-normalized”;ccDCNN.row摘要='行标准化'

DCNN使用mel频谱图作为输入,对测试集中的语音数字进行分类,准确率约为98%。

概括

本例展示了如何使用不同的机器和深度学习方法对FSDD中的语音数字进行分类。本例展示了小波散射与SVM和LSTM的结合。贝叶斯技术用于优化LSTM超参数。最后,本例展示了如何使用CNN和mel频谱图。

这个示例的目的是演示如何使用MathWorks®工具以完全不同但互补的方式解决问题。所有工作流使用audioDatastore管理来自磁盘的数据流并确保正确随机化。

本例中使用的所有方法在测试集中的表现都一样好。本示例并不是要对各种方法进行直接比较。例如,您还可以在CNN中使用贝叶斯优化来进行超参数选择。在使用类似这个版本的FSDD的小型训练集进行深度学习时,另一个有用的策略是使用数据增强。操作如何影响类并不总是已知的,因此数据扩充并不总是可行的。然而,对于语音,已建立的数据增强策略可以通过音频数据增强器

在小波时间散射的情况下,您还可以尝试进行许多修改。例如,您可以更改变换的不变尺度,改变每个滤波器库的小波滤波器的数量,并尝试不同的分类器。

附录:辅助函数

函数标签=帮助标签(ads)%此函数仅用于小波工具箱示例。它可能是%在将来的版本中更改或删除。tmp=单元格(numel(ads.Files),1);表达式=“[0 - 9]+ _”nf = 1:numel(ads.Files) idx = regexp(ads.Files{nf},expression);tmp {nf} = ads.Files {nf} (idx);结束标签=分类(tmp);结束
函数x = helperReadSPData (x)%此函数仅适用于使用小波工具箱示例。它可能会改变或%在将来的释放中删除。N =元素个数(x);如果n> 8192 x = x(1:8192);埃尔塞夫N < 8192 pad = 8192-N;前置液=地板(垫/ 2);postpad =装天花板(垫/ 2);X = [0 (prepad,1);x;0 (postpad 1)];结束x = x / max (abs (x));结束
函数x = helperBayesOptLSTM(X_train, Y_train, X_val, Y_val)该函数仅用于%“基于小波散射和深度学习的语音数字识别”%的例子。它可能会在未来的版本中更改或删除。x = @valErrorFun;函数[valeror,cons,fileName]=valerorfun(optVars)% % LSTM架构[inputSize,~]=大小(X_列{1});numClasses=numel(唯一(Y_列));层=[...sequenceInputLayer(InputSize)BilstMlayer(Optvars.numhidendunits,“输出模式”“最后一次”%使用Hyment Tallers值数从优化变量进行fullyConnectedLayer (numClasses) softmaxLayer classificationLayer];%训练期间未显示绘图选择= trainingOptions (“亚当”...“InitialLearnRate”, optVars。InitialLearnRate,...%利用优化变量的初始学习率值“MaxEpochs”, 300,...“MiniBatchSize”30岁的...“SequenceLength”“最短”...“洗牌”“从来没有”...“冗长”,假);训练网络net = trainNetwork(X_train, Y_train, layers, options);%%训练准确性X_val_P=净分类(X_val);精度训练=总和(X_val_P==Y_val)。/numel(Y_val);valeror=1-精度训练;%%将网络结果和选项与错误值一起保存在结果文件夹中的MAT文件中filename = fullfile(“结果”,num2str(valerror)+“.mat”);保存(文件名,“净”“valError”'选项')cons=[];结束% end用于内部函数结束%外部功能结束
函数X = helperspeechSpectrograms(广告、segmentDuration frameDuration、hopDuration numBands)该函数仅用于%“基于小波散射和深度学习的语音数字识别”%的例子。它可能会在未来的版本中更改或删除。% helperspeechSpectrograms(广告、segmentDuration frameDuration、hopDuration numBands)%为数据存储ads中的文件计算语音频谱图。%segmentDuration是语音片段的总持续时间(以秒为单位),%frameDuration每个光谱图帧的持续时间,hopDuration%每个谱图帧之间的时间偏移,以及%频段。DISP(“计算语音频谱图…”);numHops = ceil((segmentDuration - frameeduration)/hopDuration);numFiles =长度(ads.Files);X = 0 ([numBands numHops 1, numFiles],“单身”);i=1:numFiles[x,info]=read(ads);x=normalizeAndResize(x);fs=info.SampleRate;frameLength=round(frameDuration*fs);hopLength=round(hopDuration*fs);spec=melSpectrogram(x,fs,...“窗口”,汉明(FrameLength,“周期”),...“重叠长度”,frameLength  -  HopLength,...“FFTLength”,2048年,...'numbands',numband,...'频率范围'[4000]);%如果声谱图小于numHops,则输入声谱图X的中间。w=尺寸(规格,2);左=楼层((numHops-w)/2)+1;ind=左:左+w-1;X(:,ind,1,i)=规格;如果模(i,500)=0显示(“处理 ”+我+“文件用完了”+ numFiles)结束结束DISP(“…”);结束%---------------------------------------------------------------------函数x = normalizeAndResize (x)该函数仅用于%“基于小波散射和深度学习的语音数字识别”%的例子。它可能会在未来的版本中更改或删除。N =元素个数(x);如果n> 8192 x = x(1:8192);埃尔塞夫N < 8192 pad = 8192-N;前置液=地板(垫/ 2);postpad =装天花板(垫/ 2);X = [0 (prepad,1);x;0 (postpad 1)];结束x = x / max (abs (x));结束

版权所有2018,The MathWorks, Inc.