基于Tensorflow实现声纹识别

本文介绍了如何基于Tensorflow实现语音识别,包括安装librosa和pyAudio,使用pydub处理音频,训练分类模型,创建训练数据,以及实时录音识别。重点讲述了音频特征提取,如梅尔频谱和MFCCs,以及使用TFRecord提高训练速度。
摘要由CSDN通过智能技术生成

基于Tensorflow实现语音识别

安装librosa

librosa是一种用于音频处理的工具包,具有图形处理,特征提取,绘制声音图形。安装命令:
pip install pytest-runner
pip install librosa

安装pyAudio

pyAudio用于提取特征,训练并且使用分类器、语音分割功能、内容关系可视化
具体功能:
特征提取(feature extraction):关于时域信号和频域信号都有所涉及
分类(classification):监督学习,需要用已有的训练集来进行训练。交叉验证也实现了,进行参数优化使用。分类器可以保存在文件中以后使用。
回归(regression):将语音信号映射到一个回归值。
分割(segmenttation):有四个功能被实现了
[x] 固定大小的分割
[x] 静音检测(silence removal)
[x] 语音聚类(speaker diarization)
[x] 语音缩略图(audio thumbnailing)
可视化:给定语音,将内容可视化
安装命令:pip install pyaudio

pydub

用户处理音频的一个库:pip install pudub

训练分类模型

tip1:傅里叶变换(FFT):将音频信号从时域转换到频域
tip2:梅尔频谱:人们对频率的感知不是线性的,并且对低频较高频敏感,例如,我们可以轻松分辨出500 Hz和1000 Hz之间的差异,但是即使之间的距离相同,我们也很难分辨出10,000 Hz和10,500 Hz之间的差异。这是梅尔标度(The Mel Scale)被提出,它是HZ的非线性变换,对于以mel scale为单位的信号,人们可以做到对相同频率的信号感知相同,变换公式为
在这里插入图片描述

将音频转换成训练数据最重要使用的是librosa,使用librosa可以很方便地得到音频的梅尔频谱(Mel Spectrogram),使用的API为librosa.feature.melspectrogram(),输出的是numpy值。跟梅尔频谱同样很重要的**梅尔倒谱(MFCCs)**更多用于语音识别中,对应的 API 为 librosa.feature.mfcc()。同样以下的代码,就可以获取到音频的梅尔频谱,其中 duration 参数指定的是截取音频的长度。

y1,sr1=librosa.load(data_path,duration=2.97)
ps=librosa.feature.meispectrogram(y=y1,sr=sr1)

创建训练数据

根据上面的方法,我们创建Tensorflow训练数据,因为分类音频数据小而多,最好的方法就是将这些音频数据文件生成TFRecord文件,加快训练速度,创建!!!creat_data.py!!!,用于生成TFRecode文件
首先需要生成数据列表,用于下一步读取需要,audio_path为音频文件路径,用户需要提前把音频数据集存放在dataset/audio目录下,每个文件夹存放一个类别的音频数据,如dataset/audio/鸟叫声/…每条音频的数据长度大于2.1秒(自行定),audio是数据列表存放的位置,生成数据的格式为 音频路径/音频对应的类别标签

def get_data_list(audio_path, list_path):
    sound_sum = 0
    audios = 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')#用于存放

    for i in range(len(audios)):
        sounds = os.listdir(os.path.join(audio_path, audios[i]))#处理单独一个类声
        for sound in sounds:
            sound_path = os.path.join(audio_path, audios[i], sound)
            t = librosa.get_duration(filename=sound_path)
            # [可能需要修改参数] 过滤小于2.1秒的音频
            if t >= 2.1:
                if sound_sum % 100 == 0:
                    f_test.write('%s\t%d\n' % (sound_path, i))
                else:
                    f_train.write('%s\t%d\n' % (sound_path, i))
                sound_sum += 1
        print("Audio:%d/%d" % (i + 1, len(audios)))

    f_test.close()
    f_train.close()
   
