当前位置: 首页 > news >正文

基于Python+WaveNet+MFCC+Tensorflow智能方言分类—深度学习算法应用(含全部工程源码)(二)

目录

  • 前言
  • 引言
  • 总体设计
    • 系统整体结构图
    • 系统流程图
  • 运行环境
  • 模块实现
    • 1. 数据预处理
      • 1)数据介绍
      • 2)数据测试
      • 3)数据处理
  • 相关其它博客
  • 工程源代码下载
  • 其它资料下载


在这里插入图片描述

前言

博主前段时间发布了一篇有关方言识别和分类模型训练的博客,在读者的反馈中发现许多小伙伴对方言的辨识和分类表现出浓厚兴趣。鉴于此,博主决定专门撰写一篇关于方言分类的博客,以满足读者对这一主题的进一步了解和探索的需求。上篇博客可参考:

《基于Python+WaveNet+CTC+Tensorflow智能语音识别与方言分类—深度学习算法应用(含全部工程源码)》

引言

本项目以科大讯飞提供的数据集为基础,通过特征筛选和提取的过程,选用WaveNet模型进行训练。旨在通过语音的梅尔频率倒谱系数(MFCC)特征,建立方言和相应类别之间的映射关系,解决方言分类问题。

首先,项目从科大讯飞提供的数据集中进行了特征筛选和提取。包括对语音信号的分析,提取出最能代表语音特征的MFCC,为模型训练提供有力支持。

其次,选择了WaveNet模型进行训练。WaveNet模型是一种序列生成器,用于语音建模,在语音合成的声学建模中,可以直接学习采样值序列的映射,通过先前的信号序列预测下一个时刻点值的深度神经网络模型,具有自回归的特点。

在训练过程中,利用语音的MFCC特征,建立了方言和相应类别之间的映射关系。这样,模型能够识别和分类输入语音的方言,并将其划分到相应的类别中。

最终,通过这个项目,实现了方言分类问题的解决方案。这对于语音识别、语音助手等领域具有实际应用的潜力,也有助于保护和传承各地区的语言文化。

总体设计

本部分包括系统整体结构图和系统流程图。

系统整体结构图

系统整体结构如图所示。

在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

运行环境

本部分包括Python环境、TensorFlow环境、JupyterNotebook环境、PyCharm环境。

详见博客。

模块实现

本项目包括4个模块:数据预处理、模型构建、模型训练及保存、模型生成。下面分别给出各模块的功能介绍及相关代码。

1. 数据预处理

本部分包括数据介绍、数据测试和数据处理。

1)数据介绍

数据集网址为:challenge.xfyun.cn,向用户免费提供了3种方言(长沙话、南昌话、上海话),每种方言包括30人,每人200条数据,共计18000条训练数据,以及10人、每人50条,共计1500条验证数据。数据以pcm格式提供,可以理解为.wav文件去掉多余信息之后仅保留语音数据的格式。

2)数据测试

使用Audition进行语音测试,导出mp3格式进行检测,如图所示。

在这里插入图片描述

使用MATLAB得到该语音片段的波形和MFCC特征,相关代码如下:

[x, fs]=audioread('test.mp3');
bank=melbankm(24,256,fs,0,0.4,'m');
%Mel滤波器的阶数为24
%fft变换的长度为256,采样频率为8000Hz
%归一化mel滤波器组系数
bank=full(bank);
bank=bank/max(bank(:));
for k=1:12	%归一化mel滤波器组系数
n=0:23;
dctcoef(k,:)=cos((2*n+1)*k*pi/(2*24));
end
w=1+6*sin(pi*[1:12]./12);%归一化倒谱提升窗口
w=w/max(w);%预加重滤波器
xx=double(x);
xx=filter([1-0.9375],1,xx);%语音信号分帧
xx=enframe(xx,256,80);%对*256点分为一帧
%计算每帧的MFCC参数
for i=1:size(xx,1)
y=xx(i,:);
s=y'.*hamming(256);
t=abs(fft(s));%fft快速傅立叶变换
t=t.^2;
c1=dctcoef*log(bank*t(1:129));
c2=c1.*w';
m(i,:)=c2';
end
%求取差分系数
dtm=zeros(size(m));
for i=3:size(m,1)-2
dtm(i,:)=-2*m(i-2,:)-m(i-1,:)+m(i+1,:)+2*m(i+2,:);
end
dtm=dtm/3;
%合并mfcc参数和一阶差分mfcc参数
ccc=[m dtm];
%去除首尾两帧,因为这两帧的一阶差分参数为0
ccc=ccc(3:size(m,1)-2,:);
subplot(2,1,1) 
ccc_1=ccc(:,1);
plot(ccc_1);title('MFCC');ylabel('幅值');
[h,w]=size(ccc);
A=size(ccc);
subplot(212) ;
plot([1,w],A);
xlabel('维数');
ylabel('幅值');
title('维数与幅值的关系')

