目录 传统的语音增强方法基于一些设定好的先验假设,但是这些先验存在一定的不合理之处。此外传统语音增强依赖于参数的设定,人工经验等。随着深度学习的发展,越来越多的人开始注意使用深度学习来解决语音增强问题。由于单通道使用场景较多,本文就以单通道语音增强为例。目前基于DNN单通道大致可以分为两种方法,第一种寻求噪声语音谱与纯净语音谱的映射(Map),另一种则是基于掩蔽(Mask)的方法。 基于映射的语音增强方法通过训练DNN模型将噪声谱与纯净谱之间的映射关系,其流程如下图所示,很多博客和文章也有讲这个方法但是我觉得不详细,让初学者一脸懵逼,下面详细介绍。 Label:数据的label为纯净语音信号的幅度谱,这里只需要一帧就够了 损失函数:学习噪声幅度谱与纯净语音信号的幅度谱类似于一个回归问题,因此损失函数采用回归常用的损失函数,如均方误差(Mean Squared Error,MSE) 最后一层的激活函数:由于是回归问题,最后一层采用线性激活函数 其他:输入的幅度谱进行归一化可以加速学习过程和更好的收敛。如果不采用幅度谱可以采用功率谱,要注意的是功率谱如果采用的单位是dB,需要对数据进行预处理,因为log的定义域不能为0,简单的方法就是在取对数前给等于0的功率谱加上一个非常小的数 输入:输入为噪声信号的幅度谱,这里同样需要扩帧。对输入数据进行处理可以在语音信号加上值为0的语音帧,或者舍弃首尾的几帧。如果训练过程对输入进行了归一化,那么这里同样需要进行归一化 输出:输入为估计的纯净语音幅度谱 重构波形:在计算输入信号幅度谱的时候需要保存每一帧的相位信息,然后用保存好的相位信息和模型输出的幅度谱重构语音波形,代码如下所示。 另一种方法是使用掩蔽的方法进行语音增强,基于掩蔽的方法基于这样的假设,在噪声谱中既存在噪声信号又存在语音信号,因此将噪声信号掩蔽掉剩下的就是语音信号。目前有常用的两种掩蔽方法,即理想二值掩蔽和理想比值掩蔽, 计算方法参考基于Mask的语音分离。 理想二值掩蔽(Ideal Binary Mask,IBM)中的分离任务就成为了一个二分类问题。这类方法根据听觉感知特性,把音频信号分成不同的子带,根据每个时频单元上的信噪比,把对应的时频单元的能量设为0(噪音占主导的情况下)或者保持原样(目标语音占主导的情况下) 理想比值掩蔽(Ideal Ratio Mask, IRM),它同样对每个时频单元进行计算,但不同于IBM的“非零即一”,IRM中会计算语音信号和噪音之间的能量比,得到介于0到1之间的一个数,然后据此改变时频单元的能量大小。IRM是对IBM的演进,反映了各个时频单元上对噪声的抑制程度,可以进一步提高分离后语音的质量和可懂度。 基于掩蔽的语音增强和基于映射的语音增强模型训练和增强过程类似,这里只提几个重要的地方,其余地方参考上面内容。 Label:数据的label为根据信噪比计算的IBM或者IRM,这里只需要一帧就够了 损失函数:IBM的损失函数可以用交叉熵,IRM的损失函数还是用均方差 最后一层的激活函数:IBM只有0和1两个值,IRM范围为[0,1],因此采用sigmoid激活函数就可以了 重构波形:首先用噪声幅度谱与计算的Mask值对应位置相乘,代码如下,然后根据相位信息重构语音波形。 首先看下实验效果,首先是基于映射语音增强的结果: 基于IBM语音增强的结果: 基于IRM语音增强的结果: 训练代码: 增强代码: 语音信号处理交流群: 652292630
1. 基于映射的语音增强
1.1 训练阶段:
1.2 增强阶段:
spectrum = magnitude * np.exp(1.0j * phase)
2. 基于掩蔽的语音增强
enhance_magnitude = np.multiply(magnitude, mask)
3. Demo效果以及代码
""" @FileName: IBM.py @Description: Implement IBM @Author: Ryuk @CreateDate: 2020/05/08 @LastEditTime: 2020/05/08 @LastEditors: Please set LastEditors @Version: v0.1 """ import numpy as np import librosa from sklearn.preprocessing import StandardScaler from keras.layers import * from keras.models import Sequential def generateDataset(): mix, sr = librosa.load("./mix.wav", sr=8000) clean,sr = librosa.load("./clean.wav", sr=8000) win_length = 256 hop_length = 128 nfft = 512 mix_spectrum = librosa.stft(mix, win_length=win_length, hop_length=hop_length, n_fft=nfft) clean_spectrum = librosa.stft(clean, win_length=win_length, hop_length=hop_length, n_fft=nfft) mix_mag = np.abs(mix_spectrum).T clean_mag = np.abs(clean_spectrum).T frame_num = mix_mag.shape[0] - 4 feature = np.zeros([frame_num, 257*5]) k = 0 for i in range(frame_num - 4): frame = mix_mag[k:k+5] feature[i] = np.reshape(frame, 257*5) k += 1 snr = np.divide(clean_mag, mix_mag) mask = np.around(snr, 0) mask[np.isnan(mask)] = 1 mask[mask > 1] = 1 label = mask[2:-2] ss = StandardScaler() feature = ss.fit_transform(feature) return feature, label def getModel(): model = Sequential() model.add(Dense(2048, input_dim=1285)) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.1)) model.add(Dropout(0.1)) model.add(Dense(2048)) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.1)) model.add(Dropout(0.1)) model.add(Dense(2048)) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.1)) model.add(Dropout(0.1)) model.add(Dense(257)) model.add(BatchNormalization()) model.add(Activation('sigmoid')) return model def train(feature, label, model): model.compile(optimizer='adam', loss='mse', metrics=['mse']) model.fit(feature, label, batch_size=128, epochs=20, validation_split=0.1) model.save("./model.h5") def main(): feature, label = generateDataset() model = getModel() train(feature, label, model) if __name__ == "__main__": main()
""" @FileName: Inference.py @Description: Implement Inference @Author: Ryuk @CreateDate: 2020/05/08 @LastEditTime: 2020/05/08 @LastEditors: Please set LastEditors @Version: v0.1 """ import librosa import numpy as np from basic_functions import * import matplotlib.pyplot as plt from sklearn.preprocessing import StandardScaler from keras.models import load_model def show(data, s): plt.figure(1) ax1 = plt.subplot(2, 1, 1) ax2 = plt.subplot(2, 1, 2) plt.sca(ax1) plt.plot(data) plt.sca(ax2) plt.plot(s) plt.show() model = load_model("./model.h5") data, fs = librosa.load("./test.wav", sr=8000) win_length = 256 hop_length = 128 nfft = 512 spectrum = librosa.stft(data, win_length=win_length, hop_length=hop_length, n_fft=nfft) magnitude = np.abs(spectrum).T phase = np.angle(spectrum).T frame_num = magnitude.shape[0] - 4 feature = np.zeros([frame_num, 257 * 5]) k = 0 for i in range(frame_num - 4): frame = magnitude[k:k + 5] feature[i] = np.reshape(frame, 257 * 5) k += 1 ss = StandardScaler() feature = ss.fit_transform(feature) mask = model.predict(feature) mask[mask > 0.5] = 1 mask[mask <= 0.5] = 0 fig = plt.figure() plt.imshow(mask, cmap='Greys', interpolation='none') plt.show() plt.close(fig) magnitude = magnitude[2:-2] en_magnitude = np.multiply(magnitude, mask) phase = phase[2:-2] en_spectrum = en_magnitude.T * np.exp(1.0j * phase.T) frame = librosa.istft(en_spectrum, win_length=win_length, hop_length=hop_length) show(data, frame) librosa.output.write_wav("./output.wav",frame, sr=8000)
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算