Этот пример показов, как осудить речевые сигналы с помощью нейронных сетей для глубокого обучения. В примере сравниваются два типа сетей, применяемых к одной и той же задаче: полносвязные и сверточные.
Цель шумоподавления речи состоит в том, чтобы удалить шум от речевых сигналов, улучшая при этом качество и разборчивость речи. Этот пример демонстрирует удаление шума стиральной машины от речевых сигналов с помощью нейронных сетей для глубокого обучения. В примере сравниваются два типа сетей, применяемых к одной и той же задаче: полносвязные и сверточные.
Примите во внимание следующий речевой сигнал, дискретизированный на частоте 8 кГц.
[cleanAudio,fs] = audioread("SpeechDFT-16-8-mono-5secs.wav");
sound(cleanAudio,fs)
Добавьте шум стиральной машины в речевой сигнал. Установите степень шума так, чтобы отношение сигнал/шум (ОСШ) составляло нуль дБ.
noise = audioread("WashingMachine-16-8-mono-1000secs.mp3"); % 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 кГц субъектов, говорящих короткие предложения. Загрузите набор данных и разархивируйте загруженный файл.
url = 'http://ssd.mathworks.com/supportfiles/audio/commonvoice.zip'; downloadFolder = tempdir; dataFolder = fullfile(downloadFolder,'commonvoice'); if ~exist(dataFolder,'dir') disp('Downloading data set (956 MB) ...') unzip(url,downloadFolder) end
Использование audioDatastore
чтобы создать datastore для набора обучающих данных. Чтобы ускорить выполнение примера за счет эффективности, установите reduceDataset
на true
.
adsTrain = audioDatastore(fullfile(dataFolder,'train'),'IncludeSubfolders',true); reduceDataset = true; if reduceDataset adsTrain = shuffle (adsTrain); adsTrain = subset (adsTrain, 1:1000); end
Использование read
для получения содержимого первого файла в datastore.
[audio,adsTrainInfo] = read(adsTrain);
Слушайте речевой сигнал.
sound(audio,adsTrainInfo.SampleRate)
Постройте график речевого сигнала.
figure t = (1/adsTrainInfo.SampleRate) * (0:numel(audio)-1); plot(t,audio) title("Example Speech Signal") xlabel("Time (s)") grid on
Базовая схема глубокого обучения показана ниже. Обратите внимание, что, поскольку речь обычно падает ниже 4 кГц, сначала вы понижаете частоту чистых и шумных аудиосигналов до 8 кГц, чтобы уменьшить вычислительную нагрузку сети. Предиктор и сигналы целевой сети являются спектрами величин шумных и чистых аудиосигналов, соответственно. Выходом сети является спектр величин деноизмененного сигнала. Регрессионная сеть использует вход предиктора, чтобы минимизировать среднюю квадратную ошибку между ее выходом и входной целью. Деноизированный аудио преобразуется назад во временной интервал с помощью выходного спектра величины и фазы сигнала с шумом [2].
Аудио преобразуется в частотный диапазон с помощью Short-Time Преобразования Фурье (STFT) с длиной окна 256 выборкой, перекрытием 75% и Окна Хэмминга. Вы уменьшаете размер спектрального вектора до 129 путем падения выборок частот, соответствующих отрицательным частотам (потому что речевой сигнал временной области действителен, это не приводит к какой-либо потере информации). Предикторный вход состоит из 8 последовательных шумных векторов STFT, так что каждая выходная оценка STFT вычисляется на основе текущего шумного STFT и 7 предыдущих шумных векторов STFT.
Этот раздел иллюстрирует, как сгенерировать сигналы цели и предиктора из одного обучающего файла.
Во-первых, задайте системные параметры:
windowLength = 256;
win = hamming(windowLength,"periodic");
overlap = round(0.75 * windowLength);
ffTLength = windowLength;
inputFs = 48e3;
fs = 8e3;
numFeatures = ffTLength/2 + 1;
numSegments = 8;
Создайте dsp.SampleRateConverter
объект для преобразования аудио 48 кГц в 8 кГц.
src = dsp.SampleRateConverter("InputSampleRate",inputFs, ... "OutputSampleRate",fs, ... "Bandwidth",7920);
Использование read
для получения содержимого аудио файла из datastore.
audio = read(adsTrain);
Убедитесь, что длина звука кратна коэффициенту десятикратного уменьшения преобразования частоты дискретизации.
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)
ans = 1×2
129 544
predictors = stftSegments; size(predictors)
ans = 1×3
129 8 544
Чтобы ускорить обработку, извлеките функцию последовательности из сегментов речи всех аудио файлов в datastore с помощью длинных массивов. В отличие от массивов в памяти, длинные массивы обычно остаются недооцененными, пока вы не вызываете gather
функция. Эта отсроченная оценка позволяет быстро работать с большими наборами данных. Когда вы в конечном счете запрашиваете выход с помощью gather
MATLAB объединяет вычисления в очереди, где это возможно, и принимает минимальное количество проходов через данные. Если у вас есть Parallel Computing Toolbox™, можно использовать длинные массивы в локальном Сеансе работы с MATLAB или в локальном параллельном пуле. Можно также запустить вычисления длинный массив на кластере, если установлена Server™ MATLAB ® Parallel.
Сначала преобразуйте datastore в длинный массив.
reset(adsTrain) T = tall(adsTrain)
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6).
T = M×1 tall cell array {234480×1 double} {210288×1 double} {282864×1 double} {292080×1 double} {410736×1 double} {303600×1 double} {326640×1 double} {233328×1 double} : : : :
Отображение указывает, что количество строк (соответствующее количеству файлов в datastore), M, пока не известно. M является заполнителем до завершения вычисления.
Извлеките целевую и предикторную величину STFT из длинная таблица. Это действие создает новые переменные длинный массив для использования в последующих вычислениях. Функция HelperGenerateSpeechDenoisingFeatures
выполняет шаги, уже выделенные в разделе STFT Targets and Predictors. The 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 42 sec Evaluation completed in 1 min 36 sec
Хорошей практикой является нормализация всех функций к нулю среднего и стандартного отклонения единства.
Вычислите среднее и стандартное отклонения предикторов и целей, соответственно, и используйте их для нормализации данных.
predictors = cat(3,predictors{:}); noisyMean = mean(predictors(:)); noisyStd = std(predictors(:)); predictors(:) = (predictors(:) - noisyMean)/noisyStd; targets = cat(2,targets{:}); 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));
Сначала рассмотрим обесценивающую сеть, состоящую из полносвязных слоев. Каждый нейрон в полностью соединенном слое соединяется со всеми активациями от предыдущего слоя. A полносвязного слоя умножает вход на весовую матрицу и затем добавляет вектор смещения. Размерности весовой матрицы и вектора смещения определяются количеством нейронов в слое и количеством активаций из предыдущего слоя.
Задайте слои сети. Задайте размер входа, чтобы быть изображениями размера NumFeatures
-by- NumSegments
(129 на 8 в этом примере). Задайте два скрытых полносвязных слоев, каждый с 1024 нейронами. Поскольку чисто линейные системы, следуйте за каждым скрытым полностью соединенным слоем с слоем 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, trainTarget, слои, опции); else url = 'http://ssd.mathworks.com/supportfiles/audio/SpeechDenoising.zip'; downloadNetFolder = tempdir; netFolder = fullfile (downloadNetFolder,'SpeechDenoising'); if ~ существует (netFolder,'dir') disp ('Downloading pretrained network (1 file - 8 MB) ...') unzip (url, downloadNetFolder) end s = загрузка (полный файл (netFolder,"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]. Сверточный слой 2-D применяет скользящие фильтры к входу. Слой свертывает входы, перемещая фильтры вдоль входов вертикально и горизонтально и вычисляя точечный продукт весов и входов, а затем добавляя термин смещения. Сверточные слои обычно состоят из меньшего количества параметров, чем полносвязные слои.
Задайте слои полностью сверточной сети, описанной в [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 (trainTarget, [3 1 2 4]), слои, опции); else url = 'http://ssd.mathworks.com/supportfiles/audio/SpeechDenoising.zip'; downloadNetFolder = tempdir; netFolder = fullfile (downloadNetFolder,'SpeechDenoising'); if ~ существует (netFolder,'dir') disp ('Downloading pretrained network (1 file - 8 MB) ...') unzip (url, downloadNetFolder) end s = загрузка (полный файл (netFolder,"denoisenet.mat")); denoiseNetFullyConvolutional = s.denoiseNetFullyConvolutional; cleanMean = s.cleanMean; cleanStd = s.cleanStd; noisyMean = s.noisyMean; noisyStd = s.noisyStd; end
Подсчитайте количество весов в полносвязных слоях сети.
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
Считайте в наборе тестовых данных.
adsTest = audioDatastore(fullfile(dataFolder,'test'),'IncludeSubfolders',true);
Чтение содержимого файла из datastore.
[cleanAudio,adsTestInfo] = read(adsTest);
Убедитесь, что длина звука кратна коэффициенту десятикратного уменьшения преобразования частоты дискретизации.
L = floor(numel(cleanAudio)/decimationFactor); cleanAudio = cleanAudio(1:decimationFactor*L);
Преобразуйте аудиосигнал в 8 кГц.
cleanAudio = src(cleanAudio); reset(src)
На этом этапе проверки вы коррумпируете речь с шумом стиральной машины, не используемым на этапе обучения.
noise = audioread("WashingMachine-16-8-mono-200secs.mp3");
Создайте сегмент случайного шума из вектора шума стиральной машины.
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;
Вычислите денойзированную величину 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];
Вычислите деноизированные речевые сигналы. 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);
Постройте график чистых, шумных и обесцененных аудиосигналов.
t = (1/fs) * (0:numel(denoisedAudioFullyConnected)-1); figure subplot(4,1,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)")
Стройте графики чистых, шумных и обесцененных спектрограмм.
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)
Слушайте деноизированную речь из сети с полносвязными слоями.
sound(denoisedAudioFullyConnected,fs)
Слушайте деноизированную речь из сети со сверточными слоями.
sound(denoisedAudioFullyConvolutional,fs)
Слушай чистую речь.
sound(cleanAudio,fs)
Можно протестировать больше файлов из datastore, позвонив testDenoisingNets
. Функция создает выделенные выше графики во временной и частотной областях, а также возвращает чистые, зашумленные и обесцененные аудиосигналы.
[cleanAudio,noisyAudio,denoisedAudioFullyConnected,denoisedAudioFullyConvolutional] = testDenoisingNets(adsTest,denoiseNetFullyConnected,denoiseNetFullyConvolutional,noisyMean,noisyStd,cleanMean,cleanStd);
Процедура в предыдущем разделе передает весь спектр сигнала с шумом, чтобы predict
. Это не подходит для приложений реального времени, где низкая задержка является требованием.
Выполняйте speechDenoisingRealtimeApp
для примера, как симулировать потоковую, в реальном времени версию деноизирующей сети. Приложение использует сеть с полностью подключенными слоями. Длина звуковой системы координат равна размеру скачка STFT, который составляет 0,25 * 256 = 64 выборки.
speechDenoisingRealtimeApp
запускает Пользовательский интерфейс (UI), предназначенный для взаимодействия с симуляцией. Пользовательский интерфейс позволяет вам настройкам параметров, и результаты отражаются в симуляции мгновенно. Можно также включить/отключить шумовые затворы, которые работают на деноизированном выходе, чтобы дополнительно уменьшить шум, а также настроить время атаки, время релиза и порог шумовых затворов. Можно слушать шумное, чистое или обесценившееся аудио из пользовательского интерфейса.
На возможности строятся графики чистых, шумных и обесцененных сигналов, а также усиления шумовых ворот.
[1] https://voice.mozilla.org/en
[2] «Эксперименты по глубокому обучению для шумоподавления речи», Дин Лю, Париж Смарагдис, Минье Ким, INTERSPEECH, 2014.
[3] «Полностью сверточная нейронная сеть для улучшения речи», Se Rim Park, Jin Won Lee, INTERSPEECH, 2017.