主要内容

基于GPU加速的小波时间散射-语音数字识别

这个例子展示了如何使用加速小波散射特征的计算gpuArray(并行计算工具箱).您必须有并行计算工具箱™和支持的GPU。看到GPU计算的需求(并行计算工具箱)获取详细信息。本例使用了具有7.0计算能力的NVIDIA Titan V GPU。该示例中计算散射变换的部分提供了使用GPU或CPU的选项,如果您希望比较GPU和CPU的性能。

这个例子再现了在中找到的散射变换的专属CPU版本基于小波散射和深度学习的语音数字识别

数据

克隆或下载自由语音数字数据集(FSDD),可在https://github.com/Jakobovski/free-spoken-digit-dataset.FSDD是一个开放数据集,这意味着它可以随着时间的推移而增长。这个例子使用的是2020年8月20日提交的版本,包含3000个从6个说话者那里获得的英语数字0到9的录音。数据采样频率为8000hz。

使用audioDatastore管理数据访问,确保记录随机划分为训练集和测试集。设置位置属性设置为您计算机上FSDD录音文件夹的位置。在本例中,数据存储在下面的文件夹中tempdir

位置= fullfile (tempdir,“free-spoken-digit-dataset”“录音”);广告= audioDatastore(位置);

辅助功能,helpergenLabels的定义,它从FSDD文件创建标签的分类数组。列出类和每个类的例子数量。

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个平衡类组成,每个类有300个记录。FSDD中的记录不具有相等的持续时间。通读FSDD文件并构建信号长度的直方图。

