使用深度学习进行音频分类的端到端示例和解释(三)

简介: 使用深度学习进行音频分类的端到端示例和解释

使用数据加载器准备一批数据

现在已经定义了我们需要将数据输入到模型中的所有函数。

我们使用自定义数据集从Pandas中加载特征和标签,然后以80:20的比例将数据随机分为训练和验证集。然后,我们使用它们来创建我们的训练和验证数据加载器。

640.png

fromtorch.utils.dataimportrandom_splitmyds=SoundDS(df, data_path)
#Randomsplitof80:20betweentrainingandvalidationnum_items=len(myds)
num_train=round(num_items*0.8)
num_val=num_items-num_traintrain_ds, val_ds=random_split(myds, [num_train, num_val])
#Createtrainingandvalidationdataloaderstrain_dl=torch.utils.data.DataLoader(train_ds, batch_size=16, shuffle=True)
val_dl=torch.utils.data.DataLoader(val_ds, batch_size=16, shuffle=False)

当我们开始训练时,将随机获取一批包含音频文件名列表的输入,并在每个音频文件上运行预处理音频转换。它还将获取一批包含类ID的相应目标Label。因此,它将一次输出一批训练数据,这些数据可以直接作为输入提供给我们的深度学习模型。

640.png

让我们从音频文件开始,逐步完成数据转换的各个步骤:

文件中的音频被加载到Numpy的数组中(num_channels,num_samples)。大部分音频以44.1kHz采样,持续时间约为4秒,从而产生44,100 * 4 = 176,400个采样。如果音频具有1个通道,则阵列的形状将为(1、176,400)。同样,具有2个通道的4秒钟持续时间且以48kHz采样的音频将具有192,000个采样,形状为(2,192,000)。

每种音频的通道和采样率不同,因此接下来的两次转换会将音频重新采样为标准的44.1kHz和标准的2个通道。

某些音频片段可能大于或小于4秒,因此我们还将音频持续时间标准化为固定的4秒长度。现在,所有项目的数组都具有相同的形状(2,176,400)

时移数据扩充功能会随机将每个音频样本向前或向后移动。形状不变。

扩充后的音频将转换为梅尔频谱图,其形状为(num_channels,Mel freq_bands,time_steps)=(2,64,344)

SpecAugment数据扩充功能将时间和频率掩码随机应用于梅尔频谱图。形状不变。

最后我们每批得到了两个张量,一个用于包含梅尔频谱图的X特征数据,另一个用于包含数字类ID的y目标标签。从每个训练轮次的训练数据中随机选择批次。

每个批次的形状为(batch_sz,num_channels,Mel freq_bands,time_steps)

我们可以将批次中的一项可视化。我们看到带有垂直和水平条纹的梅尔频谱图显示了频率和时间屏蔽数据的扩充。

640.png

建立模型

我们刚刚执行的数据处理步骤是我们音频分类问题中最独特的方面。从这里开始,模型和训练过程与标准图像分类问题中常用的模型和训练过程非常相似,并且不特定于音频深度学习。

由于我们的数据现在由光谱图图像组成,因此我们建立了CNN分类架构来对其进行处理。它具有生成特征图的四个卷积块。然后将数据重新整形为我们需要的格式,以便可以将其输入到线性分类器层,该层最终输出针对10个分类的预测。

640.png

模型信息:

色彩图像以形状(batch_sz,num_channels,Mel freq_bands,time_steps)输入模型。(16,2,64,344)。

每个CNN层都应用其滤镜以提高图像深度,即通道数。(16、64、4、22)。

将其合并并展平为(16,64)的形状,然后输入到“线性”层。

线性层为每个类别输出一个预测分数,即(16、10)

