之前简单的利用深层自编码器对语音信号进行降噪
基于自编码器的语音信号降噪 - 哥廷根数学学派的文章 - 知乎 基于自编码器的语音信号降噪 - 知乎
本篇讲一些稍微复杂的基于深度学习的语音降噪方法,并比较了应用于同一任务的两种的网络:全连接层网络和卷积网络。
完整代码和数据集见如下链接
考虑以下以 8 kHz 采样的语音信号
[cleanAudio,fs] = audioread("SpeechDFT.wav");
sound(cleanAudio,fs)
将洗衣机噪声添加到上述的语音信号中,设置噪声功率,使信噪比 (SNR) 为0dB
noise = audioread("WashingMachine.mp3");
接下来从噪声文件中的随机位置提取噪声段
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
语音降噪的目的是从语音信号中去除洗衣机噪声,同时最大限度地减少输出语音信号中不希望的所谓的artifacts。
检查数据集
本例使用的数据集包含 48 kHz 的短句录音
训练集,测试集,验证集文件
训练集部分数据
使用 audioDatastore 为训练集创建数据存储
adsTrain = audioDatastore(fullfile(dataFolder,'train'),'IncludeSubfolders',true);
读取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
深度学习系统概述
基本的深度学习训练方案如下图所示。
对于熟悉语音信号处理的同学肯定是小case。注意,由于语音通常低于 4 kHz,因此首先将干净和嘈杂的语音信号下采样到 8 kHz,以减少网络的计算负担。 网络的输出是降噪信号的幅度谱,使用输出幅度谱和噪声信号的相位将降噪后的音频转换回时域[1]。
可以使用短时傅里叶变换 (STFT) 将音频信号转换到频域,使用Hamming窗,窗口长度为 256 ,重叠率为 75%。Predicter的输入由 8 个连续的噪声 STFT 向量组成,因此每个 STFT 输出估计值都是基于当前的噪声 STFT 和 7 个先前的噪声 STFT 向量计算的。
如何从一个训练文件生成Target和Predicter(直接用英文单词了,否则容易引起误解)?首先,定义系统参数:
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 kHz 音频转换为 8 kHz,
src = dsp.SampleRateConverter("InputSampleRate",inpu