Разделение источников коктейлей с использованием Нейронных сетей для глубокого обучения

Этот пример показывает, как изолировать речевой сигнал с помощью нейронной сети для глубокого обучения.

Введение

Эффект коктейльной вечеринки относится к способности мозга фокусироваться на одном динамике, фильтруя при этом другие голоса и фоновый шум. Люди очень хорошо выступают на коктейльной вечеринке. Этот пример показывает, как использовать нейронную сеть для глубокого обучения, чтобы отделить отдельных дикторов от речевой смеси, где одновременно говорят один мужчина и одна женщина.

Загрузить необходимые файлы

Прежде чем подробно войти в пример, вы загрузите предварительно обученную сеть и 4 аудио файлов.

url = 'http://ssd.mathworks.com/supportfiles/audio/CocktailPartySourceSeparation.zip';

downloadNetFolder = tempdir;
netFolder = fullfile(downloadNetFolder,'CocktailPartySourceSeparation');

if ~exist(netFolder,'dir')
    disp('Downloading pretrained network and audio files (5 files - 24.5 MB) ...')
    unzip(url,downloadNetFolder)
end

Сводные данные проблем

Загрузка аудио файлов, содержащего мужскую и женскую речь, дискретизированную с частотой дискретизации 4 кГц. Слушайте аудио файлов индивидуально для ссылки.

[mSpeech,Fs] = audioread(fullfile(netFolder,"MaleSpeech-16-4-mono-20secs.wav"));
sound(mSpeech,Fs)
[fSpeech] = audioread(fullfile(netFolder,"FemaleSpeech-16-4-mono-20secs.wav"));
sound(fSpeech,Fs)

Объедините два источника речи. Убедитесь, что источники имеют равную степень в смеси. Нормализуйте смесь так, чтобы ее максимальная амплитуда была единицей.

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:numel(mix)-1)*(1/Fs);

figure(1)
subplot(3,1,1)
plot(t,mSpeech)
title("Male Speech")
grid on
subplot(3,1,2)
plot(t,fSpeech)
title("Female Speech")
grid on
subplot(3,1,3)
plot(t,mix)
title("Speech Mix")
xlabel("Time (s)")
grid on

Слушайте микс аудио.

sound(mix,Fs)

Частотно-временное представление

Использование stft визуализировать представление частотно-временных (TF) мужских, женских и смешанных речевых сигналов. Используйте окно Ханна длины 128, длину БПФ 128 и длину перекрытия 96.

WindowLength  = 128;
FFTLength     = 128;
OverlapLength = 96;
win           = hann(WindowLength,"periodic");

