Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Denoise voz mediante redes de aprendizaje profundo

Este ejemplo muestra cómo DeNoise las señales de voz usando las redes de aprendizaje profundo. En el ejemplo se comparan dos tipos de redes aplicadas a la misma tarea: totalmente conectadas y convolucionales.

Introducción

El objetivo del discurso que denota es eliminar el ruido de las señales de voz y mejorar la calidad e inteligibilidad del habla. Este ejemplo muestra la eliminación del ruido de la lavadora de las señales de voz mediante redes de aprendizaje profundo. En el ejemplo se comparan dos tipos de redes aplicadas a la misma tarea: totalmente conectadas y convolucionales.

Resumen del problema

Considere la siguiente señal de voz muestreada a 8 kHz.

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

Agregue el ruido de la lavadora a la señal de voz. Fije la potencia de ruido de tal forma que la relación señal-ruido (SNR) sea cero dB.

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; 

Escuche la ruidosa señal de voz.

sound(noisyAudio,fs) 

Visualice las señales originales y ruidosas.

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 

El objetivo del habla denozante es eliminar el ruido de la lavadora de la señal de voz mientras se minimizan los artefactos no deseados en la voz de salida.

Examine el DataSet

Este ejemplo utiliza el conjunto de datos de voz común de Mozilla [1] para entrenar y probar las redes de aprendizaje profundo. El conjunto de datos contiene grabaciones de 48 kHz de temas que hablan frases cortas. Descargue el conjunto de datos y descomprima el archivo descargado. Establezca la ubicación de los datos.datafolder

datafolder = PathToDatabase; 

Se utiliza para crear un almacén de datos para los archivos de la carpeta.audioDatastorecv-valid-train

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

Utilízese para aleatorizar el orden de los archivos en el almacén de datos.shuffle

ads = shuffle(ads); 

Entrenará las redes de aprendizaje profundo en un subconjunto de los archivos. Cree un subconjunto de almacenes de datos que contenga los primeros 1000 archivos del almacén de datos.

ads = subset(ads,1:1000); 

Se usa para obtener el contenido del primer archivo en el almacén de datos.read

[audio,info] = read(ads); 

Escuche la señal de voz.

sound(audio,info.SampleRate) 

Trace la señal de voz.

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

Información general del sistema de aprendizaje profundo

A continuación se muestra el esquema de formación básica de aprendizaje profundo. Tenga en cuenta que, dado que el habla generalmente cae por debajo de 4 kHz, primero downsample las señales de audio limpias y ruidosas a 8 kHz para reducir la carga computacional de la red. Las señales de predicción y de red de destino son los espectros de magnitud de las señales de audio ruidosas y limpias, respectivamente. La salida de la red es el espectro de magnitud de la señal denozada. La red de regresión utiliza la entrada predictora para minimizar el error cuadrado medio entre su salida y el destino de entrada. El audio denozado se convierte de nuevo al dominio de tiempo utilizando el espectro de magnitud de salida y la fase de la señal ruidosa [2].

Puede transformar el audio en el dominio de frecuencia utilizando la transformada de Fourier de tiempo corto (STFT), con una longitud de ventana de 256 muestras, una superposición de 75% y una ventana de Hamming. Reduce el tamaño del vector espectral a 129 colocando las muestras de frecuencia correspondientes a frecuencias negativas (porque la señal de voz del dominio del tiempo es real, esto no conduce a ninguna pérdida de información). La entrada predictora consta de 8 vectores STFT ruidosos consecutivos, de modo que cada estimación de salida STFT se calcula basándose en el ruido actual de STFT y en los 7 vectores STFT ruidosos anteriores.

STFT targets y predictores

Esta sección ilustra cómo generar las señales de destino y predictor a partir de un archivo de entrenamiento.

Primero, defina los parámetros del sistema:

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

Defina el convertidor de frecuencia de muestreo utilizado para convertir el audio de 48 kHz a 8 kHz.

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