运行代码,成功得到一段语音的波形片段和MFCC特征,如图1和图2所示。

在这里插入图片描述

图1 语音片段波形图

在这里插入图片描述

图2 Matlab提取MFCC特征图

3)数据处理

本部分包括数据处理过程中的相关代码。

(1)加载库。在实验过程中,通过查找发现Matplotlib包内没有中文字体,加载库之后添加参数设定或者更改Matplotlib默认字体可以解决。相关代码如下:

#-*- coding:utf-8 -*-
import numpy as np
import os
from matplotlib import pyplot as plt
#在实验过程中使用pyplot参数设置,使得图像可打印中文,且中文内容格式应该为u“内容”
plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
plt.rcParams['axes.unicode_minus']=False 
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

(2)加载pcm文件,共18000条训练数据,1500条验证数据,相关代码如下:

train_files = glob.glob('data/*/train/*/*.pcm')
dev_files = glob.glob('data/*/dev/*/*/*.pcm')
#glob.glob()用于查找符合特定规则的文件路径名,并返回所有匹配的文件路径列表
#其中“*”为匹配符,匹配多个字符
print(len(train_files), len(dev_files), train_files[0])
#读取代码成功,打印结果

(3)整理每条语音数据对应的分类标签,相关代码如下:

labels = {'train': [], 'dev': []}
#使用dict与list类型嵌套存储分类标签
#tqdm打印进度条,用于观察读取情况
for i in tqdm(range(len(train_files))):path = train_files[i]label = path.split('/')[1]#使用split将path以“/”分隔的字符串进行切片,并选取第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']))
#读取代码成功,打印结果

(4)定义处理语音、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')#使用numpy内的memmap函数读写大文件,返回对象可使用ndarray算法操作audio = audio[2000:-2000]audio = audio.astype(np.float32)#astype实现dataframe类型转换energy = librosa.feature.rmse(audio)#librosa为音频处理包,使用feature.rmse求均方根误差frames = np.nonzero(energy >= np.max(energy) / 5)#nonzero()函数将布尔数组转为整数数组,用于进行下标运算#nonzero()返回参数数组中值不为0的元素下标,返回类型是元组#元组的每个元素均为一个整数数组,值为非零元素下标在对应帧的值indices = librosa.core.frames_to_samples(frames)[1]#将样本索引采样转换为帧audio = audio[indices[0]:indices[-1]] if indices.size else audio[0:0]slices = []for i in range(0, audio.shape[0], slice_length):s = audio[i: i + slice_length]if s.shape[0] >= min_length:slices.append(s)#长度>3s进行切片,<1s过滤return audio, slices
#文件格式处理,pcm转为wav函数
def pcm2wav(pcm_path, wav_path, channels=1, bits=16, sample_rate=sr):data = open(pcm_path, 'rb').read()fw = wave.open(wav_path, 'wb')#设置转化为.wav格式时相同的参数(通道数、采样率等)fw.setnchannels(channels)	#通道fw.setsampwidth(bits // 8)fw.setframerate(sample_rate)	#采样率fw.writeframes(data)	#写入fw.close()
#语音可视化
def visualize(index, source='train'):#可视化语音,默认可视化训练集内的语音,也可以选择参数“dev”可视化测试集if source == 'train':path = train_files[index]else:path = dev_files[index]print(path)audio, slices = load_and_trim(path)#读取语音信号print('Duration: %.2f s' % (audio.shape[0] / sr))#使用matplotlob库内的pyplot进行绘图plt.figure(figsize=(12, 3))plt.plot(np.arange(len(audio)), audio)plt.title(u'未处理信号')plt.xlabel(u'时间')plt.ylabel(u'信号幅度值')plt.show()#展示未处理的音频信号feature = mfcc(audio, sr, numcep=mfcc_dim)#提取MFCC特征print('Shape of MFCC:',feature.shape)#进行画图fig = plt.figure(figsize=(12, 5))#figsize指定figure的宽和高,单位为英寸ax = fig.add_subplot(111)#subplot()为图像分区,参数111表示只有一张图im = ax.imshow(feature,cmap=plt.cm.jet, aspect='auto')#imshow热图绘制,通过色差、亮度展示数据的差异plt.title(u'归一化MFCC')plt.ylabel('时间')plt.xlabel('MFCC参数')plt.colorbar(im,cax=make_axes_locatable(ax).append_axes('right', size='5%', pad=0.05))		
#给图配渐变色时,在图旁边把色标(colorbar)标注出来#其中cax参数表示将要绘制颜色条的轴ax.set_xticks(np.arange(0,13,2),minor=False);#设置横坐标刻度plt.show()wav_path = 'example.wav'pcm2wav(path,wav_path)return wav_path
Audio(visualize(2))	#调用函数选取其中一条语音信号进行可视化