figure(2)
subplot(3,1,1)
stft(mSpeech, Fs, 'Window', win,'OverlapLength',OverlapLength,...
     'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
title("Male Speech")
subplot(3,1,2)
stft(fSpeech, Fs, 'Window', win, 'OverlapLength', OverlapLength,...
     'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
title("Female Speech")
subplot(3,1,3)
stft(mix, Fs, 'Window', win, 'OverlapLength', OverlapLength,...
    'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
title("Mix Speech")

Разделение источников с использованием идеальных частотно-временных масок

Было показано, что применение маски TF является эффективным способом отделения желаемых аудиосигналов от конкурирующих звуков. Маска TF является матрицей того же размера, что и базовый STFT. Маска умножается на элемент за элементом с базовым STFT, чтобы изолировать требуемый источник. Маска TF может быть двоичной или мягкой.

Разделение источников с использованием идеальных двоичных масок

В идеальной двоичной маске значения камер маски составляют 0 или 1. Если степень требуемого источника больше, чем объединенная степень других источников в конкретной камере TF, то эта камера устанавливается равной 1. В противном случае значение камеры устанавливается равным 0.

Вычислите идеальную двоичную маску для мужского динамика и затем визуализируйте ее.

P_M        = stft(mSpeech, 'Window', win, 'OverlapLength', OverlapLength,...
                 'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
P_F        = stft(fSpeech, 'Window', win, 'OverlapLength', OverlapLength,...
                 'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
[P_mix,F]  = stft(mix, 'Window', win, 'OverlapLength', OverlapLength,...
                  'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
binaryMask = abs(P_M) >= abs(P_F);

figure(3)
plotMask(binaryMask, WindowLength - OverlapLength, F, Fs)

Оцените мужскую речь STFT путем умножения смеси STFT на двоичную маску мужчины-диктора. Оцените женскую речь STFT путем умножения смеси STFT на обратную двоичную маску мужской говорящей.

P_M_Hard = P_mix .* binaryMask;
P_F_Hard = P_mix .* (1-binaryMask);

Оцените мужские и женские аудиосигналы, используя обратный короткий FFT (ISTFT). Визуализируйте предполагаемые и исходные сигналы. Прослушайте предполагаемые мужские и женские речевые сигналы.

mSpeech_Hard = istft(P_M_Hard , 'Window', win, 'OverlapLength', OverlapLength,...
                     'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
fSpeech_Hard = istft(P_F_Hard , 'Window', win, 'OverlapLength', OverlapLength,...
                     'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
figure(4)
subplot(2,2,1)
plot(t,mSpeech)
axis([t(1) t(end) -1 1])
title("Original Male Speech")
grid on

subplot(2,2,3)
plot(t,mSpeech_Hard)
axis([t(1) t(end) -1 1])
xlabel("Time (s)")
title("Estimated Male Speech")
grid on

subplot(2,2,2)
plot(t,fSpeech)
axis([t(1) t(end) -1 1])
title("Original Female Speech")
grid on

subplot(2,2,4)
plot(t,fSpeech_Hard)
axis([t(1) t(end) -1 1])
title("Estimated Female Speech")
xlabel("Time (s)")
grid on

sound(mSpeech_Hard,Fs)
sound(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', 'onesided');
fSpeech_Soft = istft(P_F_Soft, 'Window', win, 'OverlapLength', OverlapLength,...
                     'FFTLength', FFTLength, 'FrequencyRange', 'onesided');

Визуализируйте предполагаемые и исходные сигналы. Прослушайте предполагаемые мужские и женские речевые сигналы. Обратите внимание, что результаты очень хороши, потому что маска создается с полным знанием разделенных мужских и женских сигналов.

figure(5)
subplot(2,2,1)
plot(t,mSpeech)
axis([t(1) t(end) -1 1])
title("Original Male Speech")
grid on

subplot(2,2,3)
plot(t,mSpeech_Soft)
axis([t(1) t(end) -1 1])
title("Estimated Male Speech")
grid on

subplot(2,2,2)
plot(t,fSpeech)
axis([t(1) t(end) -1 1])
xlabel("Time (s)")
title("Original Female Speech")
grid on

subplot(2,2,4)
plot(t,fSpeech_Soft)
axis([t(1) t(end) -1 1])
xlabel("Time (s)")
title("Estimated Female Speech")
grid on

sound(mSpeech_Soft,Fs)
sound(fSpeech_Soft,Fs)

Оценка маски с использованием глубокого обучения

Цель нейронной сети для глубокого обучения в этом примере состоит в том, чтобы оценить идеальную мягкую маску, описанную выше. Сеть оценивает маску, соответствующую мужскому динамику. Женская маска динамика получена непосредственно из мужской маски.

Базовая схема глубокого обучения показана ниже. Предиктор является спектрами величин смешанного (мужского + женского) аудио. Цель - идеальные мягкие маски, соответствующие мужскому динамику. Регрессионная сеть использует вход предиктора, чтобы минимизировать среднюю квадратную ошибку между ее выходом и входной целью. На выходе аудио STFT преобразуется назад в временной интервал с помощью выходной величины спектра и фазы смешанного сигнала.

Аудио преобразуется в частотный диапазон с помощью Преобразования Фурье Short-Time (STFT) с длиной окна 128 выборкой, перекрытием 127 и окном Ханна. Вы уменьшаете размер спектрального вектора до 65 путем падения выборок частот, соответствующих отрицательным частотам (потому что речевой сигнал временной области является реальным, это не приводит к какой-либо потере информации). Вход предиктора состоит из 20 последовательных векторов STFT. Выходные выходы: мягкая маска 65 на 20.

Вы используете обученную сеть, чтобы оценить мужскую речь. Входом для обученной сети является аудио смешанной (мужской + женский) речи.

Цели и предикторы STFT

Этот раздел иллюстрирует, как сгенерировать сигналы цели и предиктора из обучающего набора данных.

Считывайте в обучающих сигналах, состоящих из около 400 секунд речи от динамиков мужского и женского пола, соответственно, дискретизированных с частотой дискретизации 4 кГц. Низкая частота дискретизации используется для ускорения обучения. Обрезайте обучающие сигналы так, чтобы они были одинаковой длины.

maleTrainingAudioFile   = "MaleSpeech-16-4-mono-405secs.wav";
femaleTrainingAudioFile = "FemaleSpeech-16-4-mono-405secs.wav";

maleSpeechTrain   = audioread(fullfile(netFolder,maleTrainingAudioFile));
femaleSpeechTrain = audioread(fullfile(netFolder,femaleTrainingAudioFile));

L = min(length(maleSpeechTrain),length(femaleSpeechTrain));  
maleSpeechTrain   = maleSpeechTrain(1:L);
femaleSpeechTrain = femaleSpeechTrain(1:L);

Считывайте в сигналах валидации, состоящих из около 20 секунд речи от мужчин и женщин, соответственно, дискретизированных с частотой дискретизации 4 кГц. Обрезайте сигналы валидации так, чтобы они были одинаковыми по длине

maleValidationAudioFile   = "MaleSpeech-16-4-mono-20secs.wav";
femaleValidationAudioFile = "FemaleSpeech-16-4-mono-20secs.wav";

maleSpeechValidate   = audioread(fullfile(netFolder,maleValidationAudioFile));
femaleSpeechValidate = audioread(fullfile(netFolder,femaleValidationAudioFile));

L = min(length(maleSpeechValidate),length(femaleSpeechValidate));  
maleSpeechValidate   = maleSpeechValidate(1:L);
femaleSpeechValidate = femaleSpeechValidate(1:L);

Масштабируйте обучающие сигналы до той же степени. Масштабируйте сигналы валидации на ту же степень.

maleSpeechTrain   = maleSpeechTrain/norm(maleSpeechTrain);
femaleSpeechTrain = femaleSpeechTrain/norm(femaleSpeechTrain);
ampAdj            = max(abs([maleSpeechTrain;femaleSpeechTrain]));
maleSpeechTrain   = maleSpeechTrain/ampAdj;
femaleSpeechTrain = femaleSpeechTrain/ampAdj;

maleSpeechValidate   = maleSpeechValidate/norm(maleSpeechValidate);
femaleSpeechValidate = femaleSpeechValidate/norm(femaleSpeechValidate);
ampAdj               = max(abs([maleSpeechValidate;femaleSpeechValidate]));
maleSpeechValidate   = maleSpeechValidate/ampAdj;
femaleSpeechValidate = femaleSpeechValidate/ampAdj;

Создайте обучающие и валидационные «коктейльные вечеринки» миксы.

mixTrain = maleSpeechTrain + femaleSpeechTrain;
mixTrain = mixTrain / max(mixTrain);

mixValidate = maleSpeechValidate + femaleSpeechValidate;
mixValidate = mixValidate / max(mixValidate);

Сгенерируйте обучающие STFT.

WindowLength  = 128;
FFTLength     = 128;
OverlapLength = 128-1;
Fs            = 4000;
win           = hann(WindowLength,"periodic");

P_mix0 = stft(mixTrain, 'Window', win, 'OverlapLength', OverlapLength,...
              'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
P_M    = abs(stft(maleSpeechTrain, 'Window', win, 'OverlapLength', OverlapLength,...
              'FFTLength', FFTLength, 'FrequencyRange', 'onesided'));
P_F    = abs(stft(femaleSpeechTrain, 'Window', win, 'OverlapLength', OverlapLength,...
              'FFTLength', FFTLength, 'FrequencyRange', 'onesided'));

Возьмем журнал смеси STFT. Нормализуйте значения путем их среднего и стандартного отклонения.

P_mix = log(abs(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', 'onesided');
P_Val_M    = abs(stft(maleSpeechValidate, 'Window', win, 'OverlapLength', OverlapLength,...
                 'FFTLength', FFTLength, 'FrequencyRange', 'onesided'));
P_Val_F    = abs(stft(femaleSpeechValidate, 'Window', win, 'OverlapLength', OverlapLength,...
                 'FFTLength', FFTLength, 'FrequencyRange', 'onesided'));

P_Val_mix = 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 обучающих данных.

figure(6)
histogram(P_mix,"EdgeColor","none","Normalization","pdf")
xlabel("Input Value")
ylabel("Probability Density")

Вычислите обучающую мягкую маску. Используйте эту маску в качестве целевого сигнала во время обучения сети.

maskTrain = P_M ./ (P_M + P_F + eps);

Вычислите валидацию мягкую маску. Используйте эту маску для оценки маски, излучаемой обученной сетью.

maskValidate = P_Val_M ./ (P_Val_M + P_Val_F + eps);

Чтобы проверить, является ли распределение целевых данных плавным, постройте гистограмму значений маски обучающих данных.

figure(7)
histogram(maskTrain,"EdgeColor","none","Normalization","pdf")
xlabel("Input Value")
ylabel("Probability Density")

Создайте фрагменты размера (65, 20) из предиктора и целевых сигналов. В порядок, чтобы получить больше обучающих выборок, используйте перекрытие из 10 сегментов между последовательными фрагментами.

seqLen        = 20;
seqOverlap    = 10;
mixSequences  = zeros(1 + FFTLength/2,seqLen,1,0);
maskSequences = zeros(1 + FFTLength/2,seqLen,1,0);

loc = 1;
while loc < size(P_mix,2) - seqLen
    mixSequences(:,:,:,end+1)  = P_mix(:,loc:loc+seqLen-1); %#ok
    maskSequences(:,:,:,end+1) = maskTrain(:,loc:loc+seqLen-1); %#ok
    loc                        = loc + seqOverlap;
end

Создайте фрагменты размера (65,20) из предиктора валидации и целевых сигналов.

mixValSequences  = zeros(1 + FFTLength/2,seqLen,1,0);
maskValSequences = zeros(1 + FFTLength/2,seqLen,1,0);
seqOverlap       = seqLen;

loc = 1;
while loc < size(P_Val_mix,2) - seqLen
    mixValSequences(:,:,:,end+1)  = P_Val_mix(:,loc:loc+seqLen-1); %#ok
    maskValSequences(:,:,:,end+1) = maskValidate(:,loc:loc+seqLen-1); %#ok
    loc                           = loc + seqOverlap;
end

Измените форму сигналов обучения и валидации.

mixSequencesT  = reshape(mixSequences,    [1 1 (1 + FFTLength/2) * seqLen size(mixSequences,4)]);
mixSequencesV  = reshape(mixValSequences, [1 1 (1 + FFTLength/2) * seqLen size(mixValSequences,4)]);
maskSequencesT = reshape(maskSequences,   [1 1 (1 + FFTLength/2) * seqLen size(maskSequences,4)]);
maskSequencesV = reshape(maskValSequences,[1 1 (1 + FFTLength/2) * seqLen size(maskValSequences,4)]);

Определите Нейронную сеть для глубокого обучения

Задайте слои сети. Определите размер входа, чтобы быть изображениями размера 1 на 1 к 1300. Задайте два скрытых полносвязных слоев, каждый с 1300 нейронами. Следуйте каждому скрытому полносвязному слою с помощью сигмоидного слоя. Слои нормализации партии . нормализуют средние и стандартные отклонения выходных параметров. Добавьте полносвязный слой с 1300 нейронами, а затем регрессионый слой.

numNodes = (1 + FFTLength/2) * seqLen;

layers = [ ...
    
    imageInputLayer([1 1 (1 + FFTLength/2)*seqLen],"Normalization","None")
    
    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 обучающие сигналы за раз. Задайте Plots на training-progress чтобы сгенерировать графики, которые показывают процесс обучения с увеличениями количества итераций. Задайте Verbose на false отключить печать выхода таблицы, который соответствует данным, показанным на графике, в окне командной строки. Задайте Shuffle на every-epoch тасовать обучающие последовательности в начале каждой эпохи. Задайте LearnRateSchedule на piecewise уменьшить скорость обучения на заданный коэффициент (0,1) каждый раз, когда прошло определенное количество эпох (1). Задайте ValidationData к предикторам и целям валидации. Задайте ValidationFrequency таким образом, средняя квадратная ошибка валидации вычисляется один раз в эпоху. Этот пример использует решатель адаптивной оценки момента (ADAM).

maxEpochs     = 3;
miniBatchSize = 64;

options = trainingOptions("adam", ...
    "MaxEpochs",maxEpochs, ...
    "MiniBatchSize",miniBatchSize, ...
    "SequenceLength","longest", ...
    "Shuffle","every-epoch",...
    "Verbose",0, ...
    "Plots","training-progress",...
    "ValidationFrequency",floor(size(mixSequencesT,4)/miniBatchSize),...
    "ValidationData",{mixSequencesV,maskSequencesV},...
    "LearnRateSchedule","piecewise",...
    "LearnRateDropFactor",0.9, ...
    "LearnRateDropPeriod",1);

Обучите нейронную сеть для глубокого обучения

Обучите сеть с заданными опциями обучения и архитектурой слоя с помощью trainNetwork. Поскольку набор обучающих данных большая, процесс обучения может занять несколько минут. Чтобы загрузить предварительно обученную сеть, установите doTraining на false.

doTraining = true;
if doTraining
    CocktailPartyNet = trainNetwork(mixSequencesT,maskSequencesT,layers,options);
else
    s = load("CocktailPartyNet.mat");
    CocktailPartyNet = s.CocktailPartyNet;
end

Передайте предикторы валидации в сеть. Это выход - предполагаемая маска. Измените форму предполагаемой маски.

estimatedMasks0 = predict(CocktailPartyNet,mixSequencesV);

estimatedMasks0 = estimatedMasks0.';
estimatedMasks0 = reshape(estimatedMasks0,1 + FFTLength/2,numel(estimatedMasks0)/(1 + FFTLength/2));

Оцените нейронную сеть для глубокого обучения

Постройте гистограмму ошибки между фактической и ожидаемой маской.

figure(8)
histogram(maskValSequences(:) - estimatedMasks0(:),"EdgeColor","none","Normalization","pdf")
xlabel("Mask Error")
ylabel("Probability Density")

Оценка мягкой маски

Оцените мужские и женские мягкие маски. Оцените мужские и женские бинарные маски путем порога мягких масок.

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, 'ConjugateSymmetric', true,...
                           'FrequencyRange', 'onesided');
maleSpeech_est_soft = maleSpeech_est_soft / max(abs(maleSpeech_est_soft));

Визуализируйте предполагаемые и исходные мужские речевые сигналы. Послушайте предполагаемую мужскую речь мягкой маски.

range = (numel(win):numel(maleSpeech_est_soft)-numel(win));
t     = range * (1/Fs);

figure(9)
subplot(2,1,1)
plot(t,maleSpeechValidate(range))
title("Original Male Speech")
xlabel("Time (s)")
grid on

subplot(2,1,2)
plot(t,maleSpeech_est_soft(range))
xlabel("Time (s)")
title("Estimated Male Speech (Soft Mask)")
grid on

sound(maleSpeech_est_soft(range),Fs)

Умножьте микс STFT на женскую мягкую маску, чтобы получить предполагаемую женскую речь STFT. Используйте ISTFT, чтобы получить предполагаемый мужской аудиосигнал. Масштабируйте аудио.

P_Female = P_Val_mix0 .* SoftFemaleMask;

femaleSpeech_est_soft = istft(P_Female, 'Window', win, 'OverlapLength', OverlapLength,...
                              'FFTLength',FFTLength, 'ConjugateSymmetric',true,...
                              'FrequencyRange', 'onesided');
femaleSpeech_est_soft = femaleSpeech_est_soft / max(femaleSpeech_est_soft);

Визуализируйте предполагаемые и исходные женские сигналы. Послушайте предполагаемую женскую речь.

range = (numel(win):numel(maleSpeech_est_soft) - numel(win));
t     = range * (1/Fs);

figure(10)
subplot(2,1,1)
plot(t,femaleSpeechValidate(range))
title("Original Female Speech")
grid on

subplot(2,1,2)
plot(t,femaleSpeech_est_soft(range))
xlabel("Time (s)")
title("Estimated Female Speech (Soft Mask)")
grid on

sound(femaleSpeech_est_soft(range),Fs)

Оценка двоичной маски

Оцените мужские и женские бинарные маски путем порога мягких масок.

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, 'ConjugateSymmetric', true,...
                            'FrequencyRange', 'onesided');
maleSpeech_est_hard = maleSpeech_est_hard / max(maleSpeech_est_hard);

Визуализируйте предполагаемые и исходные мужские речевые сигналы. Послушайте предполагаемую мужскую речь в бинарной маске.

range = (numel(win):numel(maleSpeech_est_soft)-numel(win));
t = range * (1/Fs);

figure(11)
subplot(2,1,1)
plot(t,maleSpeechValidate(range))
title("Original Male Speech")
grid on

subplot(2,1,2)
plot(t,maleSpeech_est_hard(range))
xlabel("Time (s)")
title("Estimated Male Speech (Binary Mask)")
grid on

sound(maleSpeech_est_hard(range),Fs)

Умножьте микс STFT на женскую двоичную маску, чтобы получить предполагаемую мужскую речь STFT. Используйте ISTFT, чтобы получить предполагаемый мужской аудиосигнал. Масштабируйте аудио.

P_Female = P_Val_mix0 .* HardFemaleMask;

femaleSpeech_est_hard = istft(P_Female, 'Window', win, 'OverlapLength', OverlapLength,...
                              'FFTLength', FFTLength, 'ConjugateSymmetric', true,...
                              'FrequencyRange', 'onesided');
femaleSpeech_est_hard = femaleSpeech_est_hard / max(femaleSpeech_est_hard);

Визуализируйте предполагаемые и исходные женские речевые сигналы. Послушайте предполагаемую женскую речь.

range = (numel(win):numel(maleSpeech_est_soft)-numel(win));
t = range * (1/Fs);

figure(12)
subplot(2,1,1)
plot(t,femaleSpeechValidate(range))
title("Original Female Speech")
grid on

subplot(2,1,2)
plot(t,femaleSpeech_est_hard(range))
title("Estimated Female Speech (Binary Mask)")
grid on

sound(femaleSpeech_est_hard(range),Fs)

Сравните STFT сегмента на одну секунду для смеси, исходных женского и мужского, и предполагаемых женского и мужского, соответственно.

range = 7e4:7.4e4;

figure(13)
stft(mixValidate(range), Fs, 'Window', win, 'OverlapLength', 64,...
    'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
title("Mix STFT")

figure(14)
subplot(3,1,1)
stft(maleSpeechValidate(range),Fs, 'Window', win, 'OverlapLength', 64,...
    'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
title("Male STFT (Actual)")
subplot(3,1,2)
stft(maleSpeech_est_soft(range),Fs, 'Window', win, 'OverlapLength', 64,...
    'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
subplot(3,1,3)
stft(maleSpeech_est_hard(range),Fs, 'Window', win, 'OverlapLength', 64,...
    'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
title("Male STFT (Estimated - Binary Mask)");

figure(15)
subplot(3,1,1)
stft(femaleSpeechValidate(range),Fs, 'Window', win, 'OverlapLength', 64,...
    'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
title("Female STFT (Actual)")
subplot(3,1,2)
stft(femaleSpeech_est_soft(range),Fs, 'Window', win, 'OverlapLength', 64,...
    'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
title("Female STFT (Estimated - Soft Mask)")
subplot(3,1,3)
stft(femaleSpeech_est_hard(range),Fs, 'Window', win, 'OverlapLength', 64,...
    'FFTLength', FFTLength, 'FrequencyRange', 'onesided');
title("Female STFT (Estimated - Binary Mask)")

Ссылки

[1] «Вероятностное Binary-Mask Cocktail-Party Source Separation in a Convolutional Deep Neural Network», Andrew J.R. Simpson, 2015.

Для просмотра документации необходимо авторизоваться на сайте