主要内容

语音命令识别使用深度学习

这个例子展示了如何培养一个深度学习模型,检测音频语音命令的存在。示例数据集使用语音命令[1]训练一个卷积神经网络识别给定的命令集。

从头来训练网络,您必须先下载数据集。如果你不希望下载数据集或训练网络,然后你可以加载一个pretrained网络提供的这个例子并执行接下来的两部分的例子:使用Pre-Trained网络识别命令检测命令使用流式音频从麦克风

使用Pre-Trained网络识别命令

进入详细培训过程之前,使用pre-trained语音识别网络来识别语音命令。

加载pre-trained网络。

负载(“commandNet.mat”)

网络训练识别语音命令如下:是的,没有,向上,下来,,正确的,,,停止,

加载一个简短的语音信号,一个人说停止

[x, fs] = audioread (“stop_command.flac”);

听命令。

声音(x, fs)

pre-trained网络需要auditory-based色作为输入。你会首先将语音波形转换为一个auditory-based谱图。

使用的函数helperExtractAuditoryFeature计算听觉谱图。你将经历的细节特征提取后的例子。

auditorySpect = helperExtractAuditoryFeatures (x, fs);

命令基于其听觉谱图进行分类。

命令=分类(trainedNet auditorySpect)
命令=分类停止

网络训练分类词不属于这个集合未知的

你现在将分类词()不包含在列表命令来确定。

首先,加载语音信号,听它。

x = audioread (“play_command.flac”);声音(x, fs)

计算听觉谱图。

auditorySpect = helperExtractAuditoryFeatures (x, fs);

信号的分类。

命令=分类(trainedNet auditorySpect)
命令=分类未知的

网络训练分类背景噪音背景

创建一个一秒钟信号组成的随机噪声。

x = pinknoise (16 e3);

计算听觉谱图。

auditorySpect = helperExtractAuditoryFeatures (x, fs);

分类的背景噪音。

命令=分类(trainedNet auditorySpect)
命令=分类背景

检测命令使用流式音频从麦克风

测试你的pre-trained命令检测网络流媒体音频从你的麦克风。例如,尝试说的一个命令是的,没有,或停止。然后,试着说等一个生词马文,希拉,床上,房子,,,或任何数量从0到9。

指定的分类率赫兹和创建一个音频设备的读者,可以阅读从你的麦克风音频。

classificationRate = 20;adr = audioDeviceReader (SampleRate = fs, SamplesPerFrame =地板(fs / classificationRate));

初始化一个音频缓冲区。提取网络的分类标签。初始化缓冲半秒的标签和流式音频的分类概率。使用这些缓冲区比较分类结果在更长一段时间,通过建立“协议”当一个命令被检测到。指定阈值的决策逻辑。

audioBuffer = dsp.AsyncBuffer (fs);. class标签= trainedNet.Layers(结束);YBuffer (1: classificationRate / 2) =分类(“背景”);probBuffer = 0([元素个数(标签),classificationRate / 2));countThreshold =装天花板(classificationRate * 0.2);probThreshold = 0.7;

创建一个timescope对象可视化你的麦克风的音频输入。创建一个dsp.MatrixViewer对象可视化听觉谱图用来作出预测。

wavePlotter = timescope (SampleRate = fs,Title =“…”,TimeSpanSource =“财产”,时间间隔= 1,YLimits = [1],位置= [600640800340],TimeAxisLabels =“没有”,AxesScaling =“手动”);显示(wavePlotter) specPlotter = dsp.MatrixViewer (XDataMode =“自定义”,AxisOrigin =“左下角”,位置= [600220800380],ShowGrid = false,Title =“…”,包含=“时间(s)”,YLabel =“汪汪”(本));显示(specPlotter)

现场表演从你的麦克风语音命令识别使用音频输入。无限循环运行,集期限。停止现场检测,关闭timescope和dsp.MatrixViewer数字。

