主要内容

使用深度学习网络代谢讲话

这个例子展示了如何使用深度学习网络去噪语音信号。本例比较了适用于同一任务的两种网络:完全连接网络和卷积网络。

介绍

言语去噪的目的是消除语音信号的噪声,同时提高语音的质量和可懂度。该示例展示了使用深度学习网络从语音信号中移除洗衣机噪声。本例比较了适用于同一任务的两种网络:完全连接网络和卷积网络。

问题摘要

考虑以下以8khz采样的语音信号。

[Cleanaudio,FS] = audioread(“speemdft-16-8-mono-5secs.wav”);声音(CleanAudio,FS)

将洗衣机噪声添加到语音信号。设置噪声功率,使得信噪比(SNR)为零DB。

噪音= audioread(“洗衣机- 16 - 8 mono - 1000 - secs.mp3”);%从噪声文件中的随机位置提取噪声段ind = randi(numel(noise) - numel(cleanAudio) + 1,1,1);噪声=噪声(ind:ind + numel(cleanAudio) - 1);speechPower =总和(cleanAudio。^ 2);noisePower =总和(noiseSegment。^ 2);noisyAudio = cleanAudio + sqrt(speechPower/noisePower) * noisessegment;

听嘈杂的语音信号。

声音(noisyAudio fs)

将原始信号和噪声信号可视化。

t =(1 / fs)*(0:numel(cleanaudio)-1);子图(2,1,1)绘图(T,CleanAudio)标题(“干净音频”) 网格次要情节(2,1,2)情节(t, noisyAudio)标题(“嘈杂的音频”)包含(“时间”) 网格

语音去噪的目的是从语音信号去除洗衣机噪声,同时最小化输出语音中的不期望的伪像。

检查数据集

这个例子使用了Mozilla Common Voice数据集的一个子集[1]来训练和测试深度学习网络。数据集包含受试者说短句的48千赫录音。下载数据集并解压缩下载的文件。

