PyTorch for Audio + Music Processing(2/3/4/5/6/7) :构建数据集和提取音频特征

news2024/11/24 6:21:52

基于Torchaudio构建数据集

文章目录

  • 基于Torchaudio构建数据集
  • 前言
    • 02 Training a feed forward network
    • 03 Making predictions
    • 04 Creating a custom dataset
    • 05 Extracting Mel spectrograms
    • 06 Padding audio files
    • 07 Preprocessing data on GPU
  • 一、下载数据集
    • 文件目录
    • 标注格式
  • 二、UrbanSoundDataset类的定义
  • 三、提取梅尔频谱特征
    • 定义梅尔转换
    • 修改UrbanSoundDataset类,初始化时传入:
    • 重采样
    • 多声道合并
    • 完善get_item
  • 五、样本padding和cut
    • cut的实现
    • pad实现,右边补0
  • 五、GPU支持
  • 六、完整代码
  • 总结


前言

本系列本来打算每一章都写笔记记录下来,不过看来几个视频之后,发现2,3其只是在普及torch以及复现基础手写字体识别的例子,与torchaudio和音频处理关系不大,就跳过,感兴趣的可以直接看代码。4,5,6,7都是在讲解如何构建数据集,所以一并记录:

02 Training a feed forward network

构建和训练mnist手写字符识别网络

03 Making predictions

推理接口的实现

04 Creating a custom dataset

创建数据集处理类

05 Extracting Mel spectrograms

基于torchaudio提取音频的梅尔频谱特征

06 Padding audio files

样本的Padding和cut

07 Preprocessing data on GPU

使用GPU训练


一、下载数据集

官方数据集要注册才能下载,直接从这里urbansound8k下载。

文件目录

在这里插入图片描述
其中audio是音频文件,大概8700多个
metadata为标注的文件夹

标注格式

metadata/UrbanSound8K.csv:
在这里插入图片描述

二、UrbanSoundDataset类的定义

class UrbanSoundDataset(Dataset):

    def __init__(self, annotations_file, audio_dir):
        self.annotations = pd.read_csv(annotations_file)
        # 使用panda加载csv
        self.audio_dir = audio_dir

    def __len__(self):
        return len(self.annotations)

    def __getitem__(self, index):
        audio_sample_path = self._get_audio_sample_path(index)
        label = self._get_audio_sample_label(index)
        signal, sr = torchaudio.load(audio_sample_path)
        # 返回tensor类型的音频序列和采样率,与librosa.load的区别是,librosa返回的音频序列是numpy格式
        return signal, label

    def _get_audio_sample_path(self, index):
        fold = f"fold{self.annotations.iloc[index, 5]}"
        path = os.path.join(self.audio_dir, fold, self.annotations.iloc[
            index, 0])
        return path

    def _get_audio_sample_label(self, index):
        return self.annotations.iloc[index, 6]

三、提取梅尔频谱特征

梅尔频谱为音频信号处理中常见的特征表示,torchaudio中使用torchaudio.transforms模块来实现

定义梅尔转换

mel_spectrogram = torchaudio.transforms.MelSpectrogram(
        sample_rate=SAMPLE_RATE,
        n_fft=1024,
        hop_length=512,
        n_mels=64
    )

修改UrbanSoundDataset类,初始化时传入:

class UrbanSoundDataset(Dataset):
    def __init__(self, annotations_file, audio_dir, transformation,
                 target_sample_rate):
        self.annotations = pd.read_csv(annotations_file)
        self.audio_dir = audio_dir
        self.transformation = transformation
        self.target_sample_rate = target_sample_rate

重采样

在梅尔转换之前,需要对音频信号进行重采样和多声道合并,所以定义这两个函数:

    def _resample_if_necessary(self, signal, sr):
        # 每个信号的采样率不一致,如果跟共有变量的采样率不一致的话,需要重采样
        if sr != self.target_sample_rate:
            resampler = torchaudio.transforms.Resample(sr, self.target_sample_rate)
            signal = resampler(signal)
        return signal

多声道合并

    def _mix_down_if_necessary(self, signal):
        # 每个signal -> (channel,samples) -> (2,16000) -> (1,16000)
        # 需要把所有的通道混合起来,保持维度不变
        if signal.shape[0] > 1:
            signal = torch.mean(signal, dim=0, keepdim=True)
        return signal

