训练语音活动检测噪声模型中使用深度学习
这个例子展示了如何检测区域的言论在低信噪比环境下使用深度学习。你训练一个双向长期短期记忆(BiLSTM)网络从头执行语音活动检测(VAD)和比较基于pretrained深度学习和监督网络。从头开始探索模型训练在这个例子中,看到的使用深度学习语音活动检测噪声。使用现成的深度上优于VAD,明白了detectspeechnn
。
介绍
语音活动检测许多音频系统是一个重要的组成部分,如自动语音识别、说话人识别和音频会议。语音活动检测可以在低信噪比(信噪比)的情况下尤其具有挑战性,演讲是噪音的阻碍。
再现性,将随机种子设置为默认。
rng默认的
在高信噪比情况下,传统的语音检测算法充分执行。读入一个音频文件,包括单词之间的停顿,听它。
fs = 16 e3;[演讲,fileFs] = audioread (“MaleVolumeUp-16-mono-6secs.ogg”);声音(演讲中,fs)
使用detectSpeech
功能定位区域的言论。的detectSpeech
函数正确识别所有地区的演讲。
detectSpeech(演讲中,fs)
加载两个信号和噪声重新取样
音频采样率。
[noise200, fileFs200] = audioread (“洗衣机- 16 - 8 mono - 200 - secs.mp3”);[noise1000, fileFs1000] = audioread (“洗衣机- 16 - 8 mono - 1000 - secs.mp3”);noise200 =重新取样(fs, noise200 fileFs200);noise1000 =重新取样(fs, noise1000 fileFs1000);
使用支持函数万博1manbetxmixSNR
腐败的清洁与洗衣机噪声语音信号所需的信噪比水平dB。听的音频。
信噪比=-10年;noisySpeech = mixSNR(演讲、noise200、信噪比);声音(noisySpeech fs)
调用detectSpeech
在嘈杂的语音信号。函数无法检测到演讲地区考虑到非常低的信噪比。剩下的例子走过培训和评估基于深度学习和监督网络,可以在低信噪比条件下表现良好。
detectSpeech (noisySpeech fs)
下载和准备数据
下载并提取数据集的谷歌语音命令[1]。
downloadFolder = matlab.internal.examples.download万博1manbetxSupportFile (“音频”,“google_speech.zip”);dataFolder = tempdir;解压缩数据集(downloadFolder dataFolder) = fullfile (dataFolder,“google_speech”);
创建audioDatastore
指向对象的培训和验证数据集。
adsTrain = audioDatastore (fullfile(数据集,“训练”),IncludeSubfolders = true);adsValidation = audioDatastore (fullfile(数据集,“确认”),IncludeSubfolders = true);
构造训练和验证信号
谷歌数据集由孤立的单词。使用支持函数,万博1manbetxconstructSignal
contruct训练和验证信号,由单词和地区的沉默。的constructSignal
函数也返回地面实况二进制面具指示区域的演讲训练和验证信号。
[audioTrain, TTrainPerSample] = constructSignal (adsTrain fs 1000);[audioValidation, TValidationPerSample] = constructSignal (adsValidation fs 200);
听的第一个10秒构造信号。使用signalMask
和plotsigroi
可视化的信号和地面真理二进制面具。
时间=10;声音(audioTrain(1:时间* fs), fs)面具= signalMask (TTrainPerSample SampleRate = fs);plotsigroi (audioTrain面具,真正的)xlim([0,持续时间])标题(“干净的信号(“+时间+“秒)”)
添加噪声训练和验证信号
使用支持函数万博1manbetxmixSNR
腐败的火车和验证信号与噪音。
audioTrain = mixSNR (audioTrain noise1000,信噪比);audioValidation = mixSNR (audioValidation noise200,信噪比);
听火车的第一个10秒信号和可视化信号和面具。
声音(audioTrain(1:时间* fs), fs) plotsigroi(面具,audioTrain,真)xlim([0,持续时间])标题(“训练信号(“+时间+“秒)”)
输入管道
定义一个audioFeatureExtractor
提取光谱特性如下:spectralCentroid
,spectralCrest
,spectralEntropy
,spectralFlux
,spectralKurtosis
,spectralRolloffPoint
,spectralSkewness
,spectralSlope
和周期性特征harmonicRatio
。提取特征使用256点损害窗口有50%的重叠。
afe = audioFeatureExtractor (SampleRate = fs,…窗口=损害(256“周期”),…OverlapLength = 128,……spectralCentroid = true,…spectralCrest = true,…spectralEntropy = true,…spectralFlux = true,…spectralKurtosis = true,…spectralRolloffPoint = true,…spectralSkewness = true,…spectralSlope = true,…harmonicRatio = true);audioTrain featuresTrain =提取(afe);
显示的尺寸特性矩阵。第一个维度对应窗口的数量信号分为(这取决于信号长度、窗口长度,和重叠长度)。第二个维度是本例中使用的特性。
[numWindows, numFeatures] =大小(featuresTrain)
numWindows = 124999
numFeatures = 9
在分类应用程序中,这是一个很好的实践所有功能正常化零均值和标准差统一。
计算每个系数的平均值和标准偏差,并使用它们来规范化数据。
M =意味着(featuresTrain, 1);S =性病(featuresTrain [], 1);featuresTrain = (featuresTrain - M)。/ S;
从验证提取特征信号使用相同的过程。
audioValidation XValidation =提取(afe);XValidation = (XValidation -意味着(XValidation, 1))。/性病(XValidation [], 1);
每个特征对应于256个样本数据(窗口长度),每128样品取样(hop长度)。对于每一个窗口,将预期的声音/不值设置为基线掩模值的模式对应于这256个样本。声音/不掩码转换为分类。
windowLength =元素个数(afe.Window);overlapLength = afe.OverlapLength;TTrain =模式(缓冲区(TTrainPerSample、windowLength overlapLength,“nodelay”),1);TTrain =分类(TTrain);
做同样的验证的面具。
TValidation =模式(缓冲区(TValidationPerSample、windowLength overlapLength,“nodelay”),1);TValidation =分类(TValidation);
使用支持函数万博1manbetxfeatureBuffer
将培训特点和面具分为序列时间约8秒,75%重叠连续序列。
sequenceDuration =8;analysisHopLength =元素个数(afe.Window)——afe.OverlapLength;sequenceLength =圆(sequenceDuration * fs / analysisHopLength);overlapPercent =0.75;XTrain = featureBuffer (featuresTrain sequenceLength overlapPercent);TTrain = featureBuffer (TTrain sequenceLength overlapPercent);
网络体系结构
LSTM网络可以学习长期之间的依赖关系的时间序列数据的步骤。下面的例子使用了双向LSTM层bilstmLayer
(深度学习工具箱)观察序列在向前和向后的方向。
层= […sequenceInputLayer afe.FeatureVectorLength bilstmLayer(200年,OutputMode =“序列”)bilstmLayer(200年,OutputMode =“序列”)fullyConnectedLayer (2) softmaxLayer classificationLayer];
培训方案
定义参数训练,使用trainingOptions
(深度学习工具箱)。优化器使用亚当mini-batch大小为64和分段学习时间表。
maxEpochs =20.;miniBatchSize =64年;选择= trainingOptions (“亚当”,…MaxEpochs = MaxEpochs,…MiniBatchSize = MiniBatchSize,…洗牌=“every-epoch”,…Verbose = false,…SequenceLength = SequenceLength,…ValidationFrequency =地板(元素个数(XTrain) / miniBatchSize),…ValidationData = {XValidation。' TValidation},…情节=“训练进步”,…LearnRateSchedule =“分段”,…LearnRateDropFactor = 0.1,…LearnRateDropPeriod = 5,…OutputNetwork =“best-validation-loss”);
列车网络的
训练网络,使用trainNetwork
(深度学习工具箱)。
speechDetectNet = trainNetwork (XTrain、TTrain层,选择);
评估培训网络
估计语音活动验证信号使用训练网络。估计VAD面具从范畴转化成双,然后复制窗口纸浆包决策的决定。
YValidation =分类(speechDetectNet XValidation。');YValidation = (YValidation)的两倍。”——1;王=元素个数(afe.Window);hL = wL - afe.OverlapLength;YValidationPerSample = [repelem (YValidation(1),地板(wL / 2 +霍奇金淋巴瘤/ 2),1);repelem (YValidation (2: end-1)、霍奇金淋巴瘤,1);repelem (YValidation(结束),装天花板(wL / 2 +霍奇金淋巴瘤/ 2),1)];
计算和绘制验证混淆矩阵向量的实际和估计标签。保存后的结果分析。
cc = confusionchart (TValidationPerSample YValidationPerSample,…title =“speechDetect——验证混乱图表”,…ColumnSummary =“column-normalized”RowSummary =“row-normalized”);
speechDetectResults = cc.NormalizedValues;
评估Pretrained和监督网络
的vadnet
网络是一个pretrained网络语音活动检测。你可以使用它vadnetPreprocess
和vadnetPostprocess
功能应用,如转移学习,或者你可以使用detectspeechnn
,它封装了vadnetPreprocess
,vadnet
,vadnetPostprocess
来推断只应用程序。的vadnet
网络在日常不良条件下表现良好,但是不能在极端信噪比的情况下,比如在这个例子中使用的-10分贝信噪比。同时,vadnet
被训练来检测区域的连续语音(即连续几个词),不要孤立的单词。简而言之,pretrainedvadnet
在本例中为验证失败信号。
负载在pretrained vadnet模型。
网= vadnet ();
从验证提取特征信号使用相同的输入管道用于训练网络。
XValidation = vadnetPreprocess (audioValidation, fs);
预测和监督面具。
y =预测(净,XValidation);
vadnet
是一个回归网络,需要额外的后处理,以确定边界的决定。使用vadnetPostprocess
确定语音活动区域的边界。
边界= vadnetPostprocess (audioValidation 16 e3, y);
的vadnetPostprocess
函数返回的决定随着时间的界限。将边界转换成二进制掩模对应于原始信号样本,使用sigroi2binmask
。
YValidationPerSample =双(sigroi2binmask(边界,大小(audioValidation 1)));
创建一个混乱图表分析错误,使用confusionchart
(深度学习工具箱)。
confusionchart (TValidationPerSample YValidationPerSample,…title =“vadnet——验证混乱图表”,…ColumnSummary =“column-normalized”RowSummary =“row-normalized”);
转移学习
应用学习转移到pretrainedvadnet
利用pretrained权重和网络架构。
从pretrained网络提取层图,使用layerGraph
(深度学习工具箱)。
层= layerGraph(净);
从音频提取特征。
featuresTrain = vadnetPreprocess (audioTrain, fs);
缓冲地面的真相掩盖这决定对应分析窗口中使用vadnetPreprocess
。
windowLength = 400;overlapLength = 240;TTrainPerSamplePadded =[0(地板(windowLength / 2), 1); TTrainPerSample; 0 ((windowLength / 2),即:1)];TTrain =模式(缓冲区(TTrainPerSamplePadded、windowLength overlapLength,“nodelay”),1);
缓冲验证面具。
TValidationPerSamplePadded =[0(地板(windowLength / 2), 1); TValidationPerSample; 0 ((windowLength / 2),即:1)];TValidation =模式(缓冲区(TValidationPerSamplePadded、windowLength overlapLength,“nodelay”),1);
长期训练信号分割成重叠序列进行训练。做同样的真实的面具。
sequenceDuration =8;analysisHopLength = windowLength - overlapLength;sequenceLength =圆(sequenceDuration * fs / analysisHopLength);overlapPercent =0.75;XTrain = featureBuffer (featuresTrain sequenceLength overlapPercent);TTrain = featureBuffer (TTrain sequenceLength overlapPercent);
定义参数训练,使用trainingOptions
(深度学习工具箱)。
miniBatchSize =12;maxEpochs =9;选择= trainingOptions (“亚当”,…InitialLearnRate = 0.01,…LearnRateSchedule =“分段”,…LearnRateDropPeriod = 3,…MiniBatchSize = MiniBatchSize,…洗牌=“every-epoch”,…ValidationFrequency =地板(元素个数(XTrain) / miniBatchSize),…ValidationData = {XValidation, TValidation},…Verbose = false,…情节=“训练进步”,…MaxEpochs = MaxEpochs,…OutputNetwork =“best-validation-loss”…);
训练网络,使用trainNetwork
(深度学习工具箱)。
noisyvadnet = trainNetwork (XTrain、TTrain层,选择);
估计语音活动验证信号使用训练网络。后处理的预测使用vadnetPostprocess
,然后及时转换边界纸浆包面具。
y =预测(noisyvadnet XValidation);边界= vadnetPostprocess (audioValidation fs, y);YValidationPerSample =双(sigroi2binmask(边界,大小(audioValidation 1)));
计算和绘制验证混淆矩阵向量的实际和估计标签。保存后的结果分析。
cc = confusionchart (TValidationPerSample YValidationPerSample,…title =“noisyvadnet——验证混乱图表”,…ColumnSummary =“column-normalized”RowSummary =“row-normalized”);
noisyvadnetResults = cc.NormalizedValues;
比较网络
有几个因素在选择一个网络,如大小、推理速度,错误,和流媒体功能。
流媒体
的speechDetectNet
从头开始训练在这个例子非常适合流媒体推论,因为它BiLSTM层调用之间保留状态。看到使用深度学习语音活动检测噪声的一个例子使用speechDetect流语音活动检测。
的vadnet
体系结构包括卷积、复发和全层,不适合低延迟流。看到vadnet
文档的一个示例流VAD检测使用vadnet
。
网络规模
网络的大小进行比较。
网络= [“speechDetect”,“noisyvadnet”];b =栏(reordercats(分类(网络)、网络),[谁(“speechDetectNet”).bytes / 1024,谁(“noisyvadnet”).bytes / 1024]);标题(“网络规模”)ylabel (“大小(KB)”网格)在b。FaceColor =“平”;:b.CData (2) = (0.8500 0.3250 0.0980);
网络推理速度
比较网络推理速度。简单的speechDetect
架构已经推理速度快的CPU和GPU在短时间内(大约8第二块或更少)。长时间,speechDetect
是速度比noisyvadnet
在GPU和CPU慢。
durationsToTest = (1、5、10、20、40);环境= [“CPU”,“图形”];speechDetectSpeed = 0(元素个数(durationsToTest),元素个数(环境));noisyvadnetSpeed = 0(元素个数(durationsToTest),元素个数(环境));为jj = 1:元素个数(环境)为2 = 1:元素个数(durationsToTest) idx = 1: durationsToTest (ii) * fs;speechDetectFeatures =提取(afe audioValidation (idx)) ';vadnetFeatures = vadnetPreprocess (audioValidation (idx), fs);开关环境(jj)情况下“CPU”speechDetectSpeed(2,1)时间=(@()分类(speechDetectNet、speechDetectFeatures ExecutionEnvironment =“cpu”),1);noisyvadnetSpeed(2,1)时间=(@()预测(noisyvadnet、vadnetFeatures ExecutionEnvironment =“cpu”),1);情况下“图形”speechDetectSpeed (2, 2) = gputimeit(@()分类(speechDetectNet、speechDetectFeatures ExecutionEnvironment =“图形”),1);noisyvadnetSpeed (2, 2) = gputimeit(@()预测(noisyvadnet、vadnetFeatures ExecutionEnvironment =“图形”),1);结束结束结束tiledlayout (2, 1)为2 = 1:元素个数(环境)nexttile情节(durationsToTest, speechDetectSpeed(:,(二),“b -”,…durationsToTest noisyvadnetSpeed(:,(二),“r -”,…durationsToTest speechDetectSpeed(:,(二),“波”,…durationsToTest noisyvadnetSpeed(:,(二),“罗”)传说([“speechDetect”,“noisyvadnet”),位置=“最佳”网格)在包含(“音频持续时间(s)”)ylabel (“计算持续时间(s)”)标题(“推理速度(“(2)+ +环境“)”)结束
网络错误
使用前面计算的混乱图表显示常见的统计数据误差分析。准确性、召回、精度和f1得分都来自之前绘制的混淆矩阵。
准确的定义是正确的比例预计总观察观察。这是最直观的指标,但可以误导不平衡数据集。例如,如果演讲只是出现在5%的音频,然后所有的音频分类测度将导致95%的准确率。
回忆,也称为敏感性,正确的比例预测积极观察观察,属于积极的类。记得回答了这个问题:所有演讲的地区,正确分类是多少?低召回的言论表明,区域nonspeech并被错误地归类为地区。
精确的比例是正确预测积极观察总预测积极观察。精确的回答了这个问题:所有的观测网络分为演讲,言论实际上是多少?低精度表明地区nonspeech言论并被错误地归类为地区。
F1分数是调和平均数的精度和召回:它占假阳性和假阴性。
真正的衡量网络取决于您的应用程序。在实际情况下,成本函数通常是优化权重假阳性和假阴性的成本。
TP = speechDetectResults (2, 2);TN = speechDetectResults (1,1);FP = speechDetectResults (1、2);FN = speechDetectResults (2, 1);speechDetectAccuracy = (TP + TN) / (TP + TN + FP + FN);speechDetectRecall = TP / (TP + FN);speechDetectPrecision = TP / (TP + FP);speechDetectF1Score = 2 * (speechDetectRecall * speechDetectPrecision) / (speechDetectRecall + speechDetectPrecision);TP = noisyvadnetResults (2, 2);TN = noisyvadnetResults (1,1); FP = noisyvadnetResults(1,2); FN = noisyvadnetResults(2,1); noisyvadnetAccuracy = (TP+TN)/(TP+TN+FP+FN); noisyvadnetRecall = TP/(TP+FN); noisyvadnetPrecision = TP/(TP+FP); noisyvadnetF1Score = 2*(noisyvadnetRecall*noisyvadnetPrecision)/(noisyvadnetRecall+noisyvadnetPrecision); figure bar(categorical([“准确性”,“回忆”起,“精度”,“F1分数”]),…[speechDetectAccuracy, noisyvadnetAccuracy;…speechDetectRecall noisyvadnetRecall;…speechDetectPrecision noisyvadnetPrecision;…speechDetectF1Score noisyvadnetF1Score]);标题(“错误分析”)传说(“speechDetect”,“noisyvadnet”位置=“bestoutside”)ylim([0.5, 1])网格在
万博1manbetx支持功能
将特征向量转换成序列
函数序列= featureBuffer(特性、featureVectorsPerSequence overlapPercent)% y = featureBuffer (x, sequenceLength overlapPercent)缓冲区的序列%的特征向量,x, sequenceLength重叠长度的序列% overlapPercent。序列输出返回数组中的一个细胞% trainNetwork的消费。featureVectorOverlap =圆(overlapPercent * featureVectorsPerSequence);hopLength = featureVectorsPerSequence - featureVectorOverlap;地板(N =(大小(功能,2)- featureVectorsPerSequence) / hopLength) + 1;序列=细胞(N, 1);idx = 1;为jj = 1: N序列{jj} =特性(:,idx: idx + featureVectorsPerSequence - 1);idx = idx + hopLength;结束结束
混合信噪比
函数[noisySignal, requestedNoise] = mixSNR(信号、噪声、比例)% (noisySignal requestedNoise] = mixSNR(信号、噪音比)返回一个吵了%的信号,noisySignal。吵闹的信号混合了%指定比率的噪音分贝。numSamples =大小(信号,1);%将噪声转化为mono噪音=意味着(噪音,2);%修剪或扩大噪声与信号的大小如果(噪音,1)> = numSamples大小%选择一个随机指数,这样你还有numSamples开始%索引后的噪音。开始=兰迪(大小(噪音,1)- numSamples + 1);噪音=噪音(启动:启动+ numSamples-1);其他的numReps =装天花板(numSamples /大小(噪音,1));temp = repmat(噪音numReps 1);开始=兰迪(大小(temp, 1) - numSamples - 1);噪音= temp(启动:启动+ numSamples-1);结束signalNorm =规范(信号);noiseNorm =规范(噪音);goalNoiseNorm = signalNorm /(10 ^(比率/ 20));因素= goalNoiseNorm / noiseNorm;requestedNoise =噪音。*因素;noisySignal = + requestedNoise信号;noisySignal = noisySignal. / max (abs (noisySignal));结束
构造信号
函数(音频,面具)= constructSignal (ds、fs、持续时间)%(音频,面具)= constructSignal (ds、fs、持续时间)构造一个音频信号%连接指定的持续时间的样本% audioDatastore ds之间的随机时间的沉默。赢得=汉明(50 e - 3 * fs,“周期”);%创建一个1000秒的训练信号通过结合多个语音文件%的训练数据集。使用detectSpeech删除不需要的部分%的每个文件。插入一段随机的演讲片段之间的沉默。% Preallocate训练信号。N = * fs持续时间;音频= 0 (N, 1);% Preallocate声音活动训练面具。值1的面具%对应样本位于语音活动的地区。值为0%对应区域没有声音的活动。掩码= 0 (N, 1);%指定最大安静段时间2秒。maxSilenceSegment = 2;%构造训练信号通过调用读取数据存储在一个循环中。numSamples = 1;而numSamples < = N数据读取(ds);=数据。/ max (abs(数据));%规模振幅%确定地区的言论idx = detectSpeech(数据、fs窗口=赢得);%如果检测到地区的言论如果~ isempty (idx)%扩展指数由5帧idx (1, - 1) = max (1、idx(1,1) - 5 *元素个数(赢得));idx (1、2) = min(长度(数据),idx(1、2) + 5 *元素个数(赢得));%隔离演讲data =数据(idx (1,1): idx (1、2);%写演讲段训练信号音频(numSamples: numSamples +元素个数(数据)1)=数据;%设置VAD基线面具(numSamples: numSamples +元素个数(数据)1)= true;%随机沉默期numSilenceSamples =兰迪(maxSilenceSegment * fs, 1,1);numSamples = numSamples +元素个数(数据)+ numSilenceSamples;结束结束音频=音频(1:N);掩码=面具(1:N);结束
引用
[1]监狱长P。“语音命令:一个公共数据集单字原图语音识别”,2017。可以从https://storage.googleapis.com/download.tensorflow.org/data/speech_commands_v0.01.tar.gz。版权2017年谷歌。语音命令数据集是创作共用署名4.0许可下的