LenSig = 0(元素个数(ads.Files), 1);nr = 1;Hasdata (ads) digit = read(ads);LenSig (nr) =元素个数(数字);nr = nr + 1;结束重置(广告)直方图(LenSig)网格包含(的信号长度(样本)) ylabel (“频率”

直方图显示记录长度的分布呈正偏态。为了分类,本例使用了8192个样本的公共信号长度。值8192是一个保守的选择,它确保截断较长的录音不会影响(切断)语音内容。如果信号长度大于8192个样本,即1.024秒,则记录被截断为8192个样本。如果信号长度小于8192个样本,则该信号被对称地预先加上0,其长度为8192个样本。

小波时间散射

使用0.22秒的不变尺度创建一个小波时间散射网络。因为特征向量将通过所有时间样本的散射变换的平均值来创建,所以设置OversamplingFactor2。将该值设置为2将导致相对于临界下采样值,每条路径的散射系数数量增加4倍。

sn = waveletScattering (“SignalLength”, 8192,“InvarianceScale”, 0.22,...“SamplingFrequency”, 8000,“OversamplingFactor”2);

通过对散射网络的设置,得到326条路径。您可以用下面的代码来验证这一点。

[~, npaths] =路径(sn);总和(npaths)
ans = 326

将FSDD分成训练集和测试集。分配80%的数据给训练集,保留20%的数据给测试集。训练数据用于训练基于散射变换的分类器。测试数据用于评估模型泛化到不可见数据的能力。

rng默认的;广告= shuffle(广告);[adsTrain, adsTest] = splitEachLabel(广告,0.8);总结(adsTrain.Labels)
0 240 1 240 2 240 3 240 4 240 5 240 6 240 7 240 8 240 9 240
总结(adsTest.Labels)
0 60 1 60 2 60 3 60 4 60 5 60 6 60 7 60 8 60 9 60

形成一个8192 × 2400的矩阵,其中每一列都是一个语音数字记录。辅助函数helperReadSPData将数据截断或填充为8192的长度,并按其最大值规范化每个记录。helper函数将数据转换为单一精度。

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

对hold out测试集重复此过程。得到的矩阵是8192 × 600。

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

将散射变换应用于训练集和测试集。将训练和测试数据集移动到所使用的GPUgpuArray.的使用gpuArray与cuda支持的NVIDIA GPU提供了显著的加速。有了这个散射网络、批处理大小和GPU, GPU实现计算散射特征的速度大约是CPU版本的15倍。如果您不希望使用该图形处理器,请设置useGPU.的值也可以交替useGPU比较GPU和CPU的性能。

useGPU =真正的如果useGPU Xtrain = gpuArray(Xtrain);应变= sn.featureMatrix (Xtrain);Xtrain =收集(Xtrain);Xtest = gpuArray (Xtest);圣= sn.featureMatrix (Xtest);Xtest =收集(Xtest);其他的应变= sn.featureMatrix (Xtrain);圣= sn.featureMatrix (Xtest);结束

获得训练集和测试集的散射特征。

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

本例使用一个具有二次多项式核的支持向量机(SVM)分类器。根据散射特征拟合SVM模型。

模板= templateSVM (...“KernelFunction”多项式的...“PolynomialOrder”2,...“KernelScale”“汽车”...“BoxConstraint”, 1...“标准化”,真正的);classificationSVM = fitcecoc (...TrainFeatures,...adsTrain。标签,...“学习者”模板,...“编码”“onevsone”...“类名”分类({' 0 '' 1 '' 2 '“3”“4”“5”“6”“7”“8”“9”}));

使用k-fold交叉验证来预测模型的泛化精度。将训练集分成五组进行交叉验证。

partitionedModel = crossval (classificationSVM,“KFold”5);[validationforecasts, validationScores] = kfoldPredict(partitionedModel);validationAccuracy = (1 - kfoldLoss(partitionedModel,“LossFun”“ClassifError”)) * 100
validationAccuracy = 97.2500

估计的泛化精度约为97%。现在使用支持向量机模型来预测hold -out测试集。

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

在hold out测试集上,精确度也约为97%。

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

图(“单位”“归一化”“位置”,[0.2 0.2 0.5 0.5]);ccscat = confusionchart (adsTest.Labels predLabels);ccscat。Title =“小波散射分类”;ccscat。ColumnSummary =“column-normalized”;ccscat。RowSummary =“row-normalized”

作为最后一个例子,从数据集中读取前两个记录,计算散射特征,并使用散射特征训练的支持向量机预测语音数字。

重置(广告);sig1 = helperReadSPData(阅读(广告);scat1 = sn.featureMatrix (sig1);scat1 =意味着(scat1 (2:,:), 2) ';plab1 =预测(classificationSVM scat1);

阅读下一条记录并预测数字。

sig2 = helperReadSPData(阅读(广告);scat2 = sn.featureMatrix (sig2);scat2 =意味着(scat2 (2:,:), 2) ';plab2 =预测(classificationSVM scat2);
t = 0:1/8000: -1/8000(即:8192 * 1/8000);情节(t) [sig1 sig2])网格传奇(char (plab1), char (plab2))标题(“语音数字预测- GPU”

附录

本例中使用了以下helper函数。

helpergenLabels—根据FSDD中的文件名生成标签。

函数标签= helpergenLabels(广告)此函数仅在小波工具箱示例中使用。它可能是%在将来的版本中更改或删除。tmp =细胞(元素个数(ads.Files), 1);表达=“[0 - 9]+ _”nf = 1:numel(ads.Files) idx = regexp(ads.Files{nf},expression);tmp {nf} = ads.Files {nf} (idx);结束标签=分类(tmp);结束

helperReadSPData-确保每个语音数字录音长度为8192个样本。

函数x = helperReadSPData (x)此函数仅用于使用小波工具箱的示例。它可能会改变%将在未来的版本中删除。N =元素个数(x);如果N > 8192 x = x(1:8192);elseifN < 8192 pad = 8192-N;前置液=地板(垫/ 2);postpad =装天花板(垫/ 2);X = [0 (prepad,1);x;0 (postpad 1)];结束x =单(x / max (abs (x)));结束

另请参阅

相关的例子

更多关于

Baidu
map