importtorch.nn.functionalasFfromtorch.nnimportinit#----------------------------#AudioClassificationModel#----------------------------classAudioClassifier (nn.Module):
#----------------------------#Buildthemodelarchitecture#----------------------------def__init__(self):
super().__init__()
conv_layers= []
#FirstConvolutionBlockwithReluandBatchNorm. UseKaimingInitializationself.conv1=nn.Conv2d(2, 8, kernel_size=(5, 5), stride=(2, 2), padding=(2, 2))
self.relu1=nn.ReLU()
self.bn1=nn.BatchNorm2d(8)
init.kaiming_normal_(self.conv1.weight, a=0.1)
self.conv1.bias.data.zero_()
conv_layers+= [self.conv1, self.relu1, self.bn1]
#SecondConvolutionBlockself.conv2=nn.Conv2d(8, 16, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
self.relu2=nn.ReLU()
self.bn2=nn.BatchNorm2d(16)
init.kaiming_normal_(self.conv2.weight, a=0.1)
self.conv2.bias.data.zero_()
conv_layers+= [self.conv2, self.relu2, self.bn2]
#SecondConvolutionBlockself.conv3=nn.Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
self.relu3=nn.ReLU()
self.bn3=nn.BatchNorm2d(32)
init.kaiming_normal_(self.conv3.weight, a=0.1)
self.conv3.bias.data.zero_()
conv_layers+= [self.conv3, self.relu3, self.bn3]
#SecondConvolutionBlockself.conv4=nn.Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
self.relu4=nn.ReLU()
self.bn4=nn.BatchNorm2d(64)
init.kaiming_normal_(self.conv4.weight, a=0.1)
self.conv4.bias.data.zero_()
conv_layers+= [self.conv4, self.relu4, self.bn4]
#LinearClassifierself.ap=nn.AdaptiveAvgPool2d(output_size=1)
self.lin=nn.Linear(in_features=64, out_features=10)
#WraptheConvolutionalBlocksself.conv=nn.Sequential(*conv_layers)
#----------------------------#Forwardpasscomputations#----------------------------defforward(self, x):
#Runtheconvolutionalblocksx=self.conv(x)
#Adaptivepoolandflattenforinputtolinearlayerx=self.ap(x)
x=x.view(x.shape[0], -1)
#Linearlayerx=self.lin(x)
#Finaloutputreturnx#CreatethemodelandputitontheGPUifavailablemyModel=AudioClassifier()
device=torch.device("cuda:0"iftorch.cuda.is_available() else"cpu")
myModel=myModel.to(device)
#CheckthatitisonCudanext(myModel.parameters()).device

训练

现在,我们准备创建训练循环来训练模型。

我们定义了优化器,损失函数和学习率的调度计划的函数,以便随着训练的进行而动态地改变我们的学习率,这样可以使模型收敛的更快。

在每轮训练完成后。我们跟踪一个简单的准确性指标,该指标衡量正确预测的百分比。

#----------------------------#TrainingLoop#----------------------------deftraining(model, train_dl, num_epochs):
#LossFunction, OptimizerandSchedulercriterion=nn.CrossEntropyLoss()
optimizer=torch.optim.Adam(model.parameters(),lr=0.001)
scheduler=torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.001,
steps_per_epoch=int(len(train_dl)),
epochs=num_epochs,
anneal_strategy='linear')
#Repeatforeachepochforepochinrange(num_epochs):
running_loss=0.0correct_prediction=0total_prediction=0#Repeatforeachbatchinthetrainingsetfori, datainenumerate(train_dl):
#Gettheinputfeaturesandtargetlabels, andputthemontheGPUinputs, labels=data[0].to(device), data[1].to(device)
#Normalizetheinputsinputs_m, inputs_s=inputs.mean(), inputs.std()
inputs= (inputs-inputs_m) /inputs_s#Zerotheparametergradientsoptimizer.zero_grad()
#forward+backward+optimizeoutputs=model(inputs)
loss=criterion(outputs, labels)
loss.backward()
optimizer.step()
scheduler.step()
#KeepstatsforLossandAccuracyrunning_loss+=loss.item()
#Getthepredictedclasswiththehighestscore_, prediction=torch.max(outputs,1)
#Countofpredictionsthatmatchedthetargetlabelcorrect_prediction+= (prediction==labels).sum().item()
total_prediction+=prediction.shape[0]
#ifi%10==0:   #printevery10mini-batches#print('[%d, %5d] loss: %.3f'% (epoch+1, i+1, running_loss/10))
#Printstatsattheendoftheepochnum_batches=len(train_dl)
avg_loss=running_loss/num_batchesacc=correct_prediction/total_predictionprint(f'Epoch: {epoch}, Loss: {avg_loss:.2f}, Accuracy: {acc:.2f}')
print('Finished Training')
num_epochs=2#Justfordemo, adjustthishigher.
training(myModel, train_dl, num_epochs)