读取代码成功可以得到一句长沙话对应的波形和MFCC特征,如图所示。

在这里插入图片描述

(5)整理数据,查看语音片段的长度分布,最后得到18890个训练片段,1632个验证片段。相关代码如下:

X_train = []  #参数设置
X_dev = []
Y_train = []
Y_dev = []
lengths = []
for i in tqdm(range(len(train_files))):path = train_files[i]audio, slices = load_and_trim(path)	#取语音信号lengths.append(audio.shape[0] / sr)	#除以sr(=16000)换算成时间长度for s in slices:  #按照片段进行训练X_train.append(mfcc(s, sr, numcep=mfcc_dim))Y_train.append(labels['train'][i])
for i in tqdm(range(len(dev_files))):  #输出参数path = dev_files[i]audio, slices = load_and_trim(path)lengths.append(audio.shape[0] / sr)for s in slices:X_dev.append(mfcc(s, sr, numcep=mfcc_dim))Y_dev.append(labels['dev'][i])
print(len(X_train), len(X_dev))
plt.hist(lengths, bins=100)#matplotlib中的hist()函数,用于可视化生成直方图
plt.show()

读取代码成功,如图所示。

在这里插入图片描述

(6)将MFCC特征进行归一化处理,相关代码如下:

#矩阵堆叠,沿竖直方向矩阵堆叠
samples = np.vstack(X_train) 
#计算每一列的平均值(axis=0)
mfcc_mean = np.mean(samples, axis=0)
#计算每一列的标准差(axis=0)
mfcc_std = np.std(samples, axis=0)
print(mfcc_mean)
print(mfcc_std)
#归一化处理
X_train = [(x - mfcc_mean) / (mfcc_std + 1e-14) for x in X_train]
X_dev = [(x - mfcc_mean) / (mfcc_std + 1e-14) for x in X_dev]
maxlen = np.max([x.shape[0] for x in X_train + X_dev])
X_train = pad_sequences(X_train, maxlen, 'float32', padding='post', value=0.0) 
#pad_sequences对序列进行预处理
#maxlen参数为序列的最大长度,返回类型dtype为float32,“post”表示需要补0时在末尾补
X_dev = pad_sequences(X_dev, maxlen, 'float32', padding='post', value=0.0)
print(X_train.shape, X_dev.shape)

(7)对分类标签进行处理,相关代码如下:

