Речь Denoise Используя нейронные сети для глубокого обучения

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

Введение

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

Проблемные сводные данные

Считайте следующий речевой сигнал выбранным на уровне 8 кГц.

[cleanAudio,fs] = audioread("SpeechDFT-16-8-mono-5secs.wav");
sound(cleanAudio,fs)

Добавьте шум стиральной машины в речевой сигнал. Установите шумовую степень, таким образом, что отношение сигнал-шум (SNR) является нулевым дБ.

noise        = audioread("WashingMachine-16-8-mono-1000secs.wav");

% Extract a noise segment from a random location in the noise file
ind          = randi(numel(noise) - numel(cleanAudio) + 1, 1, 1);
noiseSegment = noise(ind:ind + numel(cleanAudio) - 1);

speechPower  = sum(cleanAudio.^2);
noisePower   = sum(noiseSegment.^2);
noisyAudio   = cleanAudio + sqrt(speechPower/noisePower) * noiseSegment;

Слушайте шумный речевой сигнал.

sound(noisyAudio,fs)

Визуализируйте исходные и сигналы с шумом.

t = (1/fs) * (0:numel(cleanAudio)-1);
subplot(2,1,1)
plot(t,cleanAudio)
title("Clean Audio")
grid on
subplot(2,1,2)
plot(t,noisyAudio)
title("Noisy Audio")
xlabel("Time (s)")
grid on

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

Исследуйте набор данных

Этот пример использует набор данных Mozilla Common Voice [1], чтобы обучить и протестировать нейронные сети для глубокого обучения. Набор данных содержит записи на 48 кГц предметов говорящие короткие предложения. Загрузите набор данных и untar загруженный файл. Установите datafolder на местоположение данных.

datafolder = PathToDatabase;

Используйте audioDatastore, чтобы создать datastore для файлов в папке cv-valid-train.

ads = audioDatastore(fullfile(datafolder,"cv-valid-train"));

Используйте shuffle, чтобы рандомизировать порядок файлов в datastore.

ads = shuffle(ads);

Вы обучите нейронные сети для глубокого обучения на подмножестве файлов. Создайте подмножество datastore, содержащее первые 1 000 файлов datastore.

ads = subset(ads,1:1000);

Используйте read, чтобы получить содержимое первого файла в datastore.

[audio,info] = read(ads);

Слушайте речевой сигнал.

sound(audio,info.SampleRate)

Постройте речевой сигнал.

figure
t = (1/info.SampleRate) * (0:numel(audio)-1);
plot(t,audio)
title("Example Speech Signal")
xlabel("Time (s)")
grid on

Системный обзор глубокого обучения

Основной план подготовки глубокого обучения показывают ниже. Обратите внимание на то, что, поскольку речь обычно падает ниже 4 кГц, вы сначала субдискретизируете чистые и шумные звуковые сигналы к 8 кГц, чтобы уменьшать вычислительную загрузку сети. Предиктор и целевые сетевые сигналы являются спектрами значения шумных и чистых звуковых сигналов, соответственно. Вывод сети является спектром значения сигнала denoised. Сеть регрессии использует вход предиктора, чтобы минимизировать среднеквадратичную погрешность между ее выводом и входной целью. denoised аудио преобразовано назад в область времени использование выходного спектра значения и фазы сигнала с шумом [2].

Вы преобразовываете аудио к частотному диапазону с помощью Кратковременного преобразования Фурье (STFT), с продолжительностью окна 256 выборок, перекрытием 75% и Окном Хэмминга. Вы уменьшаете размер спектрального вектора к 129 путем отбрасывания выборок частоты, соответствующих отрицательным частотам (потому что речевой сигнал временного интервала действителен, это не приводит ни к какой информационной потере). Вход предиктора состоит из 8 последовательных шумных векторов STFT, так, чтобы каждый STFT оценка вывода был вычислен на основе текущего шумного STFT и 7 предыдущих шумных векторов STFT.

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

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

Во-первых, задайте системные параметры:

windowLength = 256;
win          = hamming(windowLength,"periodic");
overlap      = round(0.75 * windowLength);
ffTLength    = windowLength;
inputFs      = 48e3;
fs           = 8e3;
numFeatures  = ffTLength/2 + 1;
numSegments  = 8;

