语音分类入门案例: 英文数字音频分类

news2025/2/27 8:46:34

语音分类入门案例: 英文数字音频分类

本项目是一个全流程的语音分类项目,内容简单,适合想要涉猎音频分类的小白学习。

推荐将本项目Fork成为自己的项目并运行,以获得更好的学习体验!! 项目地址:语音分类入门:全流程英文数字音频识别

1. 解压数据集

我们使用的数据集是FSDD(free-spoken-digit-dataset),
FSDD是一个简单的音频/语音数据集,由 8kHz 文件中的语音数字记录组成。内含由6位音频录制人员录制的3000条数字(0-9)的英语发音音频数据(每人50条)。

!unzip data/data176422/FSDD.zip

2.配置环境依赖

  • 需要安装python_speech_features库,这是一个强大的音频处理库,我们进行持久化安装
!pip install python_speech_features -t  /home/aistudio/external-libraries
import sys 
sys.path.append('/home/aistudio/external-libraries') #将持久化安装的库加入环境中

import paddle
import os
from tqdm import tqdm
import random
from glob import glob
import numpy as np
import matplotlib.pyplot as plt
from functools import partial
from IPython import display
import soundfile
from python_speech_features import mfcc, delta # 导入音频特征提取工具包
import scipy.io.wavfile as wav

3.数据加载与处理

3.1 音频数据展示,绘制波形

example_path='FSDD/0_george_14.wav'

# 读取音频
# fs--采样率 signal--音频信号
fs, signal = wav.read(example_path)
print('这段音频的采样率为:%d' % fs)
print('音频信号:', signal)
print('音频信号形状:', signal.shape)

# 绘制波形
import matplotlib.pyplot as plt
plt.figure(figsize=(8,2))
x = [_ for _ in range(len(signal))]
plt.plot(x, signal)
plt.show()
这段音频的采样率为:8000
音频信号: [ 12  39 179 ...  83  68 114]
音频信号形状: (4304,)

在这里插入图片描述

3.2 划分数据集

  • 获取音频文件名称列表
  • 打乱音频文件名称列表
  • 训练集:验证集:测试集=0.9:0.05:0.05
#获取音频文件名称列表
data_path='FSDD'
wavs = glob("{}/*.wav".format(data_path), recursive=True)
print(type(wavs),wavs[0])

# 打乱音频文件名称列表
random.shuffle(wavs)
wavs_len=len(wavs)
print("总数据数量:\t",wavs_len)


#训练集:验证集:测试集=0.9:0.05:0.05
# 训练集
train_wavs=wavs[:int(wavs_len*0.9)]
# 验证集
val_wavs=wavs[int(wavs_len*0.9):int(wavs_len*0.95)]
# 测试集
test_wavs=wavs[int(wavs_len*0.95):]

print("训练集数目:\t",len(train_wavs),"\n验证集数目:\t",len(val_wavs),"\n测试集数目:\t",len(test_wavs))
<class 'list'> FSDD/1_george_13.wav
总数据数量:	 3000
训练集数目:	 2700
验证集数目:	 150
测试集数目:	 150

3.3 MFCC特征提取

MFCC(Mel Frequency Cepstral Coefficent)是一种在自动语音和说话人识别中广泛使用的特征。

在这里插入图片描述

关于MFCC比较详细的介绍文档可以参考:语音信号处理之(四)梅尔频率倒谱系数(MFCC)

# MFCC特征提取
def get_mfcc(data, fs):
    # MFCC特征提取
    wav_feature =  mfcc(data, fs)
  
    # 特征一阶差分
    d_mfcc_feat = delta(wav_feature, 1)
    # 特征二阶差分
    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))
  
    return feature

# 读取音频
fs, signal = wav.read(example_path)
# 特征提取
feature = get_mfcc(signal, fs)
print('特征形状(CHW):', feature.shape,type(feature))
特征形状(CHW): (13, 3, 64) <class 'numpy.ndarray'>

3.4 音频转向量,标签提取

def preproess(wavs):
    datalist=[]
    lablelist=[]
    for w in tqdm(wavs):
        lablelist.append([int(w[5])])
        fs, signal = wav.read(w)
        f = get_mfcc(signal, fs)
        datalist.append(f)
    return np.array(datalist),np.array(lablelist)

train_data,train_lable=preproess(train_wavs)
val_data,val_lable=preproess(val_wavs)
test_data,test_lable=preproess(test_wavs)