Se usa para obtener el contenido de un archivo de audio del almacén de datos.read

audio = read(ads); 

Asegúrese de que la longitud de audio sea un múltiplo del factor de decimación del convertidor de frecuencia de muestreo.

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

Convierta la señal de audio a 8 kHz.

audio = src(audio); reset(src) 

Cree un segmento de ruido aleatorio del vector de ruido de la lavadora.

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

Agregue el ruido a la señal de voz de tal forma que el SNR sea 0 dB.

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

Se utiliza para generar vectores STFT de magnitud a partir de las señales de audio originales y ruidosas.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,:)); 

Genere las señales predictoras de entrenamiento de 8 segmentos del ruidoso STFT. La superposición entre predictores consecutivos es de 7 segmentos.

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 

Establezca los objetivos y los predictores. La última dimensión de ambas variables corresponde al número de pares de predictor/objetivo distintos generados por el archivo de audio. Cada predictor es 129-por-8, y cada objetivo es 129-por-1.

targets = cleanSTFT; size(targets) predictors = stftSegments; size(predictors) 
 ans =     129   457   ans =     129     8   457  

Extraiga entidades utilizando matrices altas

Para acelerar el procesamiento, extraiga secuencias de entidades de los segmentos de voz de todos los archivos de audio del almacén de datos utilizando matrices altas. A diferencia de las matrices en memoria, las matrices altas normalmente permanecen sin evaluar hasta que se llama a la función.gather Esta evaluación diferida le permite trabajar rápidamente con grandes conjuntos de datos. Cuando finalmente se solicita la salida utilizando, MATLAB combina los cálculos en cola donde sea posible y toma el número mínimo de pasadas a través de los datos.gather Si tiene Parallel Computing Toolbox™, puede utilizar matrices altas en la sesión de MATLAB local o en un grupo paralelo local. También puede ejecutar cálculos de matriz altos en un clúster si tiene instalado MATLAB® Parallel Server™.

En primer lugar, convierta el almacén de datos en una matriz alta.

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}         :        :         :        :  

La pantalla indica que el número de filas (correspondiente al número de archivos en el almacén de datos), M, aún no se conoce. M es un marcador de posición hasta que finaliza el cálculo.

Extraiga el objetivo y la magnitud del predictor STFT de la tabla alta. Esta acción crea nuevas variables de matriz altas para usarlas en cálculos posteriores. La función realiza los pasos ya resaltados en la sección.HelperGenerateSpeechDenoisingFeaturesSTFT Targets and Predictors El comando se aplica al contenido de cada archivo de audio en el almacén de datos.cellfunHelperGenerateSpeechDenoisingFeatures

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

Se usa para evaluar los objetivos y predictores.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 

Es una buena práctica normalizar todas las características a cero media y la desviación estándar de la unidad.

Calcule la media y la desviación estándar de los predictores y destinos, respectivamente, y utilícelos para normalizar los datos.

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; 

Remodele predictores y objetivos a las dimensiones que esperan las redes de aprendizaje profundo.

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

Utilizará el 1% de los datos para la validación durante el entrenamiento. La validación es útil para detectar escenarios en los que la red está sobreajustada a los datos de entrenamiento.

Divida los datos aleatoriamente en conjuntos de entrenamiento y validación.

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)); 

Denozación del habla con capas completamente conectadas

Primero se considera una red de eliminación de ruido compuesta por capas completamente conectadas. Cada neurona en una capa completamente conectada está conectada a todas las activaciones de la capa anterior. Una capa completamente conectada multiplica la entrada por una matriz de peso y luego agrega un vector de sesgo. Las dimensiones de la matriz de peso y el vector de sesgo se determinan por el número de neuronas en la capa y el número de activaciones de la capa anterior.