完善get_item

然后在get_item的函数里把几个函数串起来,则完成了梅尔频谱特征提取的过程:

    def __getitem__(self, index):
        audio_sample_path = self._get_audio_sample_path(index)
        label = self._get_audio_sample_label(index)
        signal, sr = torchaudio.load(audio_sample_path)
        signal = self._resample_if_necessary(signal, sr) # 重采样
        signal = self._mix_down_if_necessary(signal) # 多声道合并
        signal = self.transformation(signal) # 梅尔频谱提取
        return signal, label

五、样本padding和cut

由于训练的要求,需要把每个信号样本都缩放到同一尺度,所以使用了padding(尺度小于阈值),cut(尺度大于阈值)的处理,添加两个函数:

cut的实现

直接取前面到阈值的部分(似乎有点简单粗暴?)

    def _cut_if_necessary(self, signal):
        # 举例 signal -> Tensor -> (1,num_samples) -> (1,50000) -> 切片后变成 (1,22500)
        if signal.shape[1] > self.num_samples:
            signal = signal[:, :self.num_samples]
        return signal

pad实现,右边补0

    def _right_pad_if_necessary(self, signal):
        length_signal = signal.shape[1]
        if length_signal < self.num_samples:
            num_missing_samples = self.num_samples - length_signal
            last_dim_padding = (0, num_missing_samples)
            # 每个signal都是二维的,所以以上式子,第一个0是不pad的,只pad第二维
            signal = torch.nn.functional.pad(signal, last_dim_padding)
        return signal

五、GPU支持

就是加了一个判断,这也单独列了一章……

    if torch.cuda.is_available():
        device = "cuda"
    else:
        device = "cpu"
    print(f"Using device {device}")

六、完整代码

import os

import torch
from torch.utils.data import Dataset
import pandas as pd
import torchaudio


class UrbanSoundDataset(Dataset):

    def __init__(self,
                 annotations_file,
                 audio_dir,
                 transformation,
                 target_sample_rate,
                 num_samples,
                 device):
        self.annotations = pd.read_csv(annotations_file)
        self.audio_dir = audio_dir
        self.device = device
        self.transformation = transformation.to(self.device)
        self.target_sample_rate = target_sample_rate
        self.num_samples = num_samples

    def __len__(self):
        return len(self.annotations)

    def __getitem__(self, index):
        audio_sample_path = self._get_audio_sample_path(index)
        label = self._get_audio_sample_label(index)
        signal, sr = torchaudio.load(audio_sample_path)
        signal = signal.to(self.device)
        signal = self._resample_if_necessary(signal, sr)
        signal = self._mix_down_if_necessary(signal)
        signal = self._cut_if_necessary(signal)
        signal = self._right_pad_if_necessary(signal)
        signal = self.transformation(signal)
        return signal, label

    def _cut_if_necessary(self, signal):
        if signal.shape[1] > self.num_samples:
            signal = signal[:, :self.num_samples]
        return signal

    def _right_pad_if_necessary(self, signal):
        length_signal = signal.shape[1]
        if length_signal < self.num_samples:
            num_missing_samples = self.num_samples - length_signal
            last_dim_padding = (0, num_missing_samples)
            signal = torch.nn.functional.pad(signal, last_dim_padding)
        return signal

    def _resample_if_necessary(self, signal, sr):
        if sr != self.target_sample_rate:
            resampler = torchaudio.transforms.Resample(sr, self.target_sample_rate)
            signal = resampler(signal)
        return signal

    def _mix_down_if_necessary(self, signal):
        if signal.shape[0] > 1:
            signal = torch.mean(signal, dim=0, keepdim=True)
        return signal

    def _get_audio_sample_path(self, index):
        fold = f"fold{self.annotations.iloc[index, 5]}"
        path = os.path.join(self.audio_dir, fold, self.annotations.iloc[
            index, 0])
        return path

    def _get_audio_sample_label(self, index):
        return self.annotations.iloc[index, 6]