URL =.'http://ssd.mathwands.com/金宝appsupportfiles/audio/commonvoice.zip';downloadFolder = tempdir;dataFolder = fullfile (downloadFolder,'commonvoice');如果〜存在(DataFolder,'dir')disp('下载数据集(956 MB)......'解压缩(url, downloadFolder)结尾

audiodatastore.为训练集创建数据存储。要以性能为代价提高示例的运行速度,请设置reduceDataset真正的

adstrain = audiodataStore(fullfile(datafolder,'火车'),'insertumbfolders',真的);DEFERATASET =真正的;如果SDENTATASET ADSTRAIN = SHUFFLE(adstrain);adstrain =子集(adstrain,1:1000);结尾

获取数据存储区中第一个文件的内容。

[音频,adstraininfo] =读(adstrain);

听听语音信号。

声音(音频、adsTrainInfo.SampleRate)

绘制语音信号。

图t =(1 / adstraininfo.samplege)*(0:numel(音频)-1);plot(t,音频)标题(“例如语音信号”)包含(“时间”) 网格

深度学习系统概述

基本的深度学习训练方案如下所示。请注意,由于语音通常低于4khz,您首先将干净和嘈杂的音频信号采样到8khz,以减少网络的计算负载。预测信号和目标网络信号分别是噪声音频信号和干净音频信号的幅谱。网络的输出是去噪信号的幅度谱。回归网络利用预测器的输入来最小化其输出和输入目标之间的均方误差。使用输出幅度谱和噪声信号的相位将去噪音频转换回时域[2]。

您使用短时傅里叶变换(STFT)将音频转换为频域,窗口长度为256个样本,重叠为75%,垂直窗口。通过丢弃对应于负频率的频率样本(因为时域语音信号是真实的,将光谱矢量的大小降低到129(因为时域语音信号是真实的,这不会导致任何信息丢失)。预测器输入由8个连续的噪声STFT向量组成,从而基于当前嘈杂的STFT和7上噪声STFT向量来计算每个STFT输出估计。

STFT目标和预测因子

本节演示如何从一个训练文件中生成目标和预测器信号。

首先,定义系统参数:

windowlength = 256;win =汉明(WindowLength,“定期”);重叠= round(0.75 * windowLength);ffTLength = windowLength;inputFs = 48 e3;fs = 8 e3;numFeatures = ffTLength/2 + 1;numSegments = 8;

创建一个dsp。SampleRateConverter将48khz的音频转换为8khz。

src = dsp.samplerateconverter(“inputsamplerate”inputFs,...“OutputSampleRate”,fs,...“带宽”,7920);

从数据存储中获取音频文件的内容。

音频=阅读(adsTrain);

确保音频长度是采样率转换器抽取系数的倍数。

decimationFactor = inputFs / fs;L =地板(元素个数(音频)/ decimationFactor);音频=音频(1:decimationFactor * L);

将音频信号转换为8 kHz。

音频= src(音频);重置(src)

从洗衣机噪声向量中创建随机噪声段。

Randind = randi(numel(noise) - numel(audio),[1 1]);噪声(randind: randind + numel(audio) - 1);

在语音信号中加入噪声,使信噪比为0db。

noisePower =总和(noiseSegment。^ 2);cleanPower =总和(音频。^ 2);* sqrt(cleanPower/noisePower); / /噪声功率noisyAudio =音频+ noisessegment;

stft从原始和嘈杂的音频信号生成幅度STFT向量。

CleanStft = Stft(音频,“窗口”,赢,“OverlapLength”,交叠,'fftlength',FFTLength);CleanStft = ABS(CleanStft(NumFeatures-1:结束,:));Noisystft = Stft(Noisyaudio,“窗口”,赢,“OverlapLength”,交叠,'fftlength',FFTLength);noisystft = abs(noisystft(numfeatures-1:结束,:));

从嘈杂的STFT生成8段训练预测信号。连续预测器之间的重叠是7个段。

noisystft = [noisystft(:,1:namegments  -  1),诺斯Ystft];Stftegments =零(NumFeatures,Numegments,尺寸(Noisystft,2) -  Numsegments + 1);为了索引= 1:大小(诺斯YSTFT,2) -  NumSegments + 1 Stftegments(::,索引)=(诺斯YSTFT(:,索引:索引+ Numegments  -  1));结尾

设定目标和预测指标。两个变量的最后一个维度对应于音频文件生成的不同预测器/目标对的数量。每个预测器是129 × 8,每个目标是129 × 1。

目标= CleanStft;尺寸(目标)
ans =.1×2129 544.
预测器= Stftegments;大小(预测器)
ans =.1×3129 8 544

使用高大数组提取特征

为了加速处理,使用高阵列从数据存储中的所有音频文件的语音段中提取特征序列。与内存阵列不同,高大阵列通常保持未评估,直到您拨打电话收集功能。此延迟评估使您可以使用大数据集快速工作。当您最终请求输出时收集, MATLAB结合排队计算在可能的地方,并采取最小的次数通过数据。如果您有Parallel Computing Toolbox™,您可以在本地MATLAB会话或本地并行池中使用高数组。如果您安装了MATLAB®Parallel Server™,您还可以在集群上运行大型阵列计算。

首先,将数据存储转换为高大的数组。

重置(adstrain)t = tall(adstrain)
使用“本地”配置文件启动并行池(Parpool)连接到并行池(工人数:6)。
t = m×1高级小区{234480×1 double} {210288×1 double} {282864×1 double} {292080×1 double} {410736×1 double} {303600×1 double} {326640×1 double}{233328×1双} ::::::::::::

显示屏指示行数(对应于数据存储区中的文件数),尚不清楚。在计算完成之前,M是占位符。

从高层桌子中提取目标和预测器幅度速率。此操作创建新的高阵列变量以在后续计算中使用。功能HelpergeneratesPeepeehoisingFeatures.执行已经突出显示的步骤STFT目标和预测因子部分。的Cellfun.命令适用于HelpergeneratesPeepeehoisingFeatures.到数据存储中每个音频文件的内容。

[靶标,预测器] = Cellfun(@(x)辅助术治疗(x,噪声,src),t,“统一输出”、假);

收集评估目标和预测因子。

[目标,预测器] =聚集(目标,预测器);
使用并行池“本地”评估高表达: -  PASS 1为1:42秒评估完成1分36秒

良好的做法是以零平均值和单位标准偏差标准化所有特征。

计算预测器和目标的平均值和标准偏差,并使用它们来标准化数据。

预测=猫({}):3,预测指标;noisyMean =意味着(预测(:));noisyStd =性病(预测(:));predictors(:) = (predictors(:) - noisyMean)/noisyStd;目标=猫({}):2、目标;cleanMean =意味着(目标(:));cleanStd =性病(目标(:));targets(:) = (targets(:) - cleanMean)/cleanStd;

重塑预测器和深度学习网络预期的尺寸的目标。

预测=重塑(预测、大小(预测,1),大小(预测,2),1,大小(预测,3));目标=重塑(目标1 1、大小(目标1),大小(目标2));

您将在培训期间使用1%的数据进行验证。验证可用于检测网络过度接收培训数据的情况。

将数据随机分成训练集和验证集。

inds = randperm(大小(预测器,4));L =圆形(0.99 *尺寸(预测器,4));TrainPredictors =预测因子(::::,Inds(1:L));三raintargets=目标(::::,INDS(1:L));validatepredictors =预测器(:,:,:,inds(l + 1:结束));validatetargets = targets(:,::,Inds(L + 1:结束));

全连通层语音去噪

首先考虑一个由完全连接的图层组成的去噪网络。完全连接层中的每个神经元连接到前一层的所有激活。完全连接的层将输入乘以权重矩阵,然后添加偏置向量。重量矩阵和偏置载体的尺寸由层中的神经元数和来自前一层的激活的数量确定。

定义网络的图层。指定输入大小为大小的图像numfeatures.-经过-NumSegments(在这个例子中129-by-8)。定义两个隐藏的完全连接的层,每个层都有1024个神经元。由于纯粹的线性系统,请使用整流的线性单元(Relu)层遵循每个隐藏的完全连接的层。批量归一化层标准化输出的平均值和标准偏差。用129神经元添加完全连接的层,然后是回归层。

layers = [imageInputLayer([numFeatures,numSegments]) fullconnectedlayer (1024) batchNormalizationLayer reluLayer fullconnectedlayer (1024) batchNormalizationLayer reluLayer fullconnectedlayer (numFeatures) regressionLayer];

接下来,指定网络的培训选项。放maxepochs.3.因此,网络使3通过培训数据。放小匹匹匹匹配128因此,网络一次查看128个训练信号。指定情节作为“训练进步”生成显示随着迭代次数增加的训练进度的图。放verb错误的禁用将与图中显示的数据相对应的表输出打印到命令行窗口。指定洗牌作为“每个时代”在每个时代开始时播放训练序列。指定LearnRateSchedule“分段”每次通过一定数量的时期(1)都会通过指定因素(0.9)减少学习率。放验证数据到验证预测器和目标。放ValidationFrequency这样,验证均方误差每历元计算一次。这个例子使用了自适应矩估计(Adam)求解器。

miniBatchSize = 128;选项=培训选项(“亚当”...“maxepochs”,3,...“initiallearnrate”1 e-5...“迷你atchsize”,小匹马,...“洗牌”“每个时代”...“情节”“训练进步”...“verbose”假的,...“ValidationFrequency”、地板(大小(trainPredictors, 4) / miniBatchSize),...“LearnRateSchedule”“分段”...“学习ropfactor”,0.9,...“LearnRateDropPeriod”,1,...“validationdata”,{validatepredictors,validatetargets});

使用指定的培训选项和图层架构培训网络Trainnetwork..因为训练集很大,培训过程可能需要几分钟。要下载并加载预先培训的网络,而不是从头开始培训网络用圆形错误的

doTraining =真正的;如果doTraining denoiseNetFullyConnected = trainNetwork(trainPredictors,trainTargets,layers,options);别的URL =.“http://ssd.mathworks.com/金宝appsupportfiles/audio/SpeechDenoising.zip”;downloadNetFolder = tempdir;netFolder = fullfile (downloadNetFolder,“SpeechDenoising”);如果〜存在(NetFolder,'dir')disp('下载掠夺网络(1文件 -  8 MB)......'解压缩(url, downloadNetFolder)结尾s = load(fullfile(netfolder,“denoisenet.mat”));denoisenetlulyconnected = s.denoisenetlulyconnected;cleanMean = s.cleanMean;cleanStd = s.cleanStd;noisyMean = s.noisyMean;Noisystd = S.Noisystd;结尾

计算网络的完全连接层中的权重数。

数字= 0;为了指数= 1:元素个数(denoiseNetFullyConnected.Layers)如果ISA(denoisenetluelyconnected.layers(指数),“nnet.cnn.layer.fulleConnectedLayer”)Numweights = Numpeights + Numel(denoisenetluelyconnected.layers(索引).weights);结尾结尾fprintf(“权重的数量是%d。\ n”,数字);
权重的个数为2237440。

基于卷积层的语音去噪

考虑一个使用卷积层而不是完全连接层的网络[3.]。2-D卷积层将滑动滤波器应用于输入。该图层通过垂直和水平沿输入沿输入和计算重量和输入的点乘积来使滤波器旋转输入,然后添加偏置术语。卷积层通常由比完全连接的层更少的参数组成。

定义[中描述的完全卷积网络的层3.],由16个卷积层组成。前15个卷积层为3层组,重复5次,滤波器宽度分别为9、5、9,滤波器个数分别为18、30、8。最后一个卷积层的滤波宽度为129,滤波宽度为1。在这个网络中,卷积只在一个方向上执行(沿频率维),并且除第一个层外,所有层沿时间维的滤波器宽度都设置为1。与全连接网络类似,卷积层之后是ReLu层和批处理归一化层。

layers = [imageInputLayer([numFeatures,numSegments])卷积2dlayer ([9 8],18,“步幅”100年[1],“填充”“相同的”)BatchnormalizationLayer Rubulayer Repmat(...30岁的[convolution2dLayer (1 [5]“步幅”100年[1],“填充”“相同的”) batchNormalizationLayer relullayer convolution2dLayer([9 1],8,“步幅”100年[1],“填充”“相同的”)BatchnormalizationLayer Rufulayer卷积2dlayer([9 1],18,“步幅”100年[1],“填充”“相同的”)卷积2dlayer ([5 1],30,“步幅”100年[1],“填充”“相同的”) batchNormalizationLayer relullayer convolution2dLayer([9 1],8,“步幅”100年[1],“填充”“相同的”) batchNormalizationLayer relullayer convolution2dLayer([129 1],1,“步幅”100年[1],“填充”“相同的”) regressionLayer);

训练选项与全连接网络的选项相同,除了验证目标信号的维数被排列成与回归层期望的维数一致。

选项=培训选项(“亚当”...“maxepochs”,3,...“initiallearnrate”1 e-5...“迷你atchsize”,小匹马,...“洗牌”“每个时代”...“情节”“训练进步”...“verbose”假的,...“ValidationFrequency”、地板(大小(trainPredictors, 4) / miniBatchSize),...“LearnRateSchedule”“分段”...“学习ropfactor”,0.9,...“LearnRateDropPeriod”,1,...“validationdata”,{validatePredictors,permute(validatetargs,[3 1 2 4])});

使用指定的培训选项和图层架构培训网络Trainnetwork..因为训练集很大,培训过程可能需要几分钟。要下载并加载预先培训的网络,而不是从头开始培训网络用圆形错误的

doTraining =真正的;如果DotraindeNoisenetluelyConvolutional = Trainnetwork(TrainPredictors,换算(三raintargets,[3 1 2 4]),层,选择);别的URL =.“http://ssd.mathworks.com/金宝appsupportfiles/audio/SpeechDenoising.zip”;downloadNetFolder = tempdir;netFolder = fullfile (downloadNetFolder,“SpeechDenoising”);如果〜存在(NetFolder,'dir')disp('下载掠夺网络(1文件 -  8 MB)......'解压缩(url, downloadNetFolder)结尾s = load(fullfile(netfolder,“denoisenet.mat”));denoiseNetFullyConvolutional = s.denoiseNetFullyConvolutional;cleanMean = s.cleanMean;cleanStd = s.cleanStd;noisyMean = s.noisyMean;Noisystd = S.Noisystd;结尾

计算网络的完全连接层中的权重数。

数字= 0;为了index = 1:numel(denoisenetluelycollevolutional.layers)如果ISA(DenoisenetluelyConvolulyAl.Layers(Index),“nnet.cnn.layer.Convolution2DLayer”)Numweights = Numweights + Numel(denoisenetfullyconstoolvolultal.layers(索引)。重量);结尾结尾fprintf(“卷积层中的权重的数量为%d \ n”,数字);
convolutional layer中的weights个数为31812

测试去噪网络

读取测试数据集。

adsTest = audioDatastore (fullfile (dataFolder'测试'),'insertumbfolders',真的);

从数据存储中读取文件的内容。

[cleanAudio, adsTestInfo] =阅读(adsTest);

确保音频长度是采样率转换器抽取系数的倍数。

L =楼层(Numel(Cleanaudio)/ DecimationFactor);CleanAudio = CleanAudio(1:DecimationFactor * L);

将音频信号转换为8 kHz。

cleanAudio = src (cleanAudio);重置(src)

在这个测试阶段,您腐败了训练阶段的洗衣机噪音的语音。

噪音= audioread(“洗衣机- 16 - 8 mono - 200 - secs.mp3”);

从洗衣机噪声向量中创建随机噪声段。

randind = randi(numel(噪声) -  numel(cleanaudio),[1 1]);noisesement =噪音(Randind:Randind + Numel(CleanAudio) -  1);

在语音信号中加入噪声,使信噪比为0db。

noisePower =总和(noiseSegment。^ 2);CleanPower = Sum(CleanAudio。^ 2);* sqrt(cleanPower/noisePower); / /噪声功率Noisyaudio = Cleanaudio + Noisesement;

stft从嘈杂的音频信号产生幅度STFT向量。

Noisystft = Stft(Noisyaudio,“窗口”,赢,“OverlapLength”,交叠,'fftlength',FFTLength);noisyphase =角度(noisystft(numfeatures-1:结束,:));noisystft = abs(noisystft(numfeatures-1:结束,:));

从嘈杂的STFT生成8段训练预测信号。连续预测器之间的重叠是7个段。

噪声ystft =[噪声ystft (:,1:numSegments-1)噪声ystft];predictors = 0 (numFeatures, numSegments, size(noisySTFT,2) - numSegments + 1);为了index = 1 :(大小(诺斯YSTFT,2) -  NumSegments + 1)预测器(:,索引)=诺斯YSTFT(:,索引:索引+ NumSegments  -  1);结尾

用训练阶段计算的平均值和标准偏差对预测变量进行归一化。

预测器(:) =(预测器(:)  -  Noisemean)/诺斯YSTD;

通过使用计算去噪幅度stft预测有两个训练有素的网络。

predictors =重塑(predictors, [numFeatures,numSegments,1,size(predictors,3)]);STFTFullyConnected = predict(denoiseNetFullyConnected, predictors);STFTFullyConvolutional = predict(denoiseNetFullyConvolutional, predictors);

通过培训阶段中使用的平均值和标准偏差来缩放输出。

stftifulleconnected(:) = cleanstd * stftifulleconnected(:) + cleanmean;stftfullyconoloollyal(:) = Cleanstd * stftfullfollyal(:) +洁净模具;

将单向短时傅里叶变换为中心短时傅里叶变换。

stftfullyconnected = stftiflyconnected。。* exp(1J * Noisyphase);stftfullyconnected = [结合(stftifulleconnected(结束-1:-1:2,:));stftfulleconnected];stftfullyconvolultal =挤压(stftfullfullycollyal)。* exp(1j * noisyphase);stftfullyconstvolutional = [结合(stftfullfollownolultal(end-1:-1:2,:));stftfullecollyal];

计算去噪语音信号。istft.执行逆stft。使用嘈杂的stft向量的阶段重建时域信号。

denoisedaudiofullyconnected = istft(stftifulleconnected,...“窗口”,赢,“OverlapLength”,交叠,...'fftlength',fftlength,'缀合致密的',真的);denoisedaudiofullyconvolutional = istft(stftfullfollycollyal,...“窗口”,赢,“OverlapLength”,交叠,...'fftlength',fftlength,'缀合致密的',真的);

绘制干净,嘈杂和去噪的音频信号。

t =(1 / fs)*(0:numel(denoisedaudiofullyconnected)-1);图形子图(4,1,1)绘图(T,CleanAudio(1:Numel(DenoisedAudiofullyConnected))标题(“干净的演讲》) 网格子图(4,1,2)绘图(T,Noisyaudio(1:Numel(DenoisedAudiofullyConnected))标题(“吵闹的演讲”) 网格子图(4,1,3)绘图(T,DenoisedaudiofullyConnected)标题(“去噪语言(完全连接的层)”) 网格子图(4,1,4)绘图(T,Denoisedaudiofullycollyalcollyal)标题(“去噪(卷积层)”) 网格Xlabel(“时间”

绘制干净,嘈杂和去噪谱图。

h =图;子图(4,1,1)频谱图(CleanAudio,Win,重叠,FFTLength,FS);标题(“干净的演讲》) 网格子图(4,1,2)频谱图(Noisyaudio,Win,Recordap,FFTLength,FS);标题(“吵闹的演讲”) 网格次要情节(4 1 3)谱图(ffTLength denoisedAudioFullyConnected,赢,重叠,fs);标题(“去噪语言(完全连接的层)”) 网格次要情节(4,4)谱图(ffTLength denoisedAudioFullyConvolutional,赢,重叠,fs);标题(“去噪(卷积层)”) 网格p = get(h,'位置');套(H,'位置',[p(1) 65 p(3) 800]);

听那嘈杂的演讲。

声音(noisyAudio fs)

从具有完全连接层的网络中收听去噪语音。

声音(denoisedAudioFullyConnected fs)

用卷积层聆听来自网络的去噪语音。

声音(denoisedAudioFullyConvolutional fs)

听干净的演讲。

声音(CleanAudio,FS)

您可以通过调用来测试来自数据存储的更多文件testdenoisingnets..该功能产生上面突出显示的时域和频域图,并返回清洁,嘈杂和去噪音频信号。

[Cleanaudio,Noisyaudio,Denoisedaudiofullyconnected,Denoisedautofullycollyal] = STAYDENOINCENET(腺体,DESOENETFLUETECLUETCLED,DENOISENETFLUELECOLLEAL,NOISYMEN,NOISYSTD,Cleanmean,Cleanstd);

实时应用

上一节的程序将噪声信号的整个频谱传递到预测.这不适用于要求低延迟的实时应用程序。

运行speechDenoisingRealtimeApp举例说明如何模拟流式,实时版本的去噪网络。该应用程序使用了层间完全连接的网络。音频帧长度等于STFT跳数大小,即0.25 * 256 = 64个采样。

speechDenoisingRealtimeApp启动旨在与模拟交互的用户界面(UI)。UI使您可以调整参数,结果立即反映在模拟中。您还可以启用/禁用在去噪输出上操作的噪声门,以进一步降低噪声,以及调整噪声门的攻击时间,释放时间和阈值。您可以从UI中收听嘈杂,清洁或去噪音频。

范围绘制干净,嘈杂和去噪的信号,以及噪声门的增益。

参考

[1]https://voice.mozilla.org/en.

[2]“基于深度学习的语音去噪实验”,Liu Ding, Paris Smaragdis, Minje Kim, INTERSPEECH, 2014。

[3]“讲话增强的全卷积神经网络”,蔡里姆公园,金赢了李,三通,2017年。