本例使用转换后的数据存储在内存不足的听觉频谱图上训练语音数字识别网络。在本例中,您使用以下方法从音频中提取听觉谱图audioDatastore
而且audioFeatureExtractor
,然后把它们写到磁盘上。然后使用signalDatastore
在训练期间访问特征。当训练特征不适合内存时,工作流是有用的。在这个工作流中,您只提取一次特征,如果您正在迭代深度学习模型设计,这将加快您的工作流。
下载免费语音数字数据集(FSDD)。FSDD由4位说话者用英语说数字0到9的2000份录音组成。
url =“https://ssd.mathworks.com/金宝appsupportfiles/audio/FSDD.zip”;downloadFolder = tempdir;datasetFolder = fullfile(下载文件夹,“FSDD”);如果~存在(datasetFolder“dir”) disp (“下载FSDD…”解压缩(url, downloadFolder)结束
创建一个audioDatastore
这就指向了数据集。
pathToRecordingsFolder = fullfile(数据文件夹,“录音”);location = pathToRecordingsFolder;ads = audioDatastore(location);
辅助函数,helperGenerateLabels
,从FSDD文件创建标签的分类数组。的源代码helperGenerateLabels
在附录中列出。显示类和每个类中的示例数量。
ads. labels = helperGenerateLabels(广告);
使用“本地”配置文件启动并行池(parpool)…连接到并行池(工人数:8)。
总结(ads.Labels)
0 200 1 200 2 200 3 200 4 200 5 200 6 200 7 200 8 200 9 200
将FSDD分为训练集和测试集。将80%的数据分配给训练集,并保留20%的数据给测试集。您使用训练集来训练模型,使用测试集来验证训练后的模型。
rng默认的广告= shuffle(广告);[adsTrain,adsTest] = splitEachLabel(ads,0.8);countEachLabel (adsTrain)
ans =10×2表标签计数_____ _____ 0 160 1 160 2 160 3 160 4 160 5 160 6 160 7 160 8 160 9 160
countEachLabel (adsTest)
ans =10×2表标签计数_____ _____ 0 40 1 40 2 40 3 40 4 40 5 40 6 40 7 40 8 40 9 40
为了用整个数据集训练网络并达到尽可能高的精度,设置reduceDataset
为假。要快速运行此示例,请设置reduceDataset
为true。
reduceDataset =“假”;如果reduceDataset = =“真正的”adsTrain = splitEachLabel(adsTrain,2);adsTest = splitEachLabel(adsTest,2);结束
CNN接受mel频率谱图。
定义用于提取梅尔频率谱图的参数。使用220毫秒的窗口和10毫秒的窗口之间的跳跃。使用2048点DFT和40个频段。
Fs = 8000;frameDuration = 0.22;hopDuration = 0.01;参数个数。segmentLength = 8192;segmentDuration = params.segmentLength*(1/fs);参数个数。numHops = ceil((segmentDuration-frameDuration)/hopDuration);参数个数。numBands = 40; frameLength = round(frameDuration*fs); hopLength = round(hopDuration*fs); fftLength = 2048;
创建一个audioFeatureExtractor
对象从输入音频信号中计算梅尔频率谱图。
afe = audioFeatureExtractor(“melSpectrum”,真的,“SampleRate”fs);afe。窗口= hamming(frameLength,“周期”);afe。OverlapLength = frameLength-hopLength;afe。FFTLength = FFTLength;
设置mel-frequency谱图参数。
setExtractorParams (afe“melSpectrum”,“NumBands”params.numBands,“FrequencyRange”(50 fs / 2),“WindowNormalization”,真正的);
创建一个转换后的数据存储,从音频数据中计算梅尔频率谱图。辅助函数,getSpeechSpectrogram
(见附录),使录音长度标准化,并使音频输入的振幅标准化。getSpeechSpectrogram
使用audioFeatureExtractor
对象afe
获得基于对数的mel频率谱图。
adsSpecTrain = transform(adsTrain,@(x)getSpeechSpectrogram(x,afe,params));
使用writeall
将听觉频谱图写入磁盘。集UseParallel
为true时执行并行写入。
writeall (adsSpecTrain pwd,“WriteFcn”@myCustomWriter,“UseParallel”,真正的);
创建一个signalDatastore
这就指向了内存不足的特性。自定义读取函数返回频谱图/标签对。
数据存储(“录音”,“ReadFcn”, @myCustomRead);
验证数据集适合内存,您可以使用helper函数预计算验证特性getValidationSpeechSpectrograms
(见附录)。
XTest = getValidationSpeechSpectrograms(adsTest,afe,params);
获取验证标签。
YTest = adsTest.Labels;
构造一个小的CNN作为一个层数组。使用卷积和批处理归一化层,并使用最大池化层对特征映射进行下采样。为了降低网络记忆训练数据特定特征的可能性,在最后一个全连接层的输入中加入少量的dropout。
sz = size(XTest);specSize = sz(1:2);imageSize = [specSize 1];numClasses = numel(类别(YTest));dropoutProb = 0.2;numF = 12;图层= [imageInputLayer(imageSize,“归一化”,“没有”numF) convolution2dLayer(5日,“填充”,“相同”maxPooling2dLayer(3,“步”,2,“填充”,“相同”) convolution2dLayer (3 2 * numF“填充”,“相同”maxPooling2dLayer(3,“步”,2,“填充”,“相同”) convolution2dLayer(3、4 * numF,“填充”,“相同”maxPooling2dLayer(3,“步”,2,“填充”,“相同”) convolution2dLayer(3、4 * numF,“填充”,“相同”(3,4*numF,“填充”,“相同”) batchNormalizationLayer reluLayer maxPooling2dLayer(2) dropoutLayer(dropoutProb) fullyConnectedLayer(numClasses) softmaxLayer classificationLayer(“类”类别(欧美));];
设置用于训练网络的超参数。使用50个小批大小和1e-4的学习率。指定的亚当
的优化。若要使用并行池读取转换后的数据存储,请设置DispatchInBackground
来真正的
.有关更多信息,请参见trainingOptions
(深度学习工具箱).
miniBatchSize = 50;选项= trainingOptions(“亚当”,...“InitialLearnRate”1的军医,...“MaxEpochs”30岁的...“LearnRateSchedule”,“分段”,...“LearnRateDropFactor”、1。...“LearnRateDropPeriod”15岁的...“MiniBatchSize”miniBatchSize,...“洗牌”,“every-epoch”,...“阴谋”,“训练进步”,...“详细”假的,...“ValidationData”{XTest,欧美},...“ValidationFrequency”、装天花板(元素个数(adsTrain.Files) / miniBatchSize),...“ExecutionEnvironment”,“图形”,...“DispatchInBackground”,真正的);
通过将训练数据存储传递给来训练网络trainNetwork
.
trainedNet = trainNetwork(sds,layers,options);
使用训练好的网络预测测试集的数字标签。
[ypredict,probs] = category (trainedNet,XTest);cnnAccuracy = sum(yexpected ==YTest)/ nummel (YTest)*100
cnnAccuracy = 97
用混淆图总结训练网络在测试集上的性能。通过使用列和行摘要显示每个类的精度和召回率。混淆图底部的表格显示了精度值。混淆图右侧的表格显示召回值。
图(“单位”,“归一化”,“位置”,[0.2 0.2 1.5 1.5]);ccDCNN =混淆图(YTest, yexpected);ccDCNN。Title =“DCNN的困惑表”;ccDCNN。ColumnSummary =“column-normalized”;ccDCNN。RowSummary =“row-normalized”;
函数标签= helperGenerateLabels(广告)此函数仅在本例中使用。它可能被改变或%将在将来的版本中删除。files = ads.Files;TMP = cell(numel(files),1);表达=“[0 - 9]+ _”;parfornf = 1: number (ads.Files) idx = regexp(files{nf},表达式);Tmp {nf} =文件{nf}(idx);结束标签=分类(tmp);结束%------------------------------------------------------------函数X = getValidationSpeechSpectrograms(ads,afe,params)此函数仅在本例中使用。它可能改变了,也可能是%将在将来的版本中删除。%getValidationSpeechSpectrograms(ads,afe)计算语音频谱图%的文件在数据存储广告使用audioFeatureExtractor安全。numFiles = length(ads.Files);X = 0 ([params.numBands,params.numHops,1,numFiles],“单一”);为i = 1:numFiles x = read(ads);spec = getSpeechSpectrogram(x,afe,params);X(:,:,1,i) = spec;结束结束%--------------------------------------------------------------------------函数X = getSpeechSpectrogram(X,afe,params)此函数仅在本例中使用。它可能改变了,也可能是%将在将来的版本中删除。%getSpeechSpectrogram(x,afe)为信号计算语音谱图% x使用audioFeatureExtractor安全。X = 0 ([params.numBands,params.numHops],“单一”);x = normalizeAndResize(single(x),params);Spec = extract(afe,x).';如果频谱图的宽度小于numHops,则将频谱图放入% X的中间。W = size(spec,2);left = floor((params.numHops-w)/2)+1;Ind = left:left+w-1;X(:,ind) = log10(spec + 1e-6);结束%--------------------------------------------------------------------------函数x = normalizeandsize (x,params)此函数仅在本例中使用。它可能改变,也可能是%将在将来的版本中删除。L = params.segmentLength;N =数字(x);如果N > L x = x(1:L);elseifN < L pad = L-N;Prepad =地板(pad/2);Postpad = cell (pad/2);X = [0 (prepad,1);x;0 (postpad 1)];结束X = X /max(abs(X));结束%--------------------------------------------------------------------------函数myCustomWriter(规范、writeInfo ~)此函数仅在本例中使用。它可能改变,也可能是%将在将来的版本中删除。定义自定义书写功能,书写听觉谱图/标签对%到MAT文件。文件名= strrep(写入信息。SuggestedOutputName,“wav”,“.mat”);label = writeInfo.ReadInfo.Label;保存(文件名,“标签”,“规范”);结束%--------------------------------------------------------------------------函数[data,info] = myCustomRead(filename)此函数仅在本例中使用。它可能改变,也可能是%将在将来的版本中删除。负载(文件名,“规范”,“标签”);Data = {spec,label};信息。SampleRate = 8000;结束