Задайте конвертер частоты дискретизации, используемый, чтобы преобразовать аудио на 48 кГц в 8 кГц.

src = dsp.SampleRateConverter("InputSampleRate",inputFs, ...
                              "OutputSampleRate",fs, ...
                              "Bandwidth",7920);

Используйте read, чтобы получить содержимое звукового файла от datastore.

audio = read(ads);

Убедитесь, что аудио длина является кратной фактору десятикратного уменьшения конвертера частоты дискретизации.

decimationFactor = inputFs/fs;
L = floor(numel(audio)/decimationFactor);
audio = audio(1:decimationFactor*L);

Преобразуйте звуковой сигнал в 8 кГц.

audio = src(audio);
reset(src)

Создайте случайный шумовой сегмент из вектора шума стиральной машины.

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

Добавьте, что шум к речи сигнализирует таким образом, что ОСШ составляет 0 дБ.

noisePower   = sum(noiseSegment.^2);
cleanPower   = sum(audio.^2);
noiseSegment = noiseSegment .* sqrt(cleanPower/noisePower);
noisyAudio   = audio + noiseSegment;

Используйте stft, чтобы сгенерировать значение векторы STFT от исходных и шумных звуковых сигналов.

cleanSTFT = stft(audio,'Window',win,'OverlapLength',overlap,'FFTLength',ffTLength);
cleanSTFT = abs(cleanSTFT(numFeatures-1:end,:));
noisySTFT = stft(noisyAudio,'Window',win,'OverlapLength',overlap,'FFTLength',ffTLength);
noisySTFT = abs(noisySTFT(numFeatures-1:end,:));

Сгенерируйте учебные сигналы предиктора с 8 сегментами от шумного STFT. Перекрытие между последовательными предикторами является 7 сегментами.

noisySTFT    = [noisySTFT(:,1:numSegments - 1), noisySTFT];
stftSegments = zeros(numFeatures, numSegments , size(noisySTFT,2) - numSegments + 1);
for index = 1:size(noisySTFT,2) - numSegments + 1
    stftSegments(:,:,index) = (noisySTFT(:,index:index + numSegments - 1));
end

Поставьте цели и предикторы. Последняя размерность обеих переменных соответствует количеству отличных пар предиктора/цели, сгенерированных звуковым файлом. Каждый предиктор 129 8, и каждая цель 129 1.

targets = cleanSTFT;
size(targets)
predictors = stftSegments;
size(predictors)
ans =

   129   457


ans =

   129     8   457

Извлеките функции Используя длинные массивы

Чтобы ускорить обработку, извлеките последовательности функции от речевых сегментов всех звуковых файлов в datastore с помощью длинных массивов. В отличие от массивов в оперативной памяти, длинные массивы обычно остаются неоцененными, пока вы не вызываете функцию gather. Эта отсроченная оценка позволяет вам работать быстро с большими наборами данных. Когда вы в конечном счете запрашиваете вывод с помощью gather, MATLAB комбинирует вычисления в очереди, где возможный и берет минимальное количество проходов через данные. Если у вас есть Parallel Computing Toolbox™, можно использовать длинные массивы в локальном сеансе работы с MATLAB, или на локальном параллельном пуле. Можно также выполнить вычисления длинного массива на кластере, если вам установили MATLAB® Parallel Server™.

Во-первых, преобразуйте datastore в длинный массив.

reset(ads)
T = tall(ads)
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 12).

T =

  M×1 tall cell array

    {294384×1 double}
    {176880×1 double}
    {188400×1 double}
    {246000×1 double}
    {240240×1 double}
    {231024×1 double}
    {156144×1 double}
    {248304×1 double}
        :        :
        :        :

Отображение указывает, что количество строк (соответствующий количеству файлов в datastore), M, еще не известно. M является заполнителем, пока вычисление не завершается.

Извлеките цель и значение предиктора STFT от длинной таблицы. Это действие создает новые переменные длинного массива, чтобы использовать в последующих вычислениях. Функциональный HelperGenerateSpeechDenoisingFeatures выполняет шаги, уже подсвеченные в разделе STFT Targets and Predictors. Команда cellfun применяет HelperGenerateSpeechDenoisingFeatures к содержимому каждого звукового файла в datastore.