if __name__ == '__main__':
    get_data_list('dataset/audio', 'dataset')
有了以上的数据列表,就可开始生成 TFRecord 文件了。最终会生成 train.tfrecord 和 test.tfrecord。笔者设置的音频长度为 2.04 秒,不足长度会补 0,如果需要使用不同的音频长度时,需要修改 wav_len 参数值和 len(ps)过滤值,wav_len 参数值为音频长度 16000 * 秒数,len(ps)过滤值为梅尔频谱 shape 相乘。

```python
# 获取浮点数组
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):
        value = [value]
    return tf.train.Feature(int64_list=tf.train.Int64List(value=value))


# 把数据添加到TFRecord中
def data_example(data, label):
    feature = {
        'data': _float_feature(data),
        'label': _int64_feature(label),
    }
    return tf.train.Example(features=tf.train.Features(feature=feature))


# 开始创建tfrecord数据
def create_data_tfrecord(data_list_path, save_path):
    with open(data_list_path, 'r') as f:
        data = f.readlines()
    with tf.io.TFRecordWriter(save_path) as writer:
        for d in tqdm(data):
            try:
                path, label = d.replace('\n', '').split('\t')
                wav, sr = librosa.load(path, sr=16000)
                intervals = librosa.effects.split(wav, top_db=20)
                wav_output = []
                # [可能需要修改参数] 音频长度 16000 * 秒数
                wav_len = int(16000 * 2.04)
                for sliced in intervals:
                    wav_output.extend(wav[sliced[0]:sliced[1]])#保留疑问?--盲猜是将np矩阵类型转为列表类型容易操作!
                for i in range(5):
                    # 裁剪过长的音频,过短的补0
                    if len(wav_output) > wav_len:
                        l = len(wav_output) - wav_len
                        r = random.randint(0, l)
                        wav_output = wav_output[r:wav_len + r]
                    else:
                        wav_output.extend(np.zeros(shape=[wav_len - len(wav_output)], dtype=np.float32))
                    wav_output = np.array(wav_output)
                    # 转成梅尔频谱
                    ps = librosa.feature.melspectrogram(y=wav_output, sr=sr, hop_length=256).reshape(-1).tolist()
                    # [可能需要修改参数] 梅尔频谱shape ,librosa.feature.melspectrogram(y=wav_output, sr=sr, hop_length=256).shape
                    if len(ps) != 128 * 128: continue#跳过下面的语句继续执行循环体下一条
                    tf_example = data_example(ps, int(label))
                    writer.write(tf_example.SerializeToString())#序列化存储
                    if len(wav_output) <= wav_len:
                        break
            except Exception as e:
                print(e)


if __name__ == '__main__':
    create_data_tfrecord('dataset/train_list.txt', 'dataset/train.tfrecord')
    create_data_tfrecord('dataset/test_list.txt', 'dataset/test.tfrecord')

Urbansound8K 是目前应用较为广泛的用于自动城市环境声分类研究的公共数据集,包含 10 个分类:空调声、汽车鸣笛声、儿童玩耍声、狗叫声、钻孔声、引擎空转声、枪声、手提钻、警笛声和街道音乐声。数据集下载地址:https://zenodo.org/record/1203745/files/UrbanSound8K.tar.gz。以下是针对 Urbansound8K 生成数据列表的函数。如果读者想使用该数据集,请下载并解压到 dataset 目录下,把生成数据列表代码改为以下代码

# 创建UrbanSound8K数据列表
def get_urbansound8k_list(path, urbansound8k_cvs_path):
    data_list = []
    data = pd.read_csv(urbansound8k_cvs_path)
    # 过滤掉长度少于3秒的音频
    valid_data = data[['slice_file_name', 'fold', 'classID', 'class']][data['end'] - data['start'] >= 3]
    valid_data['path'] = 'fold' + valid_data['fold'].astype('str') + 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值