%初始化变量进行策划currentTime = 0;colorLimits = [1];期限= 10;抽搐toc <期限& & isVisible (wavePlotter) & & isVisible (specPlotter)%从音频设备中提取音频样本和样本添加到%的缓冲。x = adr ();写(audioBuffer x);fs, y =阅读(audioBuffer fs-adr.SamplesPerFrame);规范= helperExtractAuditoryFeatures (y, fs);%分类当前光谱图,保存标签的标签缓冲区,%并保存预测概率的概率缓冲区。[YPredicted,聚合氯化铝]=分类(trainedNet、规格,ExecutionEnvironment =“cpu”);YBuffer = [YBuffer(2:结束),YPredicted);probBuffer = [probBuffer(:, 2:结束)、聚合氯化铝(:));%绘制当前波形和声谱图。wavePlotter (y (end-adr.SamplesPerFrame + 1:结束)specPlotter(规范)%现在实际的命令执行的检测阈值操作。%声明了一个检测和显示在图如果以下:% 1)最常见的标签是没有背景。% 2)最后countThreshold最新帧标签的同意。% 3)的最大概率预测至少probThreshold标签。%,不声明一个检测。[YMode,计数]=模式(YBuffer);maxProb = max (probBuffer(标签= = YMode:));如果YMode = =“背景”| |数< countThreshold | | maxProb < probThreshold wavePlotter。Title =“…”;specPlotter。Title =“…”;其他的wavePlotter。Title =string(YMode); specPlotter.Title = string(YMode);结束%更新变量策划currentTime = currentTime + adr.SamplesPerFrame / fs;colorLimits = [min ([colorLimits (1), min(规范、[]“所有”)))、马克斯([colorLimits (2), max(规范、[]“所有”))));specPlotter。CustomXData = [currentTime-1, currentTime];specPlotter。ColorLimits = ColorLimits;结束发行版(wavePlotter)

发行版(specPlotter)

加载语音命令数据集

下面的例子使用了谷歌语音命令数据集[1]。数据集下载并解压缩下载的文件。

downloadFolder = matlab.internal.examples.download万博1manbetxSupportFile (“音频”,“google_speech.zip”);dataFolder = tempdir;解压缩数据集(downloadFolder dataFolder) = fullfile (dataFolder,“google_speech”);

创建培训数据存储

创建一个audioDatastore(音频工具箱)指向的训练数据集。

广告= audioDatastore (fullfile(数据集,“训练”),IncludeSubfolders = true,FileExtensions =“wav”,LabelSource =“foldernames”)
广告= audioDatastore属性:文件:{…\ AppData \当地\ Temp \床google_speech \培训\ \ 00176480 _nohash_0.wav”;’……\ AppData \当地\ Temp \床google_speech \培训\ \ 004 ae714_nohash_0.wav;’……\ AppData \当地\ Temp \ google_speech ae714_nohash_1 \培训\床\ 004。wav”……文件夹和51085}:{“C: \ \ bhemmat \ AppData \用户当地火车\ Temp \ google_speech \}标签:[床;床上;床上……和51085年更直言]AlternateFileSystemRoots: {} OutputDataType:“双”SupportedOutputFormats: 万博1manbetx[“wav”“flac”“ogg”“mp4”“m4a格式”]DefaultOutputFormat:“wav”

选择单词识别

指定的话,你希望你的模型识别的命令。标签不是命令的所有单词未知的。标记的单词不是命令未知的接近的单词创建一组命令以外的所有词语的分布。网络使用这组学习命令和其他单词之间的区别。

减少失衡已知和未知的类单词和加速处理,只包括一小部分生词的训练集。

使用子集(音频工具箱)创建一个数据存储,只包含命令和生词的子集。数一数的例子属于每个类别。

命令=分类([“是的”,“不”,《飞屋环游记》,“向下”,“左”,“正确”,“上”,“关闭”,“停止”,“走”]);isCommand = ismember (ads.Labels、命令);isUnknown = ~ isCommand;includeFraction = 0.2;掩码=兰德(元素个数(ads.Labels), 1) < includeFraction;isUnknown = isUnknown &面具;ads.Labels (isUnknown) =分类(“未知”);adsTrain =子集(广告,isCommand | isUnknown);countEachLabel (adsTrain)
ans =11×2表标签数_________ _____ 1842 1861 1839 1853 1839 1864 1852停止1885未知6490 1843对1860

