使用Hugging face Datasets库
使用hugging face datasets库可以很简单的加载数据集
from datasets import load_dataset
minds = load_dataset("PolyAI/minds14", name="en-AU", split="train")#返回的minds是一个Dataset类,load_dataset()的第一个参数表示huggingface的数据集标识符#name参数表示数据集子集的名称,split参数可以限制数据集,这里限制为训练集使用print可以看到minds的各种属性
print(minds)输出如下
Dataset({ features: ['path', 'audio', 'transcription', 'english_transcription', 'intent_class', 'lang_id'], //数据集中每个数据所带的特征 num_rows: 654 //数据集的数据总数})datasets也提供了方法来移除某些特征
columns_to_remove = ["english_transcription", "lang_id"]minds = minds.remove_columns(columns_to_remove)#传入一个含有要移除参数的列表,这个函数不会修改原来的数据集,但是会返回一个新的数据集#所以在这样操作的同时也把返回值赋给原来的数据集print(minds)输出如下
Dataset({ features: ['path', 'audio', 'transcription', 'intent_class'], //可以看到,我们指定的特征被删去了 num_rows: 654})通过Gradio,可以简单地创建一个demo来看看我们的音频,运行以下的代码还需要当前的环境中有安装ffmpeg
也许你可以在anaconda prompt里输入’ffmpeg’并看到有效的输出,但是这并不能说明当前的环境里有ffmpeg,你看到的输出可能来自系统path变量所指向的ffmpeg,为了查看虚拟环境中是否装有ffmpeg,需要用命令 ’conda list‘ 来查看。这一串文字存在的原因当然是作者刚刚没有发现这个问题而停滞了一会
from datasets import load_datasetimport gradio as grimport torchcodec
minds = load_dataset("PolyAI/minds14", name="en-AU", split="train")
def generate_audio(): example = minds.shuffle()[0] audio = example["audio"] return (audio["sampling_rate"], audio["array"]), example["intent_class"] #audio本身是含有音频信息的字典,audio["array"]则是numpy数组表示的频谱信息
with gr.Blocks() as demo: with gr.Column(): for _ in range(4): audio, label = generate_audio() output = gr.Audio(audio, label=label)
demo.launch(debug=True)实际上,我们也可以使用Hugging face datasets来加载本地数据集,这要求数据集的文件夹有如下的格式
my_dataset/├── train/│ ├── label1/│ │ ├── audio1.wav│ │ └── audio2.wav│ └── label2/│ ├── audio3.wav│ └── audio4.wav└── test/ ...只需指定load_dataset()的第一个参数为”audiofolder”,并传入参数data_dir即可,同时也可以指定split,来控制我们获得的是训练集还是别的什么
from datasets import load_datasetimport gradio as gr
minds = load_dataset("audiofolder", data_dir=".\my_dataset", split="train")#如果要运行这段代码,还需要填上完整的路径
with gr.Blocks() as demo: with gr.Column(): for i in range(4): example = minds[i] audio = example["audio"] sr = audio["sampling_rate"] array = audio["array"] output = gr.Audio((sr, array), label=f"Audio {i}") #gradio.Audio的第一个参数是包含采样率和频谱的元组
demo.launch(debug=True)自行倾听是一个检查数据集的不赖选择,但我们同样可以选择画图
import librosaimport librosa.displayimport matplotlib.pyplot as pltimport numpy as npfrom datasets import load_dataset
minds = load_dataset("audiofolder", data_dir=".\my_dataset", split="train")#路径同上testArray, testSR = minds[0]["audio"]["array"], minds[0]["audio"]["sampling_rate"]#有了采样率和振幅信息,我们就可以画出图像
plt.figure().set_figwidth(12)librosa.display.waveshow(y= testArray, sr= testSR)plt.show()使用PyTorch加载数据
Torch库中含有用于加载数据库的Dataset和Dataloader,由于显然不同的模型训练所用的数据不一定相同,我们需要实现自己的Dataset类,包括init, len, getitem方法
import numpy as npfrom datasets import load_datasetimport gradio as grimport torchfrom torch.utils.data import DataLoader, Datasetimport torchaudioimport os
class AudioDataset(Dataset):#要实现Dataset类,只需以torch中的Dataset类为父类来实现子类即可 def __init__(self, data_dir:str, target_sample_rate=16000): #由于是音频数据集,除了文件路径之外 supported_files = (".ogg", ".wav", ".mp3", ".flac") self.files = [] files_in_dir = os.listdir(data_dir) for file in files_in_dir: if file.endswith(supported_files): self.files.append(os.path.join(data_dir, file)) self.target_sr = target_sample_rate
def __len__(self): return len(self.files)
def __getitem__(self, index): filepath = self.files[index] waveform, sr = torchaudio.load(filepath) #torchaudio.load()接受一个音频的路径作为参数,返回一个音频序列和采样率
if sr != self.target_sr: #由于数据集的采样率需要统一,所以需要对不同采样率的音频重采样 resampler = torchaudio.transforms.Resample(sr, self.target_sr) waveform = resampler(waveform)
return waveform, self.target_sr, #label #label在这里并没有实现
path = ".\\models\\Aru\\wav"#同上,运行需要替换路径My_audioDataset = AudioDataset(path)
with gr.Blocks() as demo: with gr.Column(): for i in range(4): audio, sr, _ = My_audioDataset[i] output = gr.Audio((sr, audio.numpy().transpose()), label=f"Audio {i}") #可以注意到,这里进行了转置,理由的阐释放在下文里
demo.launch(debug=True)可以发现在给gradio.Audio()传递参数的时候我们进行了一系列操作。由于由torchaudio.load()得到的返回值是一个张量,但是gradio.Audio()要求numpy数组,这两者在本质上几乎没有差别,所以可以对其使用.numpy()来转换为numpy数组 同时,由torchaudio.load()得到的数组形式为(channels, time),而gradio.Audio()要求的数组形式为(time, channels),显然直接传入原来的数组是不行的,我们需要对其进行转置,由于这是二维数组,其转置与线性代数上的转置一致
线性代数上的转置即,将每个A_ij都与A_ji对调,将旧矩阵的行做为新矩阵的列,例如: 1 2 3 1 4 7 4 5 6 -> 2 5 8 7 8 9 3 6 9
实际上也有其他加载数据集的方法,但是在这里介绍的两种足够多数时候使用了
部分信息可能已经过时