[targets,predictors] = cellfun(@(x)HelperGenerateSpeechDenoisingFeatures(x,noise,src),T,"UniformOutput",false);

Используйте gather, чтобы оценить цели и предикторы.

[targets,predictors] = gather(targets,predictors);
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: Completed in 1 min 4 sec
Evaluation completed in 2 min 16 sec

Это - хорошая практика, чтобы нормировать все функции, чтобы обнулить стандартное отклонение единицы и среднее значение.

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

predictors    = cat(3,predictors{:});
targets       = cat(2,targets{:});
noisyMean     = mean(predictors(:));
noisyStd      = std(predictors(:));
predictors(:) = (predictors(:) - noisyMean)/noisyStd;
cleanMean     = mean(targets(:));
cleanStd      = std(targets(:));
targets(:)    = (targets(:) - cleanMean)/cleanStd;

Измените предикторы и цели к размерностям, ожидаемым нейронными сетями для глубокого обучения.

predictors = reshape(predictors,size(predictors,1),size(predictors,2),1,size(predictors,3));
targets    = reshape(targets,1,1,size(targets,1),size(targets,2));

Вы будете использовать 1% данных для валидации во время обучения. Валидация полезна, чтобы обнаружить сценарии, где сеть сверхсоответствует данным тренировки.

Случайным образом разделите данные в наборы обучения и валидации.

inds               = randperm(size(predictors,4));
L                  = round(0.99 * size(predictors,4));
trainPredictors    = predictors(:,:,:,inds(1:L));
trainTargets       = targets(:,:,:,inds(1:L));
validatePredictors = predictors(:,:,:,inds(L+1:end));
validateTargets    = targets(:,:,:,inds(L+1:end));

Речевое шумоподавление с полносвязными слоями

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

Задайте слои сети. Задайте входной размер, чтобы быть изображениями размера NumFeatures-by-NumSegments (129 8 в этом примере). Задайте два скрытых полносвязных слоя, каждого с 1 024 нейронами. Начиная с чисто линейных систем следуйте за каждым скрытым полносвязным слоем со слоем Rectified Linear Unit (ReLU). Пакетные слои нормализации нормируют средние значения и стандартные отклонения выходных параметров. Добавьте полносвязный слой с 129 нейронами, сопровождаемыми слоем регрессии.

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

Затем, задайте опции обучения для сети. Установите MaxEpochs на 3 так, чтобы сеть сделала 3, проходит через данные тренировки. Установите MiniBatchSize 128 так, чтобы сеть посмотрела на 128 учебных сигналов за один раз. Задайте Plots как "training-progress", чтобы сгенерировать графики, которые показывают учебный прогресс количеством увеличений итераций. Установите Verbose на false отключать печать таблицы вывод, который соответствует данным, показанным в графике в окно командной строки. Задайте Shuffle как "every-epoch", чтобы переставить обучающие последовательности в начале каждой эпохи. Задайте LearnRateSchedule к "piecewise", чтобы уменьшить темп обучения заданным фактором (0.9) каждый раз, когда определенное число эпох (1) передало. Установите ValidationData на предикторы валидации и цели. Установите ValidationFrequency, таким образом, что среднеквадратичная погрешность валидации вычисляется однажды в эпоху. Этот пример использует адаптивную оценку момента (Адам) решатель.

miniBatchSize = 128;
options = trainingOptions("adam", ...
    "MaxEpochs",3, ...
    "InitialLearnRate",1e-5,...
    "MiniBatchSize",miniBatchSize, ...
    "Shuffle","every-epoch", ...
    "Plots","training-progress", ...
    "Verbose",false, ...
    "ValidationFrequency",floor(size(trainPredictors,4)/miniBatchSize),...
    "LearnRateSchedule","piecewise",...
    "LearnRateDropFactor",0.9,...
    "LearnRateDropPeriod",1,...
    "ValidationData",{validatePredictors,validateTargets});

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