创建验证数据存储

创建一个audioDatastore(音频工具箱)指向验证数据集。遵循相同的步骤用于创建数据存储的培训。

广告= audioDatastore (fullfile(数据集,“确认”),IncludeSubfolders = true,FileExtensions =“wav”,LabelSource =“foldernames”)
广告= audioDatastore属性:文件:{…\ AppData \当地\ Temp \ google_speech \床验证\ \ 026290 a7_nohash_0.wav”;’……\ AppData \当地\ Temp \ google_speech \床验证\ \ 060 cd039_nohash_0.wav;’……\ AppData \当地\ Temp \ google_speech cd039_nohash_1 \床验证\ \ 060。wav”……文件夹和6795}:{“C: \ \ bhemmat \ AppData \用户当地\ Temp \ google_speech \验证}标签:[床;床上;床上……和6795年更直言]AlternateFileSystemRoots: {} OutputDataType:“双”SupportedOutputFormats: 万博1manbetx[“wav”“flac”“ogg”“mp4”“m4a格式”]DefaultOutputFormat:“wav”
isCommand = ismember (ads.Labels、命令);isUnknown = ~ isCommand;includeFraction = 0.2;掩码=兰德(元素个数(ads.Labels), 1) < includeFraction;isUnknown = isUnknown &面具;ads.Labels (isUnknown) =分类(“未知”);adsValidation =子集(广告,isCommand | isUnknown);countEachLabel (adsValidation)
ans =11×2表标签数_________ _____ 264 260 247 270 256 257 256停止246未知828 260对261

整个数据集训练网络,实现尽可能高的精度,集speedupExample。快速运行这个例子,集speedupExample真正的

speedupExample =;如果speedupExample numUniqueLabels =元素个数(独特(adsTrain.Labels));%减少数据集的20倍adsTrain = splitEachLabel (adsTrain轮(元素个数(adsTrain.Files) / numUniqueLabels / 20));adsValidation = splitEachLabel (adsValidation轮(元素个数(adsValidation.Files) / numUniqueLabels / 20));结束

计算听觉谱图

准备的数据有效的卷积神经网络训练,语音波形转换为auditory-based声谱图。

定义的参数特征提取。segmentDuration每个演讲片段的时间(以秒为单位)。frameDuration是频谱计算每一帧的持续时间。hopDuration是每个光谱之间的时间步。numBands过滤器的数量在听觉谱图。

创建一个audioFeatureExtractor(音频工具箱)对象进行特征提取。

fs = 16 e3;%已知采样率的数据集。segmentDuration = 1;frameDuration = 0.025;hopDuration = 0.010;segmentSamples =圆(segmentDuration * fs);frameSamples =圆(frameDuration * fs);hopSamples =圆(hopDuration * fs);overlapSamples = frameSamples - hopSamples;FFTLength = 512;numBands = 50;afe = audioFeatureExtractor (SampleRate = fs,FFTLength = FFTLength,窗口=损害(frameSamples,“周期”),OverlapLength = overlapSamples,barkSpectrum = true);setExtractorParameters (afe“barkSpectrum”NumBands = NumBands WindowNormalization = false);

读取文件数据集。训练一个卷积神经网络需要一个一致的输入的大小。数据集内的一些文件小于1秒长。应用零填充的前后音频信号的长度segmentSamples

x =阅读(adsTrain);numSamples =大小(x, 1);地板numToPadFront = ((segmentSamples - numSamples) / 2);numToPadBack =装天花板((segmentSamples - numSamples) / 2);xPadded = 0 (numToPadFront 1“喜欢”,x); x; 0 (numToPadBack 1“喜欢”,x));

提取音频功能,电话提取。输出是一个树皮频谱随时间在行。

特点=提取(afe xPadded);[numHops, numFeatures] =大小(特性)
numHops = 98
numFeatures = 50

在本例中,您后处理应用对数的听觉谱图。少量的日志会导致舍入误差。

加快处理、特征提取可以分发到多个工人使用parfor

首先,确定数据集的分区数量。如果你没有并行计算工具箱™,使用单个分区。