if __name__ == "__main__":
    ANNOTATIONS_FILE = "/home/valerio/datasets/UrbanSound8K/metadata/UrbanSound8K.csv"
    AUDIO_DIR = "/home/valerio/datasets/UrbanSound8K/audio"
    SAMPLE_RATE = 22050
    NUM_SAMPLES = 22050

    if torch.cuda.is_available():
        device = "cuda"
    else:
        device = "cpu"
    print(f"Using device {device}")

    mel_spectrogram = torchaudio.transforms.MelSpectrogram(
        sample_rate=SAMPLE_RATE,
        n_fft=1024,
        hop_length=512,
        n_mels=64
    )

    usd = UrbanSoundDataset(ANNOTATIONS_FILE,
                            AUDIO_DIR,
                            mel_spectrogram,
                            SAMPLE_RATE,
                            NUM_SAMPLES,
                            device)
    print(f"There are {len(usd)} samples in the dataset.")
    signal, label = usd[0]



总结

以上就是整个数据集的定义、加载、预处理及梅尔频谱特征提取过程,为后续的训练做好数据的准备。

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

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

相关文章

19 【RTK Query】

19 【RTK Query】 1.目前前端常见的发起 ajax 请求的方式 1、使用原生的ajax请求2、使用jquery封装好的ajax请求3、使用fetch发起请求4、第三方的比如axios请求5、angular中自带的HttpClient 就目前前端框架开发中来说我们在开发vue、react的时候一般都是使用fetch或axios自…

web前端期末大作业【 大学生抗疫感动专题网页设计】HTML+CSS

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Prometheus 使用cadvisor采集docker容器监控数据

Prometheus采集主机监控参考部署下载&#xff0c;图形生成 系统安装Grafana downloadWindows参考图形生成参考win_exporterLinux参考node_exporterMysql参考Mysql_exporterSQL Server参考SQL exporterRedis 参考Redis_exportercadvisor参考cadvisor snmp_exporter 参考图形展示…

Redis详细教程

【尚硅谷】2021最新版Redis详细教程&#xff08;基于Redis 6.2.x版本&#xff09; 文章目录 一、前言二、NoSQL数据库简介 1.技术发展 1.1 Web1.0时代1.2 Web2.0时代1.3 解决CPU及内存压力1.4 解决IO压力 2.NoSQL数据库 2.1 NoSQL数据库概述2.2 NoSQL适用场景2.3 NoSQL不适用…

小啊呜产品读书笔记001:《邱岳的产品手记-09》第17讲 产品经理如何获得非权力性的影响力 第18讲 产品案例分析:WWFTogether的情怀设计

小啊呜产品读书笔记001&#xff1a;《邱岳的产品手记-09》第17讲 产品经理如何获得非权力性的影响力 & 第18讲 产品案例分析&#xff1a;WWFTogether的情怀设计一、今日阅读计划二、泛读&知识摘录1、第17讲 产品经理如何获得非权力性的影响力&#xff1f;2、第18讲 产品…

Unity 打印安卓apk报错的日志

文章目录环境连接安卓手机附录环境 1.华为手机打开调试模式&#xff1a; 【设置】|【关于手机】|【版本号】点三次。 2.unity3d 环境设置&#xff1a; 【File】|【Building Settings】开启必备选项 &#xff08;其他非必选&#xff0c;最好勾上&#xff09;&#xff1a; D…

Sparse Merkle Tree

1. 引言 前序博客有&#xff1a; Merkle tree及其在区块链等领域的应用Merkle tree proof 2. Merkle tree Merkle tree可看成是对一组数据的密码学承诺&#xff0c;类似&#xff1a; 2.1 Merkle tree包含证明 如需证明A包含在上述树中&#xff0c;仅需要发送A, H(B), H(…

编译原理实验--实验一 词法分析--Python实现

目录 一、实验目的 二、实验内容 三、实验环境 四、实验步骤 五、测试要求 六、实验步骤 1、单词表<列出所识别语言的所有单词及其种别编码>&#xff1b; 2、识别单词的DFA图<可选择1-2类单词&#xff0c;给出识别该单词的DFA图> 3、关键代码 七、实验结果…

【C++实现】线程池的设计与实现

文章目录前言正文线程池提供的两个重要方法Any类的设计SemaphoreResult的实现Cache模式解释会遇到死锁问题第二个死锁问题&#xff0c;移植到Linux发生项目重构大致流程总结前言 开发环境&#xff1a; Linux&#xff0c;要求g版本能够支持C17以上&#xff1b;vs2019下开发&…