#print(type(train_data),train_lable[0])
100%|██████████| 2700/2700 [01:34<00:00, 28.65it/s]
100%|██████████| 150/150 [00:05<00:00, 28.87it/s]
100%|██████████| 150/150 [00:05<00:00, 27.83it/s]

3.5 组装数据集

class MyDataset(paddle.io.Dataset):
    """
    步骤一:继承paddle.io.Dataset类
    """
    def __init__(self,audio,text):
        """
        步骤二:实现构造函数,定义数据集大小
        """
        super(MyDataset, self).__init__()
        self.text = text
        self.audio = audio

    def __getitem__(self, index):
        """
        步骤三:实现__getitem__方法,定义指定index时如何获取数据,并返回单条数据(训练数据,对应的标签)
        """
        return self.audio[index],self.text[index]

    def __len__(self):
        """
        步骤四:实现__len__方法,返回数据集总数目
        """
        return self.audio.shape[0]
def prepare_input(inputs):
    src=np.array([inputsub[0] for inputsub in inputs]).astype('float32')
    trg=np.array([inputsub[1] for inputsub in inputs])
    return src,trg

train_dataset = MyDataset(train_data,train_lable)
train_loader = paddle.io.DataLoader(train_dataset, batch_size=64, shuffle=True,drop_last=True,collate_fn=partial(prepare_input))

val_dataset = MyDataset(val_data,val_lable)
val_loader = paddle.io.DataLoader(val_dataset, batch_size=64, shuffle=True,drop_last=True,collate_fn=partial(prepare_input))
for i,data in enumerate(train_loader):
    for d in data:
        print(d.shape)
    break
[64, 13, 3, 64]
[64, 1]

4.组装网络

4.1 使用CNN网络

class audio_Net(paddle.nn.Layer):
    def __init__(self):
        super(audio_Net, self).__init__()
        self.conv1 = paddle.nn.Conv2D(13, 16, 3, 1, 1)
        self.conv2 = paddle.nn.Conv2D(16, 16, (3, 2), (1, 2), (1, 0))
        self.conv3 = paddle.nn.Conv2D(16, 32, 3, 1, 1)
        self.conv4 = paddle.nn.Conv2D(32, 32, (3, 2), (1, 2), (1, 0))
        self.conv5 = paddle.nn.Conv2D(32, 64, 3, 1, 1)
        self.conv6 = paddle.nn.Conv2D(64, 64, (3, 2), 2)
        self.fc1 = paddle.nn.Linear(8*64, 128)
        self.fc2 = paddle.nn.Linear(128, 10)
  
  
    # 定义前向网络
    def forward(self, inputs):
        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 = paddle.reshape(out, [-1, 8*64])
        out = self.fc1(out)
        out = self.fc2(out)

        return out


4.2 查看网络结构

audio_network=audio_Net()
paddle.summary(audio_network,input_size=[(64,13,3,64)],dtypes=['float32'])
W1112 12:44:10.491739   269 gpu_resources.cc:61] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 11.2
W1112 12:44:10.494805   269 gpu_resources.cc:91] device: 0, cuDNN Version: 8.2.

---------------------------------------------------------------------------
 Layer (type)       Input Shape          Output Shape         Param #
===========================================================================
   Conv2D-1      [[64, 13, 3, 64]]     [64, 16, 3, 64]         1,888
Conv2D-2      [[64, 16, 3, 64]]     [64, 16, 3, 32]         1,552
Conv2D-3      [[64, 16, 3, 32]]     [64, 32, 3, 32]         4,640
Conv2D-4      [[64, 32, 3, 32]]     [64, 32, 3, 16]         6,176
Conv2D-5      [[64, 32, 3, 16]]     [64, 64, 3, 16]        18,496
Conv2D-6      [[64, 64, 3, 16]]      [64, 64, 1, 8]        24,640
Linear-1         [[64, 512]]           [64, 128]           65,664
Linear-2         [[64, 128]]            [64, 10]            1,290
===========================================================================
Total params: 124,346
Trainable params: 124,346
Non-trainable params: 0
Input size (MB): 0.61
Forward/backward pass size (MB): 6.32
Params size (MB): 0.47
Estimated Total Size (MB): 7.40
---------------------------------------------------------------------------
{'total_params': 124346, 'trainable_params': 124346}

4.3 模型训练

epochs = 20 

model=paddle.Model(audio_network)