如果~ isempty(版本(“平行”)& & ~ speedupExample池=质量;numPar = numpartitions (adsTrain、池);其他的numPar = 1;结束

为每个分区,从数据存储读取,在信号,然后提取特征。

parfor2 = 1:numPar再分=分区(adsTrain、numPar ii);XTrain = 0 (numHops numBands 1,元素个数(subds.Files));idx = 1:元素个数(subds.Files) x =阅读(再分);xPadded =[0(地板(segmentSamples-size (x, 1)) / 2), 1); x; 0(装天花板((segmentSamples-size (x, 1)) / 2), 1)];XTrain (:,:,:, idx) =提取(afe xPadded);结束XTrainC {2} = XTrain;结束

输出转换为一个四维数组与听觉谱图在第四维。

XTrain =猫(4,XTrainC {:});[numHops, numBands numChannels numSpec] =大小(XTrain)
numHops = 98
numBands = 50
numChannels = 1
numSpec = 25028

规模靠窗的权力的特性,然后把日志。与平滑分布,获取数据的对数谱图使用一个小的偏移量。

epsil = 1 e-6;XTrain = log10 (XTrain + epsil);

执行上述特征提取步骤来验证集。

如果~ isempty(版本(“平行”)池=质量;numPar = numpartitions (adsValidation、池);其他的numPar = 1;结束parfor2 = 1:numPar再分=分区(adsValidation、numPar ii);XValidation = 0 (numHops numBands 1,元素个数(subds.Files));idx = 1:元素个数(subds.Files) x =阅读(再分);xPadded =[0(地板(segmentSamples-size (x, 1)) / 2), 1); x; 0(装天花板((segmentSamples-size (x, 1)) / 2), 1)];XValidation (:,:,:, idx) =提取(afe xPadded);结束XValidationC {2} = XValidation;结束XValidation =猫(4,XValidationC {:});XValidation = log10 (XValidation + epsil);

隔离训练和验证标签。删除空的类别。

TTrain = removecats (adsTrain.Labels);TValidation = removecats (adsValidation.Labels);

可视化数据

画出波形和听觉谱图的一些训练样本。发挥相应的音频剪辑。

