Этот пример показывает, как изолировать речевой сигнал с помощью нейронной сети для глубокого обучения.
Эффект коктейльной вечеринки относится к способности мозга фокусироваться на одном динамике, фильтруя при этом другие голоса и фоновый шум. Люди очень хорошо выступают на коктейльной вечеринке. Этот пример показывает, как использовать нейронную сеть для глубокого обучения, чтобы отделить отдельных дикторов от речевой смеси, где одновременно говорят один мужчина и одна женщина.
Прежде чем подробно войти в пример, вы загрузите предварительно обученную сеть и 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.
Вы используете обученную сеть, чтобы оценить мужскую речь. Входом для обученной сети является аудио смешанной (мужской + женский) речи.
Этот раздел иллюстрирует, как сгенерировать сигналы цели и предиктора из обучающего набора данных.
Считывайте в обучающих сигналах, состоящих из около 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.