from sklearn.preprocessing import LabelEncoder
from keras.utils import to_categorical
#将标签标准化
le = LabelEncoder()
#为非监督学习
Y_train = le.fit_transform(Y_train) #fit_transform()
Y_dev = le.transform(Y_dev)
print(le.classes_)
class2id = {c: i for i, c in enumerate(le.classes_)}
#enumerate将可遍历数据对象组合为索引序列
id2class = {i: c for i, c in enumerate(le.classes_)}
num_class = len(le.classes_)
Y_train = to_categorical(Y_train, num_class)
#keras内的to_categorical将类别向量转换为二进制矩阵类型表示
Y_dev = to_categorical(Y_dev, num_class)
print(Y_train.shape, Y_dev.shape)
#代码运行,获得分类标签的处理图

(8)定义产生批数据的迭代器,相关代码如下:

batch_size = 16
def batch_generator(x, y, batch_size=batch_size):   #批次处理offset = 0while True:offset += batch_sizeif offset == batch_size or offset >= len(x):#将序列的所有元素随机排序
x, y = shuffle(x, y)	offset = batch_sizeX_batch = x[offset - batch_size: offset]    Y_batch = y[offset - batch_size: offset]#yield返回生成器
yield (X_batch, Y_batch) 

相关其它博客

基于Python+WaveNet+MFCC+Tensorflow智能方言分类—深度学习算法应用(含全部工程源码)(一)

基于Python+WaveNet+MFCC+Tensorflow智能方言分类—深度学习算法应用(含全部工程源码)(三)

基于Python+WaveNet+MFCC+Tensorflow智能方言分类—深度学习算法应用(含全部工程源码)(四)

工程源代码下载

详见本人博客资源下载页


其它资料下载

如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载》
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。

相关文章:

  • class类实现operator==重载
  • 【LeetCode】28. 找出字符串中第一个匹配项的下标 【字符串单模匹配:KMP算法】
  • 【Hadoop_04】HDFS的API操作与读写流程
  • 《地理信息系统原理》笔记/期末复习资料(10. 空间数据挖掘与空间决策支持系统)
  • AI全栈大模型工程师(二十三)用 PyTorch 训练一个最简单的神经网络
  • 微信小程序:上传图片到别的域名文件下
  • element日历组件只显示月和日,把年份隐藏掉
  • 电脑入门基础知识
  • “百里挑一”AI原生应用亮相,百度智能云千帆AI加速器首个Demo Day来了!
  • ​configparser --- 配置文件解析器​
  • 高通平台开发系列讲解(USB篇)MBIM协议详解
  • 蚂蚁SEO的百度蜘蛛池有哪些优势
  • 搜索引擎和网络浏览器之间的区别
  • filebeat 后端运行,自动退出解决
  • Layui深入
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • Docker: 容器互访的三种方式
  • jquery ajax学习笔记
  • JS 面试题总结
  • Laravel5.4 Queues队列学习
  • Swift 中的尾递归和蹦床
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 利用jquery编写加法运算验证码
  • 那些年我们用过的显示性能指标
  • 你不可错过的前端面试题(一)
  • 消息队列系列二(IOT中消息队列的应用)
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • (03)光刻——半导体电路的绘制
  • (04)odoo视图操作
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (poj1.3.2)1791(构造法模拟)
  • (附源码)php投票系统 毕业设计 121500
  • (三) diretfbrc详解
  • (转)Mysql的优化设置
  • *** 2003
  • ... 是什么 ?... 有什么用处?
  • .equals()到底是什么意思?
  • .NET 设计一套高性能的弱事件机制
  • .NET/C# 使用反射注册事件
  • .net快速开发框架源码分享
  • @RunWith注解作用
  • @Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成
  • @Transactional 竟也能解决分布式事务?
  • [20181219]script使用小技巧.txt
  • [AX]AX2012 R2 出差申请和支出报告
  • [BZOJ 3531][Sdoi2014]旅行(树链剖分+线段树)
  • [IE9] IE9 RC版下载链接
  • [ITIL学习笔记]之事件管理(2)
  • [LeetCode] 19. 删除链表的倒数第 N 个结点
  • [LeetCode] Wildcard Matching
  • [LeetCode]—Rotate Image 矩阵90度翻转