specMin = min (XTrain [],“所有”);specMax = max (XTrain [],“所有”);idx = randperm(元素个数(adsTrain.Files), 3);图(单位=“归一化”位置= (0.2 - 0.2 0.6 - 0.6));2 = 1:3 (x, fs) = audioread (adsTrain.Files {idx (ii)});次要情节(2、3、2)情节(x)轴标题(string (adsTrain.Labels (idx (ii))))次要情节spect (2、3、2 + 3) = XTrain (:,: 1, idx (ii) ';pcolor (spect) caxis ([specMin specMax])阴影声音(x, fs)暂停(2)结束

添加背景噪声数据

不仅网络必须能够识别不同的口语词汇,还发现如果输入包含沉默或背景噪音。

使用音频文件在后台文件夹中创建的样本一秒钟的视频背景噪音。创建一个相同数量的背景从每个背景噪音文件片段。您还可以创建您自己的背景噪音的录音,并将它们添加到背景文件夹。计算谱图之前,函数重新调节每个音频剪辑的因素从log-uniform抽样分布的范围volumeRange

adsBkg = audioDatastore (fullfile(数据集,“背景”))
adsBkg = audioDatastore属性:文件:{…\ AppData \当地背景\ Temp \ google_speech \ \ doing_the_dishes.wav ';’……当地\ Temp \ bhemmat \ AppData \ \ google_speech \背景\ dude_miaowing.wav”;“……当地\ Temp \ bhemmat \ AppData \ \ google_speech \ \ exercise_bike背景。wav”……和3}文件夹:{" C: \ \用户当地bhemmat \ AppData \ \ Temp \ google_speech \背景”}AlternateFileSystemRoots: {} OutputDataType:“双”标签:{}SupportedOutputFormats: [“wav”“fla万博1manbetxc”“ogg”“mp4”“m4a格式”]DefaultOutputFormat:“wav”
numBkgClips = 4000;如果speedupExample numBkgClips = numBkgClips / 20;结束volumeRange = log10([1的军医,1]);numBkgFiles =元素个数(adsBkg.Files);numClipsPerFile = histcounts (1: numBkgClips, linspace (1 numBkgClips numBkgFiles + 1);Xbkg = 0(大小(XTrain, 1),大小(XTrain, 2), 1, numBkgClips,“单身”);bkgAll = readall (adsBkg);印第安纳州= 1;数= 1:numBkgFiles bkg = bkgAll{数};idxStart =兰迪(元素个数(bkg) - f, numClipsPerFile(计数),1);idxEnd = idxStart + fs-1;获得= 10。^ (volumeRange (2) -volumeRange(1)) *兰德(numClipsPerFile(计数),1)+ volumeRange (1));j = 1: numClipsPerFile(计数)x = bkg (idxStart (j): idxEnd (j)) *获得(j);x = max (min (x, 1), 1);Xbkg(:,:,:,印第安纳州)=提取(afe x);如果国防部(印第安纳州,1000)= = = 0进展“加工”(印第安纳州)+ +字符串“背景剪辑出来的”+字符串(numBkgClips)结束印第安纳州=印第安纳+ 1;结束结束
进步=“4000年加工1000背景短片”
进步=“4000年加工2000背景短片”
进步=“4000年加工3000背景短片”
进步=“4000年加工4000背景短片”
Xbkg = log10 (Xbkg + epsil);

把谱图之间的背景噪音训练,验证集和测试集。因为背景噪音文件夹包含只有大约五个半分钟的背景噪声,背景样本在不同的数据集是高度相关的。增加背景噪声的变化,您可以创建自己的背景文件,并将它们添加到文件夹中。提高网络的健壮性噪音,你也可以尝试混合背景噪音的语音文件。

numTrainBkg =地板(0.85 * numBkgClips);numValidationBkg =地板(0.15 * numBkgClips);XTrain(:,:,: + 1:终端+ numTrainBkg) = Xbkg (:,:,:, 1: numTrainBkg);TTrain(+ 1:结束+ numTrainBkg) =“背景”;XValidation(:,:,: + 1:终端+ numValidationBkg) = Xbkg (:,:,:, numTrainBkg + 1:结束);TValidation(+ 1:结束+ numValidationBkg) =“背景”;

情节的分布不同的类标签的训练集和验证集。

图(单位=“归一化”位置= [0.2 - 0.2 0.5 - 0.5])tiledlayout (2, 1) nexttile直方图(TTrain)标题(“培训标签分配”)nexttile直方图(TValidation)标题(“验证标签分配”)

定义神经网络体系结构

创建一个简单的网络体系结构层的一个数组。使用卷积和批量标准化层,downsample特征地图“空间”(也就是说,在时间和频率)使用max池层。添加最后一个马克斯池层池输入特性全球地图。这个执行(近似)time-translation输入谱图中的不变性,使网络执行相同的分类独立言论的确切位置。全球池也显著减少了参数的数量在最后完全连接层。减少的可能性,网络记忆训练数据的特定功能,添加少量的辍学输入到最后完全连接层。

网络很小,因为它只有5卷积和几层过滤器。numF控制卷积过滤器的层数。增加网络的准确性,试着增加网络深度通过添加相同的卷积,批正常化,和ReLU层。你也可以尝试增加卷积过滤器的数量增加numF

给每个类等于总重量损失,使用类重量成反比的训练例子每个类的数量。当使用亚当优化器训练网络,训练算法是独立于整体类的归一化权重。

类=类别(TTrain);classWeights = 1. / countcats (TTrain);classWeights = classWeights ' /意味着(classWeights);numClasses =元素个数(类别(TTrain));timePoolSize =装天花板(numHops / 8);dropoutProb = 0.2;numF = 12;层= [imageInputLayer ([numHops numBands]) convolution2dLayer (3 numF填充=“相同”)batchNormalizationLayer reluLayer maxPooling2dLayer(3步= 2填充=“相同”)convolution2dLayer (3 2 * numF填充=“相同”)batchNormalizationLayer reluLayer maxPooling2dLayer(3步= 2填充=“相同”)convolution2dLayer (3、4 * numF填充=“相同”)batchNormalizationLayer reluLayer maxPooling2dLayer(3步= 2填充=“相同”)convolution2dLayer (3、4 * numF填充=“相同”)batchNormalizationLayer reluLayer convolution2dLayer (3、4 * numF、填充=“相同”)batchNormalizationLayer reluLayer maxPooling2dLayer ([timePoolSize 1]) dropoutLayer (dropoutProb) fullyConnectedLayer (numClasses) softmaxLayer classificationLayer(类=类,ClassWeights = ClassWeights)];

列车网络的

指定培训选项。优化器使用亚当mini-batch大小为128。火车25时代和学习速率降低10倍20世纪后。

miniBatchSize = 128;validationFrequency =地板(元素个数(TTrain) / miniBatchSize);选择= trainingOptions (“亚当”,InitialLearnRate = 3的军医,MaxEpochs = 25,MiniBatchSize = MiniBatchSize,洗牌=“every-epoch”,情节=“训练进步”,Verbose = false,ValidationData = {XValidation, TValidation},ValidationFrequency = ValidationFrequency,LearnRateSchedule =“分段”,LearnRateDropFactor = 0.1,LearnRateDropPeriod = 20);

培训网络。如果你没有一个GPU,然后培训网络需要时间。

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

评估培训网络

计算的最终精度网络训练集(没有数据增大)和验证集。这个数据集的网络是非常准确的。然而,训练,验证和测试数据都有类似的分布不一定反映真实世界的环境。这种限制特别适用于未知的类别,其中包含的话语只有少量的单词。

如果speedupExample负载(“commandNet.mat”,“trainedNet”);结束YValPred =分类(trainedNet XValidation);validationError =意味着(YValPred ~ = TValidation);YTrainPred =分类(trainedNet XTrain);trainError =意味着(YTrainPred ~ = TTrain);disp (“训练误差:+ trainError * 100 +“%”)
训练误差:1.5794%
disp ("验证错误:"+ validationError * 100 +“%”)
验证错误:4.6692%

情节混乱矩阵。显示每个类的精度和召回通过使用列和行摘要。混淆矩阵的类。最大的困惑是生词和命令之间,向上,下来没有,没有

图(单位=“归一化”位置= (0.2 - 0.2 0.5 - 0.5));厘米= confusionchart (TValidation YValPred,Title =“验证数据的混淆矩阵”,ColumnSummary =“column-normalized”RowSummary =“row-normalized”);sortClasses(厘米,[命令,“未知”,“背景”])

当工作在应用程序与硬件资源限制等移动应用,考虑限制可用内存和计算资源。计算网络的总大小字节和测试它的预测速度当使用一个CPU。分类的预测时间是时间一个输入图像。如果你输入多个图像网络,这些可以同时分类,导致短预测次形象。当分类流式音频,幅图片预测时间是最相关的。

信息=谁(“trainedNet”);disp (“网络大小:”+信息。字节/ 1024 +“知识库”)
网络的大小:292.2139 kB
时间= 0 (100 1);2 = 1:10 0 x = randn ([numHops numBands]);抽搐(YPredicted,聚合氯化铝)= (trainedNet x, ExecutionEnvironment =进行分类“cpu”);(二)= toc;结束disp (幅图片预测CPU时间:“+的意思是(时间(11:结束))* 1000 +“女士”)
幅图片预测CPU时间:2.4838 ms

引用

[1]监狱长P。“语音命令:一个公共数据集单字原图语音识别”,2017。可以从https://storage.googleapis.com/download.tensorflow.org/data/speech_commands_v0.01.tar.gz。版权2017年谷歌。语音命令数据集是创作共用署名4.0许可下的,可用:https://creativecommons.org/licenses/by/4.0/legalcode

引用

[1]监狱长P。“语音命令:一个公共数据集单字原图语音识别”,2017。可以从http://download.tensorflow.org/data/speech_commands_v0.01.tar.gz。版权2017年谷歌。语音命令数据集是创作共用署名4.0许可下的,可用:https://creativecommons.org/licenses/by/4.0/legalcode

另请参阅

||

相关的话题