利用深度学习网络分离鸡尾酒会信息源
这个例子展示了如何使用深度学习网络隔离语音信号。
简介
鸡尾酒会效应指的是大脑专注于一个说话者,同时过滤掉其他声音和背景噪音的能力。人类在鸡尾酒会问题上表现得很好。这个例子展示了如何使用深度学习网络从一个男性和一个女性同时说话的混合语音中分离单个说话者。
下载所需文件
在详细介绍示例之前,您将下载一个预先训练好的网络和4个音频文件。
downloadFolder = matlab.internal.examples.download万博1manbetxSupportFile(“音频”,“CocktailPartySourceSeparation.zip”);dataFolder = tempdir;unzip(下载文件夹,数据文件夹)dataset = fullfile(数据文件夹,数据文件夹)“CocktailPartySourceSeparation”);
问题总结
加载包含4千赫采样的男性和女性语音的音频文件。单独听音频文件作为参考。
[mSpeech,Fs] = audioread(fullfile(dataset, Fs)“MaleSpeech-16-4-mono-20secs.wav”));声音(mSpeech Fs)
[fSpeech] = audioread(fullfile(dataset,“FemaleSpeech-16-4-mono-20secs.wav”));声音(fSpeech Fs)
把两个语音源结合起来。确保这些源在混合中具有相同的功率。缩放混合,使其最大振幅为1。
mSpeech = mSpeech/norm(mSpeech);fSpeech = fSpeech/norm(fSpeech);ampAdj = max(abs([mSpeech;fSpeech]));mSpeech = mSpeech/ampAdj;fSpeech = fSpeech/ampAdj;mix = mSpeech + fSpeech;Mix = Mix ./max(abs(Mix));
可视化原始信号并混合信号。听混合语音信号。这个例子展示了从语音混合中提取男性和女性源的源分离方案。
t =(0:数字(mix)-1)*(1/Fs);图(1)tiledlayout(3,1) nexttile plot(t,mSpeech)“男性演讲》网格)在nexttile plot(t,fSpeech)“女性语言”网格)在Nexttile plot(t,mix)标题(“语音组合”)包含(“时间(s)”网格)在
听混音。
声音(混合,Fs)
时频表示
使用stft
来可视化男性、女性和混合语音信号的时频(TF)表示。使用长度为128的Hann窗口,FFT长度为128,重叠长度为96。
windowLength = 128;fftLength = 128;overlapLength = 96;win = hann(windowLength,“周期”);图(2)tiledlayout(3,1) nexttile stft(mSpeech,Fs,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);标题(“男性演讲》) nexttile stft(fSpeech,Fs,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);标题(“女性语言”) nexttile stft(mix,Fs,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);标题(“混合”演讲)
使用理想时频掩模的源分离
TF掩码的应用已被证明是一种有效的方法,从竞争的声音中分离所需的音频信号。TF掩码是与底层STFT相同大小的矩阵。掩码与底层STFT逐元素相乘,以隔离所需的源。TF掩码可以是二进制的,也可以是软的。
使用理想二元掩模的源分离
在理想的二进制掩码中,掩码单元格值为0或1。如果期望源的功率大于特定TF单元中其他源的功率之和,则该TF单元被设置为1。否则,单元格设置为0。
计算男性扬声器的理想二进制掩码,然后将其可视化。
P_M = stft(mSpeech,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);P_F = stft(fSpeech,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);[P_mix,F] = stft(mix,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);binarmask = abs(P_M) >= abs(P_F);图(3)plotMask(binaryMask,windowLength - overlapLength,F,Fs)
通过将混合STFT乘以男性扬声器的二进制掩码来估计男性语音STFT。通过将混合STFT乘以男性演讲者二进制掩码的倒数来估计女性演讲者的STFT。
P_M_Hard = P_mix.* binarmask;P_F_Hard = P_mix.*(1- binarmask);
使用逆短时间FFT (ISTFT)估计男性和女性音频信号。可视化估计和原始信号。听听估计的男性和女性的语音信号。
mSpeech_Hard = istft(P_M_Hard,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);fSpeech_Hard = istft(P_F_Hard,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);图(4)tiledlayout(2,2) nexttile plot(t,mSpeech)轴([t(1) t(end) -1 1])“男性原创演讲”网格)在nexttile plot(t,mSpeech_Hard) axis([t(1) t(end) -1]) xlabel(“时间(s)”)标题(“男性言语估计”网格)在nexttile plot(t,fSpeech)轴([t(1) t(end) -1])“女性原话”网格)在nexttile plot(t,fSpeech_Hard)轴([t(1) t(end) -1])“女性言语估计”)包含(“时间(s)”网格)在
声音(mSpeech_Hard Fs)
声音(fSpeech_Hard Fs)
使用理想软掩模的源分离
在软掩码中,TF掩码单元值等于所需源功率与总混合功率的比值。TF细胞的值范围为[0,1]。
计算男性扬声器的软掩码。通过将混合STFT乘以男扬声器的软掩码来估计男扬声器的STFT。通过将混合STFT乘以女演讲者的软掩码来估计女演讲者的STFT。
利用ISTFT估计男声和女声信号。
softMask = abs (P_M)。/ (abs (P_F) + abs (P_M) + eps);P_M_Soft = P_mix.*softMask;P_F_Soft = P_mix.*(1-softMask);mSpeech_Soft = istft(P_M_Soft,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);fSpeech_Soft = istft(P_F_Soft,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);
可视化估计和原始信号。听听估计的男性和女性的语音信号。请注意,结果非常好,因为掩码是在完全了解分离的男性和女性信号的情况下创建的。
图(5)tiledlayout(2,2) nexttile plot(t,mSpeech)轴([t(1) t(end) -1 1])“男性原创演讲”网格)在nexttile plot(t,mSpeech_Soft)轴([t(1) t(end) -1])“男性言语估计”网格)在nexttile plot(t,fSpeech) axis([t(1) t(end) -1]) xlabel(“时间(s)”)标题(“女性原话”网格)在nexttile plot(t,fSpeech_Soft) axis([t(1) t(end) -1]) xlabel(“时间(s)”)标题(“女性言语估计”网格)在
声音(mSpeech_Soft Fs)
声音(fSpeech_Soft Fs)
使用深度学习的掩码估计
本例中深度学习网络的目标是估计上述理想的软掩码。网络估计出该男性说话人对应的掩码。女性扬声器面具直接由男性面具衍生而来。
基本的深度学习训练方案如下所示。预测器是混合(男性+女性)音频的幅度谱。目标是与男性说话者相对应的理想软面具。回归网络使用预测器输入来最小化其输出和输入目标之间的均方误差。在输出端,音频STFT使用输出幅度谱和混合信号的相位转换回时域。
您使用短时间傅里叶变换(STFT)将音频转换到频域,窗口长度为128个样本,重叠为127个,并使用Hann窗口。通过删除负频率对应的频率样本,可以将频谱矢量的大小减小到65(因为时域语音信号是真实的,这不会导致任何信息丢失)。预测器输入由20个连续的STFT向量组成。输出是一个65 × 20的软掩码。
你使用训练过的网络来估计男性语音。输入到训练网络的是混合(男性+女性)语音音频。
STFT目标和预测器
本节说明如何从训练数据集中生成目标和预测器信号。
读取训练信号,分别由男性和女性演讲者约400秒的演讲组成,以4千赫的频率采样。低样本率用于加速训练。修剪训练信号,使它们的长度相同。
mSpeechTrain = audioread(fullfile(dataset,“malespeech - 16 - 4 - mono - 405 secs.wav”));fSpeechTrain = audioread(fullfile(dataset,“femalespeech - 16 - 4 - mono - 405 secs.wav”));L = min(长度(mSpeechTrain),长度(fSpeechTrain));mSpeechTrain = mSpeechTrain(1:L);fspeaktrain = fspeaktrain (1:L);
读取验证信号,分别由男性和女性演讲者以4千赫的频率采样,约20秒的语音组成。修剪验证信号,使它们具有相同的长度。
mSpeechValidate = audioread(fullfile(dataset,“MaleSpeech-16-4-mono-20secs.wav”));fSpeechValidate = audioread(fullfile(dataset,“FemaleSpeech-16-4-mono-20secs.wav”));L = min(length(mSpeechValidate),length(fSpeechValidate));mSpeechValidate = mSpeechValidate(1:L);fSpeechValidate = fSpeechValidate(1:L);
将训练信号缩放到相同的幂。将验证信号缩放到相同的功率。
mSpeechTrain = mSpeechTrain/norm(mSpeechTrain);fSpeechTrain = fSpeechTrain/norm(fSpeechTrain);ampAdj = max(abs([mSpeechTrain;fSpeechTrain]));mSpeechTrain = mSpeechTrain/ampAdj;fspeaktrain = fspeaktrain /ampAdj;mSpeechValidate = mspeech /norm(mSpeechValidate);fSpeechValidate = fSpeechValidate/norm(fSpeechValidate);ampAdj = max(abs([mSpeechValidate;fSpeechValidate]));mSpeechValidate = mSpeechValidate/ampAdj;fSpeechValidate = fSpeechValidate/ampAdj;
创建培训和验证“鸡尾酒会”混合。
mixTrain = mSpeechTrain + fSpeechTrain;mixTrain = mixTrain/max(mixTrain);mixValidate = mSpeechValidate + fSpeechValidate;mixValidate = mixValidate/max(mixValidate);
生成训练stft。
windowLength = 128;fftLength = 128;overlapLength = 128-1;Fs = 4000;win = hann(windowLength,“周期”);P_mix0 = abs(stft(mixTrain,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”));P_M = abs(stft(mSpeechTrain,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”));P_F = abs(stft(fSpeechTrain,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”));
取混合STFT的对数。用平均值和标准差归一化这些值。
P_mix = log(P_mix0 + eps);MP = mean(P_mix(:));SP = std(P_mix(:));P_mix = (P_mix - MP)/SP;
生成验证stft。取混合STFT的对数。用平均值和标准差归一化这些值。
P_Val_mix0 = stft(mixValidate,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”);P_Val_M = abs(stft(mSpeechValidate,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”));P_Val_F = abs(stft(fSpeechValidate,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”));P_Val_mix0 = log(abs(P_Val_mix0) + eps);MP = mean(P_Val_mix(:));SP = std(P_Val_mix(:));P_Val_mix = (P_Val_mix - MP) / SP;
训练神经网络是最容易的,当网络的输入有一个合理的平滑分布和归一化。为了检查数据分布是否平滑,绘制训练数据的STFT值的直方图。
图(6)直方图(P_mix EdgeColor =“没有”归一化=“pdf”)包含(“输入值”) ylabel (“概率密度”)
计算训练软掩码。在训练网络时使用此掩码作为目标信号。
maskTrain = P_M。/(P_M + P_F + eps);
计算验证软掩码。使用此掩码来评估训练网络发出的掩码。
maskValidate = P_Val_M。/(P_Val_M + P_Val_F + eps);
为了检查目标数据分布是否平滑,绘制训练数据掩码值的直方图。
图(7)直方图(maskTrain EdgeColor =“没有”归一化=“pdf”)包含(“输入值”) ylabel (“概率密度”)
从预测器和目标信号中创建大小(65,20)的块。为了获得更多的训练样本,在连续的块之间使用10个片段的重叠。
seqLen = 20;seqOverlap = 10;mixSequences = 0 (1 + fftLength/2,seqLen,1,0);maskSequences = 0 (1 + fftLength/2,seqLen,1,0);Loc = 1;而loc < size(P_mix,2) - seqLen mixSequences(:,:,:,end+1) = P_mix(:,loc:loc+seqLen-1);maskSequences(:,:,:,结束+ 1)= maskTrain (:, loc: loc + seqLen-1);loc = loc + seqOverlap;结束
从验证预测器和目标信号中创建大小为(65,20)的块。
mixValSequences = 0 (1 + fftLength/2,seqLen,1,0);maskValSequences = 0 (1 + fftLength/2,seqLen,1,0);seqOverlap = seqLen;Loc = 1;而loc < size(P_Val_mix,2) - seqLen mixValSequences(:,:,:,end+1) = P_Val_mix(:,loc:loc+seqLen-1);maskValSequences(:,:,:,end+1) = maskValidate(:,loc:loc+ sequlen -1);loc = loc + seqOverlap;结束
重塑培训和验证信号。
mixSequencesT =重塑(mixSequences,[1 1 (1 + fftLength/2)*seqLen size(mixSequences,4)]);mixSequencesV =重塑(mixValSequences,[1 1 (1 + fftLength/2)*seqLen size(mixValSequences,4)]);maskSequencesT =重塑(maskSequences,[1 1 (1 + fftLength/2)*seqLen size(maskSequences,4)]);maskSequencesV =重塑(maskValSequences,[1 1 (1 + fftLength/2)*seqLen size(maskValSequences,4)]);
定义深度学习网络
定义网络的层。指定输入大小为1 × 1 × 1300的图像。定义两个隐藏的全连接层,每个层有1300个神经元。每个隐藏的全连接层后面都有一个sigmoid层。批归一化层对输出的均值和标准差进行归一化。添加一个具有1300个神经元的完全连接层,然后是回归层。
numNodes = (1 + fftLength/2)*seqLen;层= [...imageInputLayer([1 1 (1 + fftLength/2)*seqLen],归一化=“没有”) fullyConnectedLayer(numNodes) BiasedSigmoidLayer(6) batchNormalizationLayer dropoutLayer(0.1) fullyConnectedLayer(numNodes) BiasedSigmoidLayer(6) batchNormalizationLayer dropoutLayer(0.1) fullyConnectedLayer(numNodes) BiasedSigmoidLayer(0) regressionLayer];
为网络指定培训选项。集MaxEpochs
来3.
这样网络对训练数据进行了三次处理。集MiniBatchSize
来64
这样网络就会看到64
每次训练信号。集情节
来训练进步
生成随迭代次数增加而显示训练进度的图。集详细的
来假
禁用将与图中显示的数据相对应的表输出打印到命令行窗口。集洗牌
来every-epoch
在每个纪元开始时,对训练序列进行洗牌。集LearnRateSchedule
来分段
每次经过一定数量的epoch(1)时,将学习率降低指定的因子(0.1)。集ValidationData
到验证预测器和目标。集ValidationFrequency
使验证均方误差每epoch计算一次。本例使用自适应矩估计(ADAM)求解器。
maxEpochs = 3;miniBatchSize = 64;选项= trainingOptions(“亚当”,...MaxEpochs = MaxEpochs,...MiniBatchSize = MiniBatchSize,...SequenceLength =“最长”,...洗牌=“every-epoch”,...Verbose = 0,...情节=“训练进步”,...ValidationFrequency =地板(大小(mixSequencesT 4) / miniBatchSize),...ValidationData = {mixSequencesV, maskSequencesV},...LearnRateSchedule =“分段”,...LearnRateDropFactor = 0.9,...LearnRateDropPeriod = 1);
训练深度学习网络
使用指定的训练选项和层结构训练网络trainNetwork
.由于训练集很大,训练过程可能需要几分钟。要加载预训练的网络,请设置speedupExample
来真正的
.
speedupExample =假;如果speedupExample CocktailPartyNet = trainNetwork(mixSequencesT,maskSequencesT,layers,options);其他的S = load(fullfile(dataset,“CocktailPartyNet.mat”));CocktailPartyNet = s.c octailpartynet;结束
将验证预测器传递给网络。输出是估计的掩码。重塑估计的面具。
estimatedMasks0 = predict(鸡尾酒派对网,mixSequencesV);estimatedMasks0 = estimatedMasks0.';estimatedMasks0 =重塑(estimatedMasks0,1 + fftLength/2, nummel (estimatedMasks0)/(1 + fftLength/2));
评估深度学习网络
绘制实际和预期掩码之间误差的直方图。
图(8)直方图(maskValSequences(:) - estimatedMasks0(:),EdgeColor=“没有”归一化=“pdf”)包含(“面具错误”) ylabel (“概率密度”)
评估软掩码估计
估计男性和女性软面具。通过对软掩码进行阈值估计男性和女性二元掩码。
SoftMaleMask = estimatedMasks0;SoftFemaleMask = 1 - SoftMaleMask;
缩短混合STFT以匹配估计掩码的大小。
P_Val_mix0 = P_Val_mix0(:,1:size(SoftMaleMask,2));
将混合STFT与男性软掩码相乘,得到估计的男性语音STFT。
P_Male = P_Val_mix0.*SoftMaleMask;
使用ISTFT得到估计的男性音频信号。缩放音频。
maleSpeech_est_soft = istft(P_Male,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”, ConjugateSymmetric = true);maleSpeech_est_soft = maleSpeech_est_soft/max(abs(maleSpeech_est_soft));
确定要分析的范围和相关的时间向量。
range = windowLength:numel(maleSpeech_est_soft)-windowLength;t = range*(1/Fs);
可视化估计的和原始的男性语音信号。听听估计软面具男讲话。
sound(maleSpeech_est_soft(range),Fs) figure(9) tiledlayout(2,1) nexttile plot(t,mSpeechValidate(range)) title(“男性原创演讲”)包含(“时间(s)”网格)在nexttile plot(t,maleSpeech_est_soft(range)) xlabel(“时间(s)”)标题(“男性言语评估(软面具)”网格)在
将混合STFT与女性软掩码相乘,得到估计的女性语音STFT。使用ISTFT得到估计的男性音频信号。缩放音频。
P_Female = P_Val_mix0.*SoftFemaleMask;femaleSpeech_est_soft = istft(P_Female,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”, ConjugateSymmetric = true);femaleSpeech_est_soft = femaleSpeech_est_soft/max(femaleSpeech_est_soft);
想象一下估计的和原始的女性信号。听一听估计的女性讲话。
sound(femaleSpeech_est_soft(range),Fs) figure(10) tiledlayout(2,1) nexttile plot(t,fSpeechValidate(range)) title(“女性原话”网格)在nexttile plot(t,femaleSpeech_est_soft(range))“时间(s)”)标题(“女性言语估计(软面具)”网格)在
计算二进制掩码估计
通过对软掩码进行阈值估计男性和女性二元掩码。
HardMaleMask = SoftMaleMask >= 0.5;HardFemaleMask = SoftMaleMask < 0.5;
将混合STFT与男性二进制掩码相乘,得到估计的男性语音STFT。使用ISTFT得到估计的男性音频信号。缩放音频。
P_Male = P_Val_mix0.*HardMaleMask;maleSpeech_est_hard = istft(P_Male,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”, ConjugateSymmetric = true);maleSpeech_est_hard = maleSpeech_est_hard/max(maleSpeech_est_hard);
可视化估计的和原始的男性语音信号。听估计的二进制掩码男性语音。
sound(maleSpeech_est_hard(range),Fs) figure(11) tiledlayout(2,1) nexttile plot(t,mSpeechValidate(range)) title(“男性原创演讲”网格)在nexttile plot(t,maleSpeech_est_hard(range)) xlabel(“时间(s)”)标题(男性言语估计(二进制掩码)网格)在
将混合STFT与女性二进制掩码相乘,得到估计的男性语音STFT。使用ISTFT得到估计的男性音频信号。缩放音频。
P_Female = P_Val_mix0.*HardFemaleMask;femaleSpeech_est_hard = istft(P_Female,Window=win,OverlapLength= OverlapLength,FFTLength= FFTLength,FrequencyRange=“单向的”, ConjugateSymmetric = true);female espeech_est_hard = femaleSpeech_est_hard/max(femaleSpeech_est_hard);
可视化估计和原始的女性语音信号。听一听估计的女性讲话。
sound(femaleSpeech_est_hard(range),Fs) figure(12) tiledlayout(2,1) nexttile plot(t,fSpeechValidate(range)) title(“女性原话”网格)在nexttile plot(t,femaleSpeech_est_hard(range))“女性言语估计(二元掩码)”网格)在
分别比较混合、原始女性和男性、估计女性和男性一秒段的STFTs。
Range = 7e4:7.4e4;图(13)stft (mixValidate(范围),Fs,窗口=赢,OverlapLength = 64, FFTLength = FFTLength FrequencyRange =“单向的”);标题(“混合STFT”)
图(14)tiledlayout(3,1) nexttile stft(mSpeechValidate(range),Fs,Window=win,OverlapLength=64,FFTLength= FFTLength,FrequencyRange=“单向的”);标题(“男性STFT(实际)”) nexttile stft(maleSpeech_est_soft(range),Fs,Window=win,OverlapLength=64,FFTLength= FFTLength,FrequencyRange=“单向的”);标题(男性STFT(估计-软口罩)) nexttile stft(maleSpeech_est_hard(range),Fs,Window=win,OverlapLength=64,FFTLength= FFTLength,FrequencyRange=“单向的”);标题(男性STFT(估计-二进制掩码));
图(15)tiledlayout(3,1) nexttile stft(fSpeechValidate(range),Fs,Window=win,OverlapLength=64,FFTLength= FFTLength,FrequencyRange=“单向的”);标题(“女性STFT(实际)”) nexttile stft(femaleSpeech_est_soft(range),Fs,Window=win,OverlapLength=64,FFTLength= FFTLength,FrequencyRange=“单向的”);标题(女性STFT(估计-软面膜)) nexttile stft(femaleSpeech_est_hard(range),Fs,Window=win,OverlapLength=64,FFTLength= FFTLength,FrequencyRange=“单向的”);标题(女性STFT(估计-二进制掩码))
参考文献
[1]“卷积深度神经网络中的概率二元掩码鸡尾酒会源分离”,Andrew J.R. Simpson, 2015。