doTraining = true;
if doTraining
    denoiseNetFullyConnected = trainNetwork(trainPredictors,trainTargets,layers,options);
else
    s = load("denoisenet.mat");
    denoiseNetFullyConnected = s.denoiseNetFullyConnected;
    cleanMean = s.cleanMean;
    cleanStd  = s.cleanStd;
    noisyMean = s.noisyMean;
    noisyStd  = s.noisyStd;
end

Считайте количество весов в полносвязных слоях сети.

numWeights = 0;
for index = 1:numel(denoiseNetFullyConnected.Layers)
    if isa(denoiseNetFullyConnected.Layers(index),"nnet.cnn.layer.FullyConnectedLayer")
        numWeights = numWeights + numel(denoiseNetFullyConnected.Layers(index).Weights);
    end
end
fprintf("The number of weights is %d.\n",numWeights);
The number of weights is 2237440.

Речевое шумоподавление со сверточными слоями

Рассмотрите сеть, которая использует сверточные слои вместо полносвязных слоев [3]. 2D сверточный слой применяет скользящие фильтры к входу. Слой применяет операцию свертки к входу путем перемещения фильтров вдоль входа вертикально и горизонтально и вычисления скалярного произведения весов и входа, и затем добавления срока смещения. Сверточные слои обычно состоят из меньшего количества параметров, чем полносвязные слоя.

Задайте слои полностью сверточной сети, описанной в [3], включив 16 сверточных слоев. Первые 15 сверточных слоев являются группами из 3 слоев, повторенных 5 раз, с ширинами фильтра 9, 5, и 9, и количество фильтров 18, 30 и 8, соответственно. Последний сверточный слой имеет ширину фильтра 129 и 1 фильтра. В этой сети свертки выполняются только в одном направлении (по измерению частоты), и ширина фильтра вдоль измерения времени установлена в 1 для всех слоев кроме первого. Подобно полностью связанной сети сверточные слои сопровождаются ReLu и обрабатывают слои нормализации в пакетном режиме.

layers = [imageInputLayer([numFeatures,numSegments])
          convolution2dLayer([9 8],18,"Stride",[1 100],"Padding","same")
          batchNormalizationLayer
          reluLayer

          repmat(...
          [convolution2dLayer([5 1],30,"Stride",[1 100],"Padding","same")
          batchNormalizationLayer
          reluLayer
          convolution2dLayer([9 1],8,"Stride",[1 100],"Padding","same")
          batchNormalizationLayer
          reluLayer
          convolution2dLayer([9 1],18,"Stride",[1 100],"Padding","same")
          batchNormalizationLayer
          reluLayer], 4,1)

          convolution2dLayer([5 1],30,"Stride",[1 100],"Padding","same")
          batchNormalizationLayer
          reluLayer
          convolution2dLayer([9 1],8,"Stride",[1 100],"Padding","same")
          batchNormalizationLayer
          reluLayer

          convolution2dLayer([129 1],1,"Stride",[1 100],"Padding","same")

          regressionLayer
          ];

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

options = trainingOptions("adam", ...
    "MaxEpochs",3, ...
    "InitialLearnRate",1e-5,...
    "MiniBatchSize",miniBatchSize, ...
    "Shuffle","every-epoch", ...
    "Plots","training-progress", ...
    "Verbose",false, ...
    "ValidationFrequency",floor(size(trainPredictors,4)/miniBatchSize),...
    "LearnRateSchedule","piecewise",...
    "LearnRateDropFactor",0.9,...
    "LearnRateDropPeriod",1,...
    "ValidationData",{validatePredictors,permute(validateTargets,[3 1 2 4])});

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

doTraining = true;
if doTraining
    denoiseNetFullyConvolutional = trainNetwork(trainPredictors,permute(trainTargets,[3 1 2 4]),layers,options);
else
    s = load("denoisenet.mat");
    denoiseNetFullyConvolutional = s.denoiseNetFullyConvolutional;
    cleanMean = s.cleanMean;
    cleanStd  = s.cleanStd;
    noisyMean = s.noisyMean;
    noisyStd  = s.noisyStd;
end
IdleTimeout has been reached.
Parallel pool using the 'local' profile is shutting down.

Считайте количество весов в полносвязных слоях сети.

