任何一个数字,都是由10个基数构成的,本任务目的是借助于机器来实现英文语音数字的识别。下面,利用语音特征提取技术和卷积神经网络模型,对英文语音数字进行识别以解决上述问题。
#7.3task1
'''
任务1——提取音频的语音特征数据
'''
import scipy.io.wavfile as wav
import webrtcvad
import numpy as np
from python_speech_features import mfcc,delta
class VioceFeature():
#音频切分
def vad(self,file_path,mode=3):
print('tttt=',file_path)
samp_rate, signal_data = wav.read(file_path)
vad = webrtcvad.Vad(mode=mode)
signal= np.pad(signal_data,(0,160-(signal_data.shape[0]%int(samp_rate*0.02))),'constant')
lens = signal.shape[0]
signals = np.split(signal, lens//int(samp_rate*0.02))
audio = [];audios = []
for signal_item in signals:
if vad.is_speech(signal_item,samp_rate):
audio.append(signal_item)
elif len(audio)>0 and (not vad.is_speech(signal_item,samp_rate)):
audios.append(np.concatenate(audio, 0))
audio= []
return audios,samp_rate
#特征提取
def get_mfcc(self,data, samp_rate):
wav_feature = mfcc(data, samp_rate)
# 对mfcc特征进行一阶差分
d_mfcc_feat = delta(wav_feature, 1)
# 对mfcc特征进行二阶差分
d_mfcc_feat2 = delta(wav_feature, 2)
# 特征拼接
feature = np.concatenate([wav_feature.reshape(1, -1, 13), d_mfcc_feat.reshape(1, -1, 13), d_mfcc_feat2.reshape(1, -1, 13)], 0)
# 对数据进行截取或者填充
if feature.shape[1]>64:
feature = feature[:, :64, :]
else:
feature = np.pad(feature, ((0, 0), (0, 64-feature.shape[1]), (0, 0)), 'constant')
# 通道转置(HWC->CHW)
feature = feature.transpose((2, 0, 1))
# 新建空维度(CHW->NCHW)
feature = feature[np.newaxis, :]
return feature
from VioceFeature import *
voicefeature=VioceFeature()
audios,samp_rate=voicefeature.vad('D:/Python/chapter7/data1/audio.wav')
features = []
for audio in audios:
feature = voicefeature.get_mfcc(audio, samp_rate)
features.append(feature)
features = np.concatenate(features, 0).astype('float32')
print("features",features)
features.shape
print(features.shape)
定义类 VoiceFeature,主要包含两个成员方法 vad 和 get mfcc,分别实现语音切分和特征数据提取功能
#7.3task1
'''
任务1——提取音频的语音特征数据
'''
import scipy.io.wavfile as wav
import webrtcvad
import numpy as np
from python_speech_features import mfcc,delta
class VioceFeature():
#音频切分
def vad(self,file_path,mode=3):
print('tttt=',file_path)
samp_rate, signal_data = wav.read(file_path)
vad = webrtcvad.Vad(mode=mode)
signal= np.pad(signal_data,(0,160-(signal_data.shape[0]%int(samp_rate*0.02))),'constant')
lens = signal.shape[0]
signals = np.split(signal, lens//int(samp_rate*0.02))
audio = [];audios = []
for signal_item in signals:
if vad.is_speech(signal_item,samp_rate):
audio.append(signal_item)
elif len(audio)>0 and (not vad.is_speech(signal_item,samp_rate)):
audios.append(np.concatenate(audio, 0))
audio= []
return audios,samp_rate
#特征提取
def get_mfcc(self,data, samp_rate):
wav_feature = mfcc(data, samp_rate)
# 对mfcc特征进行一阶差分
d_mfcc_feat = delta(wav_feature, 1)
# 对mfcc特征进行二阶差分
d_mfcc_feat2 = delta(wav_feature, 2)
# 特征拼接
feature = np.concatenate([wav_feature.reshape(1, -1, 13), d_mfcc_feat.reshape(1, -1, 13), d_mfcc_feat2.reshape(1, -1, 13)], 0)
# 对数据进行截取或者填充
if feature.shape[1]>64:
feature = feature[:, :64, :]
else:
feature = np.pad(feature, ((0, 0), (0, 64-feature.shape[1]), (0, 0)), 'constant')
# 通道转置(HWC->CHW)
feature = feature.transpose((2, 0, 1))
# 新建空维度(CHW->NCHW)
feature = feature[np.newaxis, :]
return feature
在文件 7-3 task1.ipynb 中调用模块 VoiceFeature,编写以下代码,得到满足神经网络模型输入格式的特征数据。
代码行1导人 VoiceFeature 模块中的所有类,代码行2创建对象 voicefeature,代码行3调用对象 voicefeature 的方法 vad 完成语音切分。代码行 4~8对切分出的语音数据集 audios采用MFCC算法进行特征数据提取,提取后的结果保存在矩阵变量catures中。执行如下命令查看 features 的矩阵形状。
from VioceFeature import *
voicefeature=VioceFeature()
audios,samp_rate=voicefeature.vad('D:/Python/chapter7/data1/audio.wav')
features = []
for audio in audios:
feature = voicefeature.get_mfcc(audio, samp_rate)
features.append(feature)
features = np.concatenate(features, 0).astype('float32')
print("features",features)
features.shape
print(features.shape)
如图所示,特征矩阵features含4个语音数字,其特征数据分别保存在13通道3x64的矩阵中。为识别出是哪4个语音数字,还需要构建语音数字识别神经网络模型,利用模型对其做进一步处理。
该模型就是一个分类器,它的输入就是nx13x3x64的四维语音矩阵,它的输出是十维向量,第i维是语音片段被分类为第i个数字的概率,如Y=(0,1…,0)则表示该语音片段对应的数字是1。每两层卷积层为一个块,前一层负责提取特征数据,后一层负责下采样经过6层卷积操作后,形成1x8x64单通道特征输出,经过两层的全连接层进行分类,最终得到识别结果。模型的实现代码如下。
#7.3task2
'''
任务2——构建语音数字识别神经网络模型
'''
import paddle.fluid as fluid
from paddle.fluid.dygraph import Linear, Conv2D, BatchNorm
from paddle.fluid.layers import softmax_with_cross_entropy,accuracy,reshape
#定义语音识别网络模型
class AudioCNN(fluid.dygraph.Layer):
def __init__(self):
super().__init__()
self.conv1 = Conv2D(num_channels=13,num_filters=16,filter_size=3,stride=1,padding=1)
self.conv2 = Conv2D(16,16,(3,2),(1,2),(1,0))
self.conv3 = Conv2D(16,32,3,1,1)
self.conv4 = Conv2D(32,32,(3,2),(1,2),(1,0))
self.conv5 = Conv2D(32,64,3,1,1)
self.conv6 = Conv2D(64,64,(3,2),2)
self.fc1 = Linear(input_dim=1*8*64,output_dim=128,act='relu')
self.fc2 = Linear(128,10,act='softmax')
# 定义前向网络
def forward(self, inputs, labels=None):
out = self.conv1(inputs)
out = self.conv2(out)
out = self.conv3(out)
out = self.conv4(out)
out = self.conv5(out)
out = self.conv6(out)
out = reshape(out,[-1,8*64])
out = self.fc1(out)
out = self.fc2(out)
if labels is not None:
loss = softmax_with_cross_entropy(out, labels)
acc = accuracy(out, labels)
return loss, acc
else:
return out
将该python文件保存为final_model.py
代码行 12定义的二维卷积层的输人通道数与输人数据的通道格式一致(为 13),采用16个卷积核,卷积核大小即滤波器尺寸为 3x3,步长为1、填充尺寸为1,进行特征数据提取。在代码行5中,紧接着利用尺寸为3x2的滤波器,按水平、垂直方向设置步长分别为1和2、无填充来实现下采样。代码行13~17又完成两组特征数据提取和下采样操作,代码行19主要对卷积后的特征数据进行降维,形成一个1x128的向量,最后在代码行11完成分类操作。 代码行 22~31 定义前向网络,其中采用初始化方法init 中定义好的网络层依次对输人数据 inputs 进行前向处理,再返回处理后的结果,如果样本带有标签,则计算分类误差1oss和分类精度acc,否则直接返回分类结果 out。
通步骤1已经获取了英文数字的语音特征,并在步骤2中对构建的神经网络模型进行了训练。下面就利用保存的模型对语音特征数据进行分类工作,将分类结果合并,从而最终完成对语音的识别任务。根据任务目标按照以下步骤完成步骤3。
#7.3task3
'''
任务3——利用训练好的模型来识别语音
'''
#获得模型的语音特征输入数据
from VioceFeature import *
voicefeature=VioceFeature()
audios,samp_rate=voicefeature.vad('D:/Python/chapter7/data1/audio.wav')
features = []
for audio in audios:
feature = voicefeature.get_mfcc(audio, samp_rate)
features.append(feature)
features = np.concatenate(features, 0).astype('float32')
import numpy as np
import paddle.fluid as fluid
from paddle.fluid.dygraph import to_variable, load_dygraph
from AudioCNN import AudioCNN
with fluid.dygraph.guard(place=fluid.CPUPlace()):
model = AudioCNN()
params_dict, _ = load_dygraph('D:/Python/chapter7/data/final_model')
model.set_dict(params_dict)
model.eval()
features =to_variable(features)
out = model(features)
result = ' '.join([str(num) for num in np.argmax(out.numpy(),1).tolist()])
print('语音数字的识别结果是:',result)
前文的模型定义和训练来看,训练好最后的模型所花的时间相对还是很少的,主要是所使用的 AudioCNN卷积神经网络比较简单。但现实生活中,可能会遇到更复杂的机器学习、深度学习任务,需要运算速度更高的硬件(GPU、TPU),甚至同时使用多个机器其同执行一个任务(多卡训练和多机训练)。但本案例是在普通的计算机上进行训练和预测,所以通过以下语句配置模型识别的机器资源。
with fluid.dygraph.guard(place=fluid.CPUPlace()):
首先要构造一个模型实例 model,然后将前文训练好的模型 fnal model 参数加载到模型实例中。加载完毕后,还需将模型的状态调整为校验状态eval,这是因为模型在训练过程中要同时支持正向计算和反向传导梯度,此时的模型比较臃肿,而校验状态eval的模型只需支持正向计算,此时模型的实现简单且性能较高。对应的代码如下。
model = AudioCNN()
params_dict, _ = load_dygraph('D:/Python/chapter7/data/final_model')
model.set_dict(params_dict)
model.eval()
在步骤1中提取出英文语音数字的语音特征features,下面就基于该特征数据,利用训练好的模型进行语音识别,实现的代码如下。
features =to_variable(features)
out = model(features)
result = ' '.join([str(num) for num in np.argmax(out.numpy(),1).tolist()])
print('语音数字的识别结果是:',result)
代码行1将多维矩阵转换成飞桨支持的张量类型,代码行2将特征数据features作为模型的输人来预测识别结果。由于模型的输出out 仍是一个张量类型,因此在代码行3中对其进行 numpy转换,将其转换成一个二维数组,然后按行求各行中的最大值的索引,因为索引值与预测的数字值是一一对应的,故最后的拼接结果result 实际就是识别的数字。
作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。
但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的 AI大模型资料
包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
😝有需要的小伙伴,可以V扫描下方二维码免费领取🆓
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。
保证100%免费
】😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