在做ASR和KWS实验时,必不可少的需要对语音数据预处理,提取特征(业内常见是提取为MFCC),最后再喂入模型中。数据预处理可分为离线处理和在线处理:
后面章节将介绍语音预处理、特征提取到特征文件
语音预处理常用工具是librosa或者audiomentations,下面将介绍基于audiomentations的数据预处理;
audiomentations工具是一款GitHub开源的语音处理工具,主要有
import audiomentations
import librosa
def audio_preprocessing(file):
""" file为wav语音文件,返回离散语音数据 """
data , sr = librosa.core.load(file) # 语音流转为离散数值
augmenter = Compose([
AddGaussianNoise(min_amplitude=0.001, max_amplitude=0.015, p=0.5),
TimeStretch(min_rate=0.8, max_rate=1.25, p=0.5),
PitchShift(min_semitones=-4, max_semitones=4, p=0.5),
Shift(min_fraction=-0.5, max_fraction=0.5, p=0.5),
])
return augmenter(audio, sample_rate=sr) # 语音预处理,返回离散语音数据
特征文件常见的有.h5,.npy, .txt, .csv等 ,前两种比较受欢迎,其读写速度都比较快,博客详细的介绍他们的性能;这里我采用.h5文件保存特征,但是.h5有一个问题,多线程读取一个文件时会出现报错:
据说.h5多线程本身的问题,因此需要用到多线程的需要注意。
下面简单介绍下hdf5文件存储特征时,节省空间的小技巧。
博客详细的讲解了特征提取为MFCC的过程,这里简单介绍:
import librosa
def extract_feature_1(file):
""" file 为 数组"""
melspectrogram = librosa.feature.melspectrogram(y=file, sr=16000, n_fft=2048, hop_length=1024) # mel滤波
s =librosa.power_to_db(melspectrogram) # 取对数
mfcc = librosa.feature.mfcc(S=s, n_mfcc=20) # MFCC,这里其实可以一步到位,去掉melspectrogram、power_to_db操作都可以
mfcc_delta = librosa.feature.delta(mfcc)
mfcc_delta_delta = librosa.feature.delta(mfcc_delta) # 偏微分
mfcc_comb = np.concatenate([mfcc, mfcc_delta, mfcc_delta_delta], axis=0)
return mfcc_comb
DCT变换只提取了频谱的包络信息,损失了大量声音细节,特征也失去了,因此在深度学习中,采用特征更加丰富的Mel谱信息作为特征更优。下面我们定义只提取到mei谱的特征函数。
import librosa
def extract_feature(file):
""" file 为 数组"""
melspectrogram = librosa.feature.melspectrogram(y=file, sr=16000, n_fft=2048, hop_length=1024, n_mels=40) # mel滤波
mel =librosa.power_to_db(melspectrogram) # 取对数
return mel
假设数据特征shape(1,40, 101),若没有补0.
import h5py
import audio_preprocessing,extract_feature
def extract_feature_to_h5(data)
"""data为数组,存储的为语音wav文件 """
### 预处理 audio_preprocessing()
audio_data = []
for wav in data:
audio_data.append(audio_preprocessing(wav))
### 特征提取
features = []
for wav in audio_data:
item = extract_feature(wav)
item = np.pad(data, (0, max(0, in_len - item.shape[1])), "constant") # 数据格式对齐(1,40,101)
features.appen(item.reshape(1,40,101))
### 特征保存到文件.h5
h5_train = h5py.File("Train.h5", 'w') # 新建一个Train.h5文件
h5_data = h5_train.create_dataset("data", data=[[[]]], maxshape=(None, 40, 101), chunks=(1, 40, 101), compression="gzip", compression_opts=9) # 在.h5文件中创建data 数据集,后续需要重新添加数据,因此数据集大小不能写死maxshape=(None,101,40)中None说明可以随时写入数据集。
for i, item in enumerate(features):
h5_data .resize((i+1,40, 101))
h5_data [i] = item
h5_data.close()