简介
结合上节课的内容,使用WaveNet进行语音分类
原理
对于每一个MFCC特征都输出一个概率分布,然后结合CTC算法即可实现语音识别
相比之下,语音分类要简单很多,因为对于整个MFCC特征序列只需要输出一个分类结果即可
语音分类和语音识别的区别,可以类比一下文本分类和序列标注的区别
具体实现时,只需要稍微修改一下网络结构即可
数据
使用科大讯飞方言种类识别AI挑战赛提供的数据,http://challenge.xfyun.cn/,初赛提供了6种方言,复赛提供了10种方言
每种方言包括30个人每人200条共计6000条训练数据,以及10个人每人50条共计500条验证数据
数据以pcm格式提供,可以理解为wav文件去掉多余信息之后,仅保留语音数据的格式
实现
以下以长沙、南昌、上海三种方言数据为例,介绍如何实现语音分类
加载库
# -*- coding:utf-8 -*-
import numpy as np
import os
from matplotlib import pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
%matplotlib inline
from sklearn.utils import shuffle
import glob
import pickle
from tqdm import tqdm
from keras.models import Model
from keras.preprocessing.sequence import pad_sequences
from keras.layers import Input, Activation, Conv1D, Add, Multiply, BatchNormalization, GlobalMaxPooling1D, Dropout
from keras.optimizers import Adam
from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau
from python_speech_features import mfcc
import librosa
from IPython.display import Audio
import wave
加载pcm文件,共1W8条训练数据,1.5K条验证数据
train_files = glob.glob('data/*/train/*/*.pcm')
dev_files = glob.glob('data/*/dev/*/*/*.pcm')
print(len(train_files), len(dev_files), train_files[0])
整理每条语音数据对应的分类标签
labels = {'train': [], 'dev': []}
for i in tqdm(range(len(train_files))):
path = train_files[i]
label = path.split('/')[1]
labels['train'].append(label)
for i in tqdm(range(len(dev_files))):
path = dev_files[i]
label = path.split('/')[1]
labels['dev'].append(label)
print(len(labels['train']), len(labels['dev']))
定义处理语音、pcm转wav、可视化语音的三个函数,由于语音片段长短不一,所以去除少于1s的短片段,对于长片段则切分为不超过3s的片段
mfcc_dim = 13
sr = 16000
min_length = 1 * sr
slice_length = 3 * sr
def load_and_trim(path, sr=16000):
audio = np.memmap(path, dtype='h', mode='r')
audio = audio[2000:-2000]
audio = audio.astype(np.float32)
energy = librosa.feature.rmse(audio)
frames = np.nonzero(energy >= np.max(energy) / 5)
indices = librosa.core.frames_to_samples(frames)[1]
audio = audio[indices[0]:indices[-1]] if indices.size else a