model.prepare(optimizer=paddle.optimizer.Adam(learning_rate=0.001,parameters=model.parameters()),
                loss=paddle.nn.CrossEntropyLoss(), 
                metrics=paddle.metric.Accuracy())

model.fit(train_data=train_loader, 
            epochs=epochs,
             eval_data= val_loader,
             verbose =2,
             log_freq =100,
             callbacks=[paddle.callbacks.VisualDL('./log')]

在这里插入图片描述
在这里插入图片描述

5.预测

bingo_num=0
for i in range(test_data.shape[0]):
    x=paddle.to_tensor([test_data[i]],dtype='float32')
    out=audio_network(x)
    out=paddle.nn.functional.softmax(out,axis=-1)
    out=paddle.argmax(out)

    if i<3:
        fs, signal = wav.read(test_wavs[i])
        display.display(display.Audio(signal, rate=fs))
        print("预测值:",out.numpy()[0],"\t 真实值:",test_lable[i][0])
    if out.numpy()[0]==test_lable[i][0]:
        bingo_num+=1

print("\n测试集准确率:",bingo_num/150)

  
预测值: 5 	 真实值: 5
预测值: 2 	 真实值: 2
预测值: 9 	 真实值: 9
测试集准确率: 0.9066666666666666

6.总结

本项从0搭建一个全流程的音频分类模型,重点展示音频文件的读取与处理过程,适合想涉猎音频的领域的小白学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/9746.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浅谈企业的数据安全体系建设难点

随着云计算、大数据、物联网、移动互联网、人工智能等新技术的发展&#xff0c;网络边界被不断打破&#xff0c;数字双生、敏捷创新、安全合规驱动快速转型&#xff0c;社会和企业都在面临数字化的转型带来的数据安全风险。 近年来数据泄露的安全事件频发&#xff0c;国家和机…

基于混合整数遗传算法的最优成分选择(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

软著申请注意事项

https://register.ccopyright.com.cn/registration.html 在版权登记中心的网站声明了申请软著是免费的&#xff0c;按照版权登记中心的要求提供材料&#xff0c;按其公布的流程办理即可。 版权登记网站&#xff1a;https://register.ccopyright.com.cn/registration.html 微信…

详解:驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server 建立安全连接。

文章目录1.问题分析2.java连接MySQL数据库3.java连接SQLServer数据库3.1 创建security文件3.2 对需要运行的项目添加参数1.问题分析 SSL协议提供服务主要&#xff1a; 认证用户服务器&#xff0c;确保数据发送到正确的服务器    .加密数据&#xff0c;防止数据传输途中被窃…

EN 14963屋顶覆盖物塑料连续顶灯—CE认证

屋顶覆盖物塑料连续顶灯CE认证&#xff08;欧盟强制认证&#xff09;&#xff0d;简介 在欧盟市场“CE”标志属强制性认证标志&#xff0c;以表明产品符合欧盟《技术协调与标准化新方法》指令的基本要求。这是欧盟法律对产品提出的一种强制性要求。 在屋顶覆盖物塑料连续顶灯产…

固定资产管理软件在金融行业的应用

随着金融业务的拓展&#xff0c;金融机构对办公设备等固定资产投入逐年增加&#xff0c;加上机构的组织架构不断扩大、人员流转增大、分支机构越累越多&#xff0c;这些都给固定资产的管理带来了压力。如果采购环节把控不好&#xff0c;重复采购会给企业带来不小的损失。如果盘…

前端:时间你用对了吗?

导读&#xff1a; 前后端接口中的时间是怎么约定的&#xff1f; 项目中是否有遇到过时区问题引发的bug&#xff1f; 时间应该遵循什么样的使用规范&#xff1f; 如何理解并处理跨时区问题&#xff1f; 关键字&#xff1a;时间戳、时区、设备本地时间、北京时间 1. 支付宝中的跨…

【仁川出差】记2022.10仁川出差

10.16号深圳蛇口港出发&#xff0c;香港机场坐飞机&#xff0c;直达韩国仁川机场。 因为不熟悉&#xff0c;然后人也多&#xff0c;入境时候排队排了很久&#xff0c;出来之后&#xff0c;因为有韩国同事开车来接&#xff0c;解决了第一步怎么到酒店的交通问题。 开车差不多一个…

【快速搭建系列】idea快速搭建struts2框架和测试

idea快速搭建struts2框架和测试示例 步骤 搭建环境 新建一个maven项目 添加maven依赖 pom.xml <!-- ****************struts2框架包*************** --> <!-- struts2-core --> <dependency> <groupId>org.apache.struts</groupId> <ar…

解决 80% 的工作场景?GitHub 爆赞的 Java 高并发与集合框架,太赞了

在工作中&#xff0c;笔者经常和掌握不同技术的朋友讨论具体问题的解决方案&#xff0c;发现在 Java 体系中&#xff0c;大家使用最多的是 Java 集合框架&#xff08;JCF&#xff09;和 Java 并发工具包&#xff08;JUC&#xff09;。实际上&#xff0c;JCF 和 JUC 已经能够覆盖…

曼孚科技入选IDC中国数据智能市场代表厂商

日前&#xff0c;国际知名市场调研机构IDC发布了《Market Glance&#xff1a;中国数据智能市场概览&#xff0c;2022》报告。 报告全面展示了中国数据智能市场的构成与格局&#xff0c;同时遴选出不同细分市场领域的主要技术服务供应商&#xff0c;并依此绘制出市场地图&#…

【window 安装多环境python冲突 -已解决】

简介&#xff1a;在window上面那幢一个python原生环境时没有问题 但是在安装anaconda&#xff0c;就会出现整个环境呗anaconda所占据< 首先我的环境目前装了三个环境&#xff0c;一个是python原生3.7 和3.10的&#xff0c;然后&#xff0c;因为涉及一些操作可能会用到多个版…

MYSQL中LIKE(模糊查询)

0 写在前面 通常我们在搜索的时候总是不会特别精准&#xff0c;例如在百度上搜索&#xff0c;主要搜索关键字&#xff0c;然后加载页面之后再挑选。 所以&#xff0c;在数据库中&#xff0c;有时候会将查询条件不一定直接使用uuid这样的标准查询。实际业务中可能存在模糊查询…

linux笔记(4):东山哪吒开发板(D1-H)测试gpio点亮LED

文章目录1.控制gpio电平高低的流程1.1 选PB2控制LED&#xff0c;对应的编号是GPIO341.2 进入目录 /sys/class/gpio1.3 生成gpio34目录1.4 进入gpio34目录1.5 设置IO方向为输出1.6 控制gpio34(PB2)电平高低附录&#xff1a;linux的GPIO编号和D1-H的IO对用关系参考文档&#xff1…

【vue】Jeecg框架使用过程中的注意事项:

文章目录1.连接后台地址&#xff1a;2.获取接口数据时&#xff1a;3.模糊查询&#xff1a;4.设置默认查询参数&#xff1a;5.数据字典&#xff1a;6.j-date显示时分秒&#xff1a;7.设置添加、编辑、删除、导入等按钮的显示与隐藏&#xff08;按钮权限&#xff09;8.设置列的显…

艾美捷NCTC-135培养基改良版(粉末)相关研究和类别

细胞培养基是生物制药生产的最关键原材料之一&#xff0c;是人工模拟细胞在休内生长的营养环境&#xff0c;提供细胞营养和促进细胞生长增殖的物质基础。培养基主要也括有血清培养基、无血清细胞培养基、化学限定培养基。 无血清细胞培养基的发明是培养基发展史的一个里程碑。无…

如何一键生成活动邀请函的分享链接?

想设计一个活动邀请函但不会编程怎么办&#xff1f;想制作个能播放视频的邀请函要怎么做&#xff1f;今天小编就教你如何使用在线工具乔拓云去制作一个活动邀请函&#xff0c;不仅不用编程而且还有模板能一键套用&#xff0c;下面小编就教你如何使用这个在线工具去制作一个活动…

MongoDB学习二:基本常用命令--增删改查

基本常用命令 查看当前正在使用的数据库命令 db 另外&#xff1a; 数据库名可以是满足以下条件的任意UTF-8字符串。 不能是空字符串&#xff08;“”)。 不得含有’ &#xff08;空格)、.、$、/、\和\0 (空字符)。 应全部小写。 最多64字节。 有一些数据库名是保留的&#xff…

C语言无法实现的泛型编程,C++是如何实现的?模板

1.泛型编程 如何实现一个通用的交换函数&#xff1f; void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& left, double& right) {double temp left;left right;right temp; } void Swap(char& left, c…

rt-thread 之------fal移植

rt-thread 之 fal移植 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录rt-thread 之 fal移植前言一、fal是什么&#xff1f;二、移植1.片内flash fal移植step1&#xff1a;使能RT-Thread Components--->中的fal选…