推理

作为训练循环的一部分,我们还将根据验证数据评估指标。所以我们会对原始数据中保留测试数据集(被当作是训练时看不见的数据)进行推理。出于本演示的目的,我们将为此目的使用验证数据。

我们禁用梯度更新并运行一个推理循环。与模型一起执行前向传播以获取预测,但是我们不需要反向传播和优化。

#----------------------------#Inference#----------------------------definference (model, val_dl):
correct_prediction=0total_prediction=0#Disablegradientupdateswithtorch.no_grad():
fordatainval_dl:
#Gettheinputfeaturesandtargetlabels, andputthemontheGPUinputs, labels=data[0].to(device), data[1].to(device)
#Normalizetheinputsinputs_m, inputs_s=inputs.mean(), inputs.std()
inputs= (inputs-inputs_m) /inputs_s#Getpredictionsoutputs=model(inputs)
#Getthepredictedclasswiththehighestscore_, prediction=torch.max(outputs,1)
#Countofpredictionsthatmatchedthetargetlabelcorrect_prediction+= (prediction==labels).sum().item()
total_prediction+=prediction.shape[0]
acc=correct_prediction/total_predictionprint(f'Accuracy: {acc:.2f}, Total items: {total_prediction}')
#Runinferenceontrainedmodelwiththevalidationsetinference(myModel, val_dl)

结论

现在我们已经看到了声音分类的端到端示例,它是音频深度学习中最基础的问题之一。这不仅可以用于广泛的应用中,而且我们在此介绍的许多概念和技术都将与更复杂的音频问题相关,例如自动语音识别,其中我们从人类语音入手,了解人们在说什么,以及将其转换为文本。

最后,如果您喜欢这篇文章,给个赞吧。