Defina las capas de la red. Especifique el tamaño de entrada para que sean imágenes de tamaño NumFeatures-by-NumSegments (129-by-8 en este ejemplo). Define dos capas ocultas completamente conectadas, cada una con 1024 neuronas. Desde sistemas puramente lineales, siga cada capa oculta completamente conectada con una capa de unidad lineal rectificada (ReLU). Las capas de normalización de lotes normalizan los medios y las desviaciones estándar de las salidas. Añade una capa completamente conectada con 129 neuronas, seguida de una capa de regresión.

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

A continuación, especifique las opciones de formación para la red. Configurado para que la red haga 3 pases a través de los datos de entrenamiento.MaxEpochs3 Conjunto de modo que la red mira a 128 señales de entrenamiento a la vez.MiniBatchSize128 Especifique como para generar trazados que muestren el progreso del entrenamiento a medida que aumente el número de iteraciones.Plots"training-progress" Se establece en para deshabilitar la impresión de la salida de tabla que corresponde a los datos mostrados en la gráfica en la ventana de línea de comandos.Verbosefalse Especifique cómo mezclar las secuencias de entrenamiento al principio de cada época.Shuffle"every-epoch" Especifique para disminuir la tasa de aprendizaje por un factor especificado (0,9) cada vez que haya transcurrido un cierto número de épocas (1).LearnRateSchedule"piecewise" Se establece en los predictores y destinos de validación.ValidationData Establecer tal que el error cuadrado medio de validación se calcula una vez por época.ValidationFrequency Este ejemplo utiliza el solucionador de estimación de momento adaptativo (Adam).

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}); 

Entrena la red con las opciones de entrenamiento especificadas y la arquitectura de capas usando.trainNetwork Dado que el conjunto de entrenamiento es grande, el proceso de entrenamiento puede tardar varios minutos. Para cargar una red entrenada previamente en lugar de entrenar una red desde cero, establezca en.doTrainingfalse

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 

Cuente el número de pesos en las capas completamente conectadas de la red.

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. 

Palabras que denotan con capas convolucionales

Considere una red que utiliza capas convolucionales en lugar de capas completamente conectadas [3]. Una capa convolucional 2-D aplica filtros deslizantes a la entrada. La capa convoluciona la entrada moviendo los filtros a lo largo de la entrada vertical y horizontalmente y calculando el producto escalar de las ponderaciones y la entrada, y luego añadiendo un término de sesgo. Las capas convolucionales suelen consistir en menos parámetros que las capas totalmente conectadas.

Defina las capas de la red totalmente convolucional descrita en [3], que comprende 16 capas convolucionales. Las primeras 15 capas convolucionales son grupos de 3 capas, repetidas 5 veces, con anchos de filtro de 9, 5 y 9, y el número de filtros de 18, 30 y 8, respectivamente. La última capa convolucional tiene un ancho de filtro de 129 y 1 filtro. En esta red, las convoluciones se realizan en una sola dirección (a lo largo de la dimensión de frecuencia) y el ancho del filtro a lo largo de la dimensión de tiempo se establece en 1 para todas las capas excepto la primera. Al igual que en la red completamente conectada, las capas convolucionales son seguidas por ReLu y capas de normalización de lotes.

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           ]; 

Las opciones de formación son idénticas a las opciones de la red totalmente conectada, salvo que las dimensiones de las señales de destino de validación se permutan para que sean coherentes con las dimensiones que espera la capa de regresión.

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])}); 

Entrena la red con las opciones de entrenamiento especificadas y la arquitectura de capas usando.trainNetwork Dado que el conjunto de entrenamiento es grande, el proceso de entrenamiento puede tardar varios minutos. Para cargar una red entrenada previamente en lugar de entrenar una red desde cero, establezca en.doTrainingfalse

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. 

Cuente el número de pesos en las capas completamente conectadas de la red.

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 

Pruebe las redes de Denozante

Utilice las señales de voz de la carpeta "CV-Valid-test" para probar el rendimiento de las redes entrenadas. Se utiliza para crear un almacén de datos para los archivos en la carpeta "CV-Valid-test".audioDatastore

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

