- 离线处理: 训练之前先对语音数据进行加噪音、调低\高音量、1.5倍速播放等(有人用工具audiomentations),然后再提取MFCC特征到特征文件里(特征文件格式.h5,.csv),训练时数据集从特征文件读取,不需要再预处理了.
优点: 只需提取特征一次就可以多次训练,时间减少很多;
缺点: 每个epoch喂入模型的数据特征都是一样的(提取到特征文件,其实特征就被写死了),变相的降低了数据集可增强的空间,模型泛化能力会降低; - 在线处理: 对数据进行预处理,然后提取MFCC特征,最后喂入模型中。每一个epoch都会进行预处理,再喂入模型;
优点: 数据集可增强空间变大(相当于有epoch个数据集),模型泛化能力强;
缺点: 训练时间长,显存消耗大;
一些音频增强的方法
1.导入必要包
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import librosa
import matplotlib.pyplot as plt
import os
import cv2
import IPython.display as ipd
EPS = 1e-8
#获取频谱函数
def get_spectrogram(wav):
D = librosa.stft(wav, n_fft=480, hop_length=160,
win_length=480, window='hamming')
spect, phase = librosa.magphase(D)
return spect
加载wav
file_path = './1.wav'
wav, sr = librosa.load(file_path, sr=None)
print(wav.shape, wav.max(), wav.min())
librosa显示的是归一化后的数值,torchaudio显示是原始的数值
(95984,) 0.047088623 -0.041259766
#播放wav
ipd.Audio(wav, rate=sr)
#显示频谱图
log_spect = np.log(get_spectrogram(wav))
print('spectrogram shape:', log_spect.shape)
plt.imshow(log_spect, aspect='auto', origin='lower',)
plt.title('spectrogram of origin audio')
plt.show()
#spectrogram shape: (241, 600)
时间偏移
start_ = int(np.random.uniform(-4800,4800))
print('time shift: ',start_)
if start_ >= 0:
wav_time_shift = np.r_[wav[start_:], np.random.uniform(-0.001,0.001, start_)]
else:
wav_time_shift = np.r_[np.random.uniform(-0.001,0.001, -start_), wav[:start_]]
ipd.Audio(wav_time_shift, rate=sr)
spectrogram shape: (241, 600)
速度变化及音频填充剪切
data = np.array(wav)
print(data.shape)
speed_rate = np.random.uniform(0.5)
wav_speed_tune = cv2.resize(wav, (1, int(len(wav) * speed_rate))).squeeze()
print('speed rate: %.3f' % speed_rate, '(lower is faster)')
print(len(wav_speed_tune))
# if len(wav_speed_tune) < 16000:
# pad_len = 16000 - len(wav_speed_tune)
# wav_speed_tune = np.r_[np.random.uniform(-0.001,0.001,int(pad_len/2)),
# wav_speed_tune,
# np.random.uniform(-0.001,0.001,int(np.ceil(pad_len/2)))]
# else:
# cut_len = len(wav_speed_tune) - 16000
# wav_speed_tune = wav_speed_tune[int(cut_len/2):int(cut_len/2)+16000]
print('wav length: ', wav_speed_tune.shape[0])
ipd.Audio(wav_speed_tune, rate=sr)
(95984,) speed rate: 0.810 (lower is faster) 77744 wav length: 77744
log_spect = np.log(get_spectrogram(wav_speed_tune)+EPS)
print('spectrogram shape:', log_spect.shape)
plt.imshow(log_spect, aspect='auto', origin='lower',)
plt.title('spectrogram of speed tuned audio')
plt.show()
spectrogram shape: (241, 486) 可以发现音频长度变短了
混合背景背景音同时随机改变音量
随机选择一片背景噪音,然后将其与语音混合,同时随机调整音量
#裁取背景音
bg_files = os.listdir('../input/train/audio/_background_noise_/')
bg_files.remove('README.md')
chosen_bg_file = bg_files[np.random.randint(6)]
bg, sr = librosa.load('../input/train/audio/_background_noise_/'+chosen_bg_file, sr=None)
print(chosen_bg_file,'|', bg.shape[0], bg.max(), bg.min())
ipd.Audio(bg, rate=sr) # !! be prepared when playing the noise, bacause it's so ANNOYING !!
#融合
start_ = np.random.randint(bg.shape[0]-16000)
bg_slice = bg[start_ : start_+16000]
wav_with_bg = wav * np.random.uniform(0.8, 1.2) + \
bg_slice * np.random.uniform(0, 0.1)
ipd.Audio(wav_with_bg, rate=sr)
或者
#生成噪音
samples = np.random.uniform(low=-0.2, high=0.2, size=wav.shape).astype(np.float32)
ipd.Audio(samples,rate=16000)
# samples.shape (95984,)
# wav.shape (95984,)
#调节音量,混合噪音
wav_with_bg = wav * np.random.uniform(0.8, 1.4) + \
samples * np.random.uniform(0, 0.01)
audiomentations的食用方法(github地址)
1. AddBackgroundNoise
混入其他声音,例如 背景噪音。 如果您的原始声音很干净并且想要模拟存在背景噪音的环境,则很有用。必须指定要混入(背景噪音)声音的文件夹。 理想情况下,这些声音应至少与要转换的输入声音一样长。 否则,背景声音将被重复,听起来可能不自然。请注意,增加的噪声的增益与输入中的信号量有关。 这意味着,如果输入完全静音,则不会添加任何噪声。
2.AddGaussianNoise
增加高斯噪音
AddGaussianNoise(min_amplitude=0.001, max_amplitude=0.015, p=0.5),
3.AddGaussianSNR
使用随机信噪比(SNR)将高斯噪声添加到样本中
4.AddImpulseResponse
用随机脉冲响应对音频进行卷积。 可以使用例如来创建脉冲响应。 http://tulrich.com/recording/ir_capture/
脉冲响应在给定的ir_path中表示为wav文件。
5.AddShortNoises
混入各种声音(重叠的突发声),之间有随机的停顿。 如果您的原始声音很干净,并且您想要模拟有时会产生短噪音的环境,则很有用。
必须指定要混入(杂音)声音的文件夹。
6.FrequencyMask
屏蔽频谱图上的某些频带。 受https://arxiv.org/pdf/1904.08779.pdf启发
7.Gain
将音频乘以随机幅度因子以减小或增大音量。 此技术可以帮助模型在某种程度上相对于输入音频的整体增益保持不变。
警告:此转换可能会返回[-1,1]范围之外的样本,这可能会导致削波或环绕失真,具体取决于您稍后对音频的处理方式。 另请参阅https://en.wikipedia.org/wiki/Clipping_(audio)#Digital_clipping
8.PitchShift
在不改变节奏的情况下,调高或调低声音
9.TimeMask
Make a randomly chosen part of the audio silent. Inspired by https://arxiv.org/pdf/1904.08779.pdf
10.SpecFrequencyMask
屏蔽频谱图中的一组频率,例如Google AI SpecAugment。 事实证明,这种类型的数据增强使语音识别模型更强大。
可以用原始值的平均值或给定常数(例如零)代替被掩盖的频率。