目录
相关文章
|
机器学习/深度学习 编解码 人工智能
人脸表情[七种表情]数据集(15500张图片已划分、已标注)|适用于YOLO系列深度学习分类检测任务【数据集分享】
本数据集包含15,500张已划分、已标注的人脸表情图像,覆盖惊讶、恐惧、厌恶、高兴、悲伤、愤怒和中性七类表情,适用于YOLO系列等深度学习模型的分类与检测任务。数据集结构清晰,分为训练集与测试集,支持多种标注格式转换,适用于人机交互、心理健康、驾驶监测等多个领域。
|
2月前
|
机器学习/深度学习 人工智能 监控
河道塑料瓶识别标准数据集 | 科研与项目必备(图片已划分、已标注)| 适用于YOLO系列深度学习分类检测任务【数据集分享】
随着城市化进程加快和塑料制品使用量增加,河道中的塑料垃圾问题日益严重。塑料瓶作为河道漂浮垃圾的主要类型,不仅破坏水体景观,还威胁水生生态系统的健康。传统的人工巡查方式效率低、成本高,难以满足实时监控与治理的需求。
|
2月前
|
机器学习/深度学习 传感器 人工智能
火灾火焰识别数据集(2200张图片已划分、已标注)|适用于YOLO系列深度学习分类检测任务【数据集分享】
在人工智能和计算机视觉的快速发展中,火灾检测与火焰识别逐渐成为智慧城市、公共安全和智能监控的重要研究方向。一个高质量的数据集往往是推动相关研究的核心基础。本文将详细介绍一个火灾火焰识别数据集,该数据集共包含 2200 张图片,并已按照 训练集(train)、验证集(val)、测试集(test) 划分,同时配有对应的标注文件,方便研究者快速上手模型训练与评估。
火灾火焰识别数据集(2200张图片已划分、已标注)|适用于YOLO系列深度学习分类检测任务【数据集分享】
|
2月前
|
机器学习/深度学习 人工智能 自动驾驶
7种交通场景数据集(千张图片已划分、已标注)|适用于YOLO系列深度学习分类检测任务【数据集分享】
在智能交通与自动驾驶技术快速发展的今天,如何高效、准确地感知道路环境已经成为研究与应用的核心问题。车辆、行人和交通信号灯作为城市交通系统的关键元素,对道路安全与交通效率具有直接影响。然而,真实道路场景往往伴随 复杂光照、遮挡、多目标混杂以及交通信号状态多样化 等挑战,使得视觉识别与检测任务难度显著增加。
|
2月前
|
机器学习/深度学习 人工智能 监控
坐姿标准好坏姿态数据集(图片已划分、已标注)|适用于YOLO系列深度学习分类检测任务【数据集分享】
坐姿标准好坏姿态数据集的发布,填补了计算机视觉领域在“细分健康行为识别”上的空白。它不仅具有研究价值,更在实际应用层面具备广阔前景。从青少年的健康教育,到办公室的智能提醒,再到驾驶员的安全监控和康复训练,本数据集都能发挥巨大的作用。
坐姿标准好坏姿态数据集(图片已划分、已标注)|适用于YOLO系列深度学习分类检测任务【数据集分享】
|
2月前
|
机器学习/深度学习 编解码 人工智能
102类农业害虫数据集(20000张图片已划分、已标注)|适用于YOLO系列深度学习分类检测任务【数据集分享】
在现代农业发展中,病虫害监测与防治 始终是保障粮食安全和提高农作物产量的关键环节。传统的害虫识别主要依赖人工观察与统计,不仅效率低下,而且容易受到主观经验、环境条件等因素的影响,导致识别准确率不足。
|
1月前
|
机器学习/深度学习 数据采集 编解码
基于深度学习分类的时相关MIMO信道的递归CSI量化(Matlab代码实现)
基于深度学习分类的时相关MIMO信道的递归CSI量化(Matlab代码实现)
|
机器学习/深度学习 人工智能 文字识别
中药材图像识别数据集(100类,9200张)|适用于YOLO系列深度学习分类检测任务
本数据集包含9200张中药材图像,覆盖100类常见中药材,适用于YOLO系列及主流深度学习模型的图像分类与目标检测任务。数据已划分为训练集(8000张)与验证集(1200张),采用标准文件夹结构和简体中文命名,适配PyTorch、TensorFlow等框架,可用于中药识别系统开发、医学辅助诊断、移动端图像识别App研发及AI科研训练,具备较强的实用性与拓展性。
679 46
|
2月前
|
机器学习/深度学习 自动驾驶 算法
道路表面缺陷数据集(裂缝/井盖/坑洼)(6000张图片已划分、已标注)|适用于YOLO系列深度学习分类检测任务【数据集分享】
随着城市化与交通运输业的快速发展,道路基础设施的健康状况直接关系到出行安全与城市运行效率。长期高强度的使用、气候变化以及施工质量差异,都会导致道路表面出现裂缝、坑洼、井盖下沉及修补不良等缺陷。这些问题不仅影响驾驶舒适度,还可能引发交通事故,增加道路养护成本。
道路表面缺陷数据集(裂缝/井盖/坑洼)(6000张图片已划分、已标注)|适用于YOLO系列深度学习分类检测任务【数据集分享】
|
机器学习/深度学习 人工智能 编解码
AI虫子种类识别数据集(近3000张图片已划分、已标注)|适用于YOLO系列深度学习分类检测任务【数据集分享】
本数据集包含近3000张已划分、标注的虫子图像,适用于YOLO系列模型的目标检测与分类任务。涵盖7类常见虫子,标注采用YOLO格式,结构清晰,适合农业智能化、小样本学习及边缘部署研究。数据来源多样,标注精准,助力AI虫害识别落地应用。

热门文章

最新文章