Mezclar los archivos en el almacén de datos.

ads = shuffle(ads); 

Lea el contenido de un archivo del almacén de datos.

[cleanAudio,info] = read(ads); 

Asegúrese de que la longitud de audio sea un múltiplo del factor de decimación del convertidor de frecuencia de muestreo.

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

Convierta la señal de audio a 8 kHz.

cleanAudio = src(cleanAudio); reset(src) 

En esta etapa de prueba, usted corrompió el habla con el ruido de la lavadora no utilizado en la etapa de entrenamiento.

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

Cree un segmento de ruido aleatorio del vector de ruido de la lavadora.

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

Agregue el ruido a la señal de voz de tal forma que el SNR sea 0 dB.

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

Se utiliza para generar vectores STFT de magnitud a partir de las ruidosas señales de audio.stft

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

Genere las señales predictoras de entrenamiento de 8 segmentos del ruidoso STFT. La superposición entre predictores consecutivos es de 7 segmentos.

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 

Normalizar los predictores por la media y la desviación estándar calculada en la etapa de entrenamiento.

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

Calcule la magnitud denozada STFT utilizando con las dos redes entrenadas.predict

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

Escale las salidas por la media y la desviación estándar utilizada en la etapa de entrenamiento.

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

Convierta el STFT unilateral en un STFT centrado.

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]; 

Calcule las señales de voz denozadas. realiza el STFT inverso.istft Utilice la fase de los ruidosos vectores STFT para reconstruir la señal de dominio del tiempo.

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

Trace las señales de audio limpias, ruidosas y denozadas.

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)") 

Trace los espectrogramas limpios, ruidosos y denoterizados.

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]); 

Escuche el discurso ruidoso.

sound(noisyAudio,fs) 

Escuche el discurso denozado de la red con capas completamente conectadas.

sound(denoisedAudioFullyConnected,fs) 

Escuche el discurso denozado de la red con capas convolucionales.

sound(denoisedAudioFullyConvolutional,fs) 

Escuche el discurso limpio.

sound(cleanAudio,fs) 

Puede probar más archivos desde el almacén de datos mediante una llamada.testDenoisingNets La función produce las parcelas de dominio de tiempo y de dominio de frecuencia resaltadas anteriormente, y también devuelve las señales de audio limpias, ruidosas y denozadas.

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

Aplicación en tiempo real

El procedimiento en la sección anterior pasa todo el espectro de la señal ruidosa a.predict Esto no es adecuado para aplicaciones en tiempo real donde la latencia baja es un requisito.

Ejecute un ejemplo de Cómo simular una versión de streaming en tiempo real de la red de eliminación de ruido.speechDenoisingRealtimeApp La aplicación utiliza la red con capas completamente conectadas. La longitud del marco de audio es igual al tamaño del salto STFT, que es 0,25 * 256 = 64 muestras.

inicia una interfaz de usuario (IU) diseñada para interactuar con la simulación.speechDenoisingRealtimeApp La interfaz de usuario le permite ajustar los parámetros y los resultados se reflejan en la simulación al instante. También puede activar/desactivar una compuerta de ruido que opere en la salida denozada para reducir aún más el ruido, así como ajustar el tiempo de ataque, el tiempo de liberación y el umbral de la compuerta de ruido. Puede escuchar el sonido ruidoso, limpio o denozado de la interfaz de usuario.

El alcance traza las señales limpias, ruidosas y denozadas, así como la ganancia de la compuerta de ruido.

Referencias

[1] https://voice.mozilla.org/

[2] "experimentos sobre aprendizaje profundo para el habla denoising", Ding Liu, Paris Smaragdis, Minje Kim, INTERSPEECH, 2014.

[3] "una red neuronal totalmente convolucional para la mejora del habla", se RIM Park, Jin Won Lee, INTERSPEECH, 2017.