实验四 数码管实验【Verilog】

实验四 数码管实验【Verilog】前言推荐实验四 数码管实验【Verilog】一、实验目的&#xff1a;二、实验设备&#xff1a;三、实验任务:四、实验原理:五、实验步骤&#xff1a;六、实验结果&#xff1a;七、心得体会&#xff1a;最后前言 以下内容源自Verilog实验 仅供学习交流…

[附源码]java毕业设计校园期刊网络投稿系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Git的基础操作及使用

目录 1.git工作原理示意 2.git拉取服务器上的代码 3.git往服务器上提交新code 4.git 查看提交记录&#xff0c; 5.git删除旧代码仓库&#xff0c;提交新的代码仓库 6.如何修改自己提交代码的用户名和邮箱 6.1.查看现用邮箱和用户名 6.2.使用命令修改git的用户名和提交的…

将一段文本映射到低纬向量空间

文本表示学习就是将一段文本映射到低纬向量空间&#xff0c;获取句子的语义表示&#xff0c;大致经历过四个阶段&#xff1a; 阶段 1&#xff1a;统计类型&#xff0c;此阶段比较典型的是利用 TD-IDF 抽取关键词&#xff0c;用关键词表示表征整个句子。 阶段 2&#xff1a;深度…

MySQL数据库增删改查进阶 — 聚合查询、分组查询、联合查询

文章目录1.聚合查询1.1 count 函数1.2 sum 函数1.3 avg 函数1.4 max 和 min 函数2.分组查询2.1 group by 子句2.2 分组查询可以指定条件2.2.1 分组之前&#xff0c;指定条件2.2.2 分组之后&#xff0c;指定条件2.2.3 分组前后都指定条件3.联合查询3.1 笛卡尔积3.1.1 笛卡尔积中…

YourKit Java Profiler 2022.9.X Crack

YourKit Java Profiler 2022.9.X Crack 从 CPU 和内存利用率的角度分析您的程序非常重要。它允许您最大限度地提高自身性能并限制其对服务器系统工具的影响&#xff0c;这将始终受到最终用户的重视。 在 YourKit Java Profiler 的支持下&#xff0c;可以很容易地运行基于 Java…

传奇单机架设教程及游戏GM设置方法

传奇技术教学 第二课:传奇单机架设教程及游戏GM设置方法 架设前关杀毒 确保自己的热血传奇客户端是13周年以后的 最好用最新的. 不要使用已经淘汰的10周年客户端和微端客户端 否则会出现显示不全情况. 注意HERO引擎版本在登录器方面不支持WIN8及WIN10系统的. 若你是以上系统…

Linux资源限制命令—ulimit

ulimit功能简述 假设有这样一种情况&#xff0c;当一台 Linux 主机上同时登陆了 10 个人&#xff0c;在系统资源无限制的情况下&#xff0c;这 10 个用户同时打开了 500 个文档&#xff0c;而假设每个文档的大小有 10M&#xff0c;这时系统的内存资源就会受到巨大的挑战。而实…

市面上主流源表软件全面对比,总有一款适合你!

在电测行业中&#xff0c;在对高精度的电压、电流或电流电压源进行测量扫描时就要请出我们的小伙伴“源表“。 它精确的采集能力以及为各种低电平测量应用提供额外的灵活性让它成为了电测行业中不和或缺的一员。而作为和它配合的搭档源表软件也在电测行业中有着重要的作用。 …

【排序专题】不会吧,不会吧居然还有人不懂排序算法?有彩蛋哦

文章目录1. 冒泡排序2. 选择排序3. 简单插入排序4. 希尔排序-->简单插入排序演变5. 归并排序(递归版本)6. 归并排序(非递归版本)7. 荷兰国旗问题8.由荷兰国旗问题进而引出快速排序 and 快速排序1.0版本9.快速排序2.0版本(挖坑法)10.快速排序 3.0版本(随机取数法)11.堆排序12…

AOP结合注解实现项目中接口调用情况监控

一、概述 项目中经常会遇到这样一个需求&#xff0c;需要监控每个controller中接口被调用的情况。 比如某个接口被调用的时间&#xff0c;哪个用户调用的&#xff0c;请求参数是什么&#xff0c;返回值是什么等等。 并且调用情况需要存储到数据库中&#xff0c;此时就可以AO…