numWeights = 0;
for index = 1:numel(denoiseNetFullyConvolutional.Layers)
    if isa(denoiseNetFullyConvolutional.Layers(index),"nnet.cnn.layer.Convolution2DLayer")
        numWeights = numWeights + numel(denoiseNetFullyConvolutional.Layers(index).Weights);
    end
end
fprintf("The number of weights in convolutional layers is %d\n",numWeights);
The number of weights in convolutional layers is 31812

Протестируйте сети шумоподавления

Используйте речевые сигналы от папки "условная цена допустимый тест", чтобы проверить производительность обучившего нейронные сети. Используйте audioDatastore, чтобы создать datastore для файлов в папке "условная цена допустимый тест".

ads = audioDatastore(fullfile(datafolder,"cv-valid-test"));

Переставьте файлы в datastore.

ads = shuffle(ads);

Считайте содержимое файла от datastore.

[cleanAudio,info] = read(ads);

Убедитесь, что аудио длина является кратной фактору десятикратного уменьшения конвертера частоты дискретизации.

L            = floor( numel(cleanAudio)/decimationFactor);
cleanAudio   = cleanAudio(1:decimationFactor*L);

Преобразуйте звуковой сигнал в 8 кГц.

cleanAudio = src(cleanAudio);
reset(src)

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

noise = audioread("WashingMachine-16-8-mono-200secs.wav");

Создайте случайный шумовой сегмент из вектора шума стиральной машины.

randind      = randi(numel(noise) - numel(cleanAudio) , [1 1]);
noiseSegment = noise(randind : randind + numel(cleanAudio) - 1);

Добавьте, что шум к речи сигнализирует таким образом, что ОСШ составляет 0 дБ.

noisePower   = sum(noiseSegment.^2);
cleanPower   = sum(cleanAudio.^2);
noiseSegment = noiseSegment .* sqrt(cleanPower/noisePower);
noisyAudio   = cleanAudio + noiseSegment;

Используйте stft, чтобы сгенерировать значение векторы STFT от шумных звуковых сигналов.

noisySTFT  = stft(noisyAudio,'Window',win,'OverlapLength',overlap,'FFTLength',ffTLength);
noisyPhase = angle(noisySTFT(numFeatures-1:end,:));
noisySTFT  = abs(noisySTFT(numFeatures-1:end,:));

Сгенерируйте учебные сигналы предиктора с 8 сегментами от шумного STFT. Перекрытие между последовательными предикторами является 7 сегментами.

noisySTFT  = [noisySTFT(:,1:numSegments-1) noisySTFT];
predictors = zeros( numFeatures, numSegments , size(noisySTFT,2) - numSegments + 1);
for index = 1 : size(noisySTFT,2) - numSegments + 1
    predictors(:,:,index) = noisySTFT(:,index:index + numSegments - 1);
end

Нормируйте предикторы средним и стандартным отклонением, вычисленным на учебном этапе.

predictors(:) = (predictors(:) - noisyMean) / noisyStd;

Вычислите denoised значение, STFT при помощи predict с этими двумя обучил нейронные сети.

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

Масштабируйте выходные параметры средним и стандартным отклонением, используемым на учебном этапе.

STFTFullyConnected(:)     = cleanStd * STFTFullyConnected(:)     +  cleanMean;
STFTFullyConvolutional(:) = cleanStd * STFTFullyConvolutional(:) +  cleanMean;

Преобразуйте односторонний STFT в STFT в центре.

STFTFullyConnected     = STFTFullyConnected.' .* exp(1j*noisyPhase);
STFTFullyConnected     = [conj(STFTFullyConnected(end-1:-1:2,:)) ; STFTFullyConnected];
STFTFullyConvolutional = squeeze(STFTFullyConvolutional) .* exp(1j*noisyPhase);
STFTFullyConvolutional = [conj(STFTFullyConvolutional(end-1:-1:2,:)) ; STFTFullyConvolutional];

Вычислите denoised речевые сигналы. istft выполняет обратный STFT. Используйте фазу шумных векторов STFT, чтобы восстановить сигнал временного интервала.

