前言
本章介绍如何使用Tensorflow实现简单的声纹识别模型,首先你需要熟悉音频分类,没有了解的可以查看这篇文章《基于Tensorflow实现声音分类》。基于这个知识基础之上,我们训练一个声纹识别模型,通过这个模型我们可以识别说话的人是谁,可以应用在一些需要音频验证的项目。
环境准备
主要介绍libsora,PyAudio,pydub的安装,其他的依赖包根据需要自行安装。
Python 3.7
Tensorflow 2.0
安装libsora
最简单的方式就是使用pip命令安装,如下:
pip install pytest-runner
pip install librosa
如果pip命令安装不成功,那就使用源码安装,下载源码:https://github.com/librosa/librosa/releases/, windows的可以下载zip压缩包,方便解压。
pip install pytest-runner
tar xzf librosa-.tar.gz 或者 unzip librosa-.tar.gz
cd librosa-/
python setup.py install
如果出现libsndfile64bit.dll': error 0x7e错误,请指定安装版本0.6.3,如pip install librosa==0.6.3
安装PyAudio
使用pip安装命令,如下:
pip install pyaudio
在安装的时候需要使用到C++库进行编译,如果读者的系统是windows,Python是3.7,可以在这里下载whl安装包,下载地址:https://github.com/intxcc/pyaudio_portaudio/releases
安装pydub
使用pip命令安装,如下:
pip install pydub
创建数据
本教程笔者使用的是Free ST Chinese Mandarin Corpus数据集,这个数据集一共有855个人的语音数据,有102600条语音数据。如果读者有其他更好的数据集,可以混合在一起使用。
如何已经读过笔者《基于Tensorflow实现声音分类》这篇文章,应该知道语音数据小而多,最好的方法就是把这些音频文件生成TFRecord,加快训练速度。所以创建create_data.py用于生成TFRecord文件。
首先是创建一个数据列表,数据列表的格式为,创建这个列表主要是方便之后的读取,也是方便读取使用其他的语音数据集,不同的语音数据集,可以通过编写对应的生成数据列表的函数,把这些数据集都写在同一个数据列表中,这样就可以在下一步直接生成TFRecord文件了。
def get_data_list(audio_path, list_path):
files = os.listdir(audio_path)
f_train = open(os.path.join(list_path, 'train_list.txt'), 'w')
f_test = open(os.path.join(list_path, 'test_list.txt'), 'w')
sound_sum = 0
s = set()
for file in files:
if '.wav' not in file:
continue
s.add(file[:15])
sound_path = os.path.join(audio_path, file)
if sound_sum % 100 == 0:
f_test.write('%s\t%d\n' % (sound_path.replace('\\', '/'), len(s) - 1))
else:
f_train.write('%s\t%d\n' % (sound_path.replace('\\', '/'), len(s) - 1))
sound_sum += 1
f_test.close()
f_train.close()
if __name__ == '__main__':
get_data_list('dataset/ST-CMDS-20170001_1-OS', 'dataset')
有了上面创建的数据列表,就可以把语音数据转换成训练数据了,主要是把语音数据转换成梅尔频谱(Mel Spectrogram),使用librosa可以很方便得到音频的梅尔频谱,使用的API为librosa.feature.melspectrogram(),输出的是numpy值,可以直接用tensorflow训练和预测。关于梅尔频谱具体信息读者可以自行了解,跟梅尔频谱同样很重要的梅尔倒谱(MFCCs)更多用于语音识别中,对应的API为librosa.feature.mfcc()。在转换过程中,笔者还使用了librosa.effects.split裁剪掉静音部分的音频,这样可以减少训练数据的噪声,提供训练准确率。笔者目前默认每条语音的长度为2.04秒,这个读者可以根据自己的情况修改语音的长度,如果要修改训练语音的长度,需要根据注释的提示修改相应的数据值。如果语音长度比较长的,程序会随机裁剪20次,以达到数据增强的效果。
# 获取浮点数组
def _float_feature(value):
if not isinstance(value, list):
value = [value]
return tf.train.Feature(float_list=tf.train.FloatList(value=value))
# 获取整型数据
def _int64_feature(value):
if not isinstance(value, list):</