Path: blob/master/site/zh-cn/tutorials/audio/transfer_learning_audio.ipynb
25118 views
Copyright 2021 The TensorFlow Authors.
导入 TensorFlow 和其他库
首先安装 TensorFlow I/O,这将使您更轻松地从磁盘上加载音频文件。
关于 YAMNet
YAMNet 是一种采用 MobileNetV1 深度可分离卷积架构的预训练神经网络。它可以使用音频波形作为输入,并对 AudioSet 语料库中的 521 个音频事件分别进行独立预测。
在内部,模型会从音频信号中提取“帧”并批量处理这些帧。此版本的模型使用时长为 0.96 秒的帧,每 0.48 秒提取一帧。
模型会接受包含任意长度波形的一维 float32 张量或 NumPy 数组,表示为 [-1.0, +1.0]
区间内的单通道(单声道)16 kHz 样本。本教程包含帮助您将 WAV 文件转换为受支持格式的代码。
模型会返回 3 个输出,包括类分数、嵌入向量(将用于迁移学习)和对数梅尔语谱图。您可以在此处找到更多详细信息。
YAMNet 的一种特定用途是作为高级特征提取器 - 1,024 维嵌入向量输出。您将使用基础 (YAMNet) 模型的输入特征并将它们馈送到由一个隐藏的 tf.keras.layers.Dense
层组成的浅层模型中。然后,您将在少量数据上训练网络进行音频分类,而不需要大量带标签的数据和端到端训练。(这类似于使用 TensorFlow Hub 进行图像分类迁移学习,请参阅以了解更多信息。)
首先,您将测试模型并查看音频分类结果。然后,您将构建数据预处理流水线。
从 TensorFlow Hub 加载 YAMNet
您将使用来自 TensorFlow Hub 的预训练 YAMNet 从声音文件中提取嵌入向量。
从 TensorFlow Hub 中加载模型非常简单:选择模型,复制其网址,然后使用 load
函数。
注:要阅读模型的文档,请在浏览器中使用模型网址。
加载模型后,您可以遵循 YAMNet 基本使用教程并下载 WAV 样本文件以运行推断。
您将需要用于加载音频文件的函数,稍后在处理训练数据时也将使用该函数。(请参阅简单音频识别以详细了解如何读取音频文件及其标签。)
注:从 load_wav_16k_mono
返回的 wav_data
已经归一化为 [-1.0, 1.0]
区间内的值(有关更多信息,请参阅 TF Hub 上的 YAMNet 文档)。
加载类映射
务必加载 YAMNet 能够识别的类名。映射文件以 CSV 格式记录在 yamnet_model.class_map_path()
中。
运行推断
YAMNet 提供帧级类分数(即每帧 521 个分数)。为了确定剪辑级预测,可以按类跨帧聚合分数(例如,使用平均值或最大值聚合)。这是通过 scores_np.mean(axis=0)
以如下方式完成的。最后,要在剪辑级找到分数最高的类,您需要在 521 个聚合分数中取最大值。
注:模型正确推断出动物的声音。您在本教程中的目标是提高模型针对特定类的准确率。此外,请注意该模型生成了 13 个嵌入向量,每帧 1 个。
ESC-50 数据集
ESC-50 数据集 (Piczak, 2015) 是一个包含 2,000 个时长为 5 秒的环境录音的带标签集合。该数据集由 50 个类组成,每个类有 40 个样本。
下载并提取数据集。
探索数据
每个文件的元数据均在 ./datasets/ESC-50-master/meta/esc50.csv
下的 csv 文件中指定
所有音频文件均位于 ./datasets/ESC-50-master/audio/
您将创建支持映射的 pandas DataFrame
,并使用它来更清晰地查看数据。
过滤数据
现在,数据存储在 DataFrame
中,请应用一些转换:
过滤掉行并仅使用所选类 -
dog
和cat
。如果您想使用任何其他类,则可以在此处进行选择。修改文件名以获得完整路径。这将使后续加载更加容易。
将目标更改到特定区间内。在此示例中,
dog
将保持为0
,但cat
将改为1
,而非其原始值5
。
加载音频文件并检索嵌入向量
在这里,您将应用 load_wav_16k_mono
并为模型准备 WAV 数据。
从 WAV 数据中提取嵌入向量时,您会得到一个形状为 (N, 1024)
的数组,其中 N
为 YAMNet 找到的帧数(每 0.48 秒音频一帧)。
您的模型将使用每一帧作为一个输入。因此,您需要创建一个新列,每行包含一帧。您还需要展开标签和 fold
列以正确反映这些新行。
展开的 fold
列会保留原始值。您不能混合帧,因为在执行拆分时,最后可能会将同一个音频拆分为不同的部分,这会降低您的验证和测试步骤的效率。
拆分数据
您需要使用 fold
列将数据集拆分为训练集、验证集和测试集。
ESC-50 被排列成五个大小一致的交叉验证 fold
,这样,源自同一来源的剪辑就始终位于同一 fold
中 - 请参阅 ESC: Dataset for Environmental Sound Classification 论文以了解更多信息。
最后一步是从数据集中移除 fold
列,因为您在训练期间不会用到它。
创建模型
大部分工作已经完成!接下来,请定义一个非常简单的序贯模型,其中包含一个隐藏层和两个输出,以便通过声音识别猫和狗。
让我们对测试数据运行 evaluate
方法,以避免过拟合。
做得很棒!
测试模型
接下来,仅使用 YAMNet 基于之前测试中的嵌入向量尝试您的模型。
保存可直接将 WAV 文件作为输入的模型
使用嵌入向量作为输入,您的模型即可工作。
在实际场景中,您需要使用音频数据作为直接输入。
为此,您需要将 YAMNet 与您的模型组合成一个模型,从而导出用于其他应用。
为了便于使用模型的结果,最后一层将为 reduce_mean
运算。使用此模型进行应用时(您将在本教程后续内容中了解),您将需要最后一层的名称。如果未定义,TensorFlow 会自动定义递增式名称,这会使得使其难以测试,因为它会在您每次训练模型时不断变化。使用原始 TensorFlow 运算时,您无法为其分配名称。为了解决这个问题,您将创建一个应用 reduce_mean
的自定义层并将其称为 'classifier'
。
加载您保存的模型以验证它能否按预期工作。
最终测试:给定一些声音数据,您的模型能否返回正确的结果?
如果您想在应用环境中尝试您的新模型,可以使用 'serving_default' 签名。
(可选)更多测试
模型已准备就绪。
让我们基于测试数据集将它与 YAMNet 进行比较。