denoisedAudioFullyConnected     = istft(STFTFullyConnected,  ...
                                        'Window',win,'OverlapLength',overlap, ...
                                        'FFTLength',ffTLength,'ConjugateSymmetric',true);
denoisedAudioFullyConvolutional = istft(STFTFullyConvolutional,  ...
                                        'Window',win,'OverlapLength',overlap, ...
                                        'FFTLength',ffTLength,'ConjugateSymmetric',true);

Постройте чистые, шумные и denoised звуковые сигналы.

figure
subplot(4,1,1)
t = (1/fs) * (0:numel(denoisedAudioFullyConnected)-1);
plot(t,cleanAudio(1:numel(denoisedAudioFullyConnected)))
title("Clean Speech")
grid on
subplot(4,1,2)
plot(t,noisyAudio(1:numel(denoisedAudioFullyConnected)))
title("Noisy Speech")
grid on
subplot(4,1,3)
plot(t,denoisedAudioFullyConnected)
title("Denoised Speech (Fully Connected Layers)")
grid on
subplot(4,1,4)
plot(t,denoisedAudioFullyConvolutional)
title("Denoised Speech (Convolutional Layers)")
grid on
xlabel("Time (s)")

Постройте чистые, шумные, и denoised спектрограммы.

h = figure;
subplot(4,1,1)
spectrogram(cleanAudio,win,overlap,ffTLength,fs);
title("Clean Speech")
grid on
subplot(4,1,2)
spectrogram(noisyAudio,win,overlap,ffTLength,fs);
title("Noisy Speech")
grid on
subplot(4,1,3)
spectrogram(denoisedAudioFullyConnected,win,overlap,ffTLength,fs);
title("Denoised Speech (Fully Connected Layers)")
grid on
subplot(4,1,4)
spectrogram(denoisedAudioFullyConvolutional,win,overlap,ffTLength,fs);
title("Denoised Speech (Convolutional Layers)")
grid on
p = get(h,'Position');
set(h,'Position',[p(1) 65 p(3) 800]);

Слушайте шумную речь.

sound(noisyAudio,fs)

Слушайте denoised речь от сети с полносвязными слоями.

sound(denoisedAudioFullyConnected,fs)

Слушайте denoised речь от сети со сверточными слоями.

sound(denoisedAudioFullyConvolutional,fs)

Послушайте чистую речь.

sound(cleanAudio,fs)

Можно протестировать больше файлов от datastore путем вызова testDenoisingNets. Функция производит временной интервал и графики частотного диапазона, подсвеченные выше, и также возвращает чистые, шумные, и denoised звуковые сигналы.

[cleanAudio,noisyAudio,denoisedAudioFullyConnected,denoisedAudioFullyConvolutional] = testDenoisingNets(ads,denoiseNetFullyConnected,denoiseNetFullyConvolutional,noisyMean,noisyStd,cleanMean,cleanStd);

Приложение реального времени

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

Запустите speechDenoisingRealtimeApp для примера того, как моделировать потоковую передачу, версию в реальном времени сети шумоподавления. Приложение использует сеть с полносвязными слоями. Аудио длина кадра равна размеру транзитного участка STFT, который является 0.25 * 256 = 64 выборки.

speechDenoisingRealtimeApp запускает Пользовательский интерфейс (UI), разработанный, чтобы взаимодействовать с симуляцией. Пользовательский интерфейс позволяет настройкам параметров, и результаты отражаются в симуляции немедленно. Можно также позволить/запретить подавитель шума, который управляет на denoised выводом, чтобы далее уменьшать шум, а также настроить время атаки, время релиза и порог подавителя шума. Можно слушать шумное, чистое или denoised аудио от пользовательского интерфейса.

Осциллограф строит чистое, шумное и сигналы denoised, а также усиление подавителя шума.

Ссылки

[1] https://www.kaggle.com/mozillaorg/common-voice

[2] "Эксперименты на глубоком обучении для речевого шумоподавления", Дин Лю, Париж Smaragdis, Миндж Ким, INTERSPEECH, 2014.

[3] "Полностью Сверточная нейронная сеть для речевого улучшения", парк Se Rim, Чжин выигранный Ли, INTERSPEECH, 2017.