2021 年 3 月 2 日 - 作者:Luiz GUStavo Martins,开发者倡导者迁移学习 是一种流行的机器学习技术,您可以通过重复使用先前模型学习的信息来训练新模型。迁移学习最常见的应用是视觉领域,使用少量数据来训练准确的图像分类器或对象检测器,或者用于文本,其中使用预训练的文本嵌入或 BERT 等语言模型来改进自然语言理解任务,例如情感分析或问答。在本文中,您将学习如何将迁移学习用于一种新的重要数据类型:音频,以构建声音分类器。
作者:Luiz GUStavo Martins,开发者倡导者
迁移学习 是一种流行的机器学习技术,您可以通过重复使用先前模型学习的信息来训练新模型。迁移学习最常见的应用是视觉领域,使用少量数据来训练准确的图像分类器或对象检测器,或者用于文本,其中使用预训练的文本嵌入或 BERT 等语言模型来改进自然语言理解任务,例如情感分析或问答。在本文中,您将学习如何将迁移学习用于一种新的重要数据类型:音频,以构建声音分类器。
音频分类有很多重要的用例,包括 保护野生动物、检测鲸鱼,甚至 打击非法砍伐森林。
使用 YAMNet,您可以在几个简单的步骤中创建一个定制的音频分类器
您可以按照此教程中的代码进行操作 此处。
YAMNet(“Yet another Audio Mobilenet Network”)是一个预训练模型,它根据 AudioSet 语料库 预测 521 个音频事件。
此模型在 TensorFlow Hub 上可用,包括 TFLite 和 TF.js 版本,用于在移动设备和网络上运行该模型。代码可以在他们的 存储库 中找到。
该模型有 3 个输出
该模型采用以 16 kHz 采样表示的波形,范围为 [-1.0, 1.0],将其框定在 0.96 秒的窗口中,并在 0.48 秒的跳跃中,然后运行模型的核心以提取一批这些帧的嵌入。
在波形上跳跃 0.96 秒的窗口 |
例如,尝试使用此音频文件 [链接] 与模型一起使用将为您提供这些结果
第一个图是波形。第二个图是对数梅尔谱图。第三个图显示了每帧音频的类别概率预测,其中深色表示可能性更高。 |
要使用该模型进行迁移学习,您将使用 环境声音分类数据集,简称 ESC-50。这是一个包含 50 个类别中的 2000 个环境音频录音的集合。每个录音长 5 秒,最初来自 Freesound 项目。
ESC-50 包含您需要的狗和猫类别。
该数据集有两个重要的组成部分:音频文件和一个包含每个音频文件元数据的元数据 csv 文件。
元数据 csv 文件中的列包含将用于训练模型的信息
有关更详细的信息,您可以阅读 原始 ESC 论文。
要加载数据集,您将从元数据文件开始,并使用 Pandas 方法 read_csv
加载它。
使用加载的数据框,下一步是按将要使用的类别进行过滤,在本例中为:狗和猫。
下一步将是加载音频文件以开始该过程,但如果音频文件过多,仅将所有音频文件加载到内存可能会造成很大的负担并导致内存不足问题。最佳解决方案是在需要时延迟加载音频文件。TensorFlow 可以使用 tf.data.Dataset 和 map 方法轻松实现这一点。
让我们从之前创建的 pandas 数据框创建数据集,并将 load_wav 方法应用于所有文件
filenames = filtered_pd['filename']
targets = filtered_pd['target']
folds = filtered_pd['fold']
main_ds = tf.data.Dataset.from_tensor_slices((filenames, targets, folds))
main_ds = main_ds.map(load_wav_for_map)
在这里,还没有将任何音频文件加载到内存中,因为映射尚未进行评估。例如,如果您请求数据集的大小,例如 (len(list(train_ds.as_numpy_iterator()))
,这将使 map 函数进行评估并加载所有文件。
相同的技术将用于从每个音频文件中提取所有特征(嵌入)。
在这里,您将从 TensorFlow Hub 加载 YAMNet 模型。您只需要模型的句柄,并调用 tensorflow_hub
库中的 load
方法。
yamnet_model_handle = 'https://tfhub.dev/google/yamnet/1'
yamnet_model = hub.load(yamnet_model_handle)
这将加载模型到内存中,准备使用。
对于每个音频文件,您将使用 YAMNet 模型提取嵌入。对于每个音频文件,将执行 YAMNet。嵌入输出与音频文件中的相同标签和文件夹配对。
def extract_embedding(wav_data, label, fold):
''' run YAMNet to extract embedding from the wav data '''
scores, embeddings, spectrogram = yamnet_model(wav_data)
num_embeddings = tf.shape(embeddings)[0]
return (embeddings,
tf.repeat(label, num_embeddings),
tf.repeat(fold, num_embeddings))
main_ds = main_ds.map(extract_embedding).unbatch()
这些嵌入将是分类模型的输入。从模型的 文档 中,您可以看到,对于给定的音频文件,它会将波形框定在长度为 0.96 秒、跳跃为 0.48 秒的滑动窗口中,然后运行模型的核心。因此,总而言之,对于每 0.48 秒,模型将输出一个包含 1024 个浮点值的嵌入数组。此部分也是使用 map() 完成的,因此也是延迟评估,这就是它执行如此快的原因。
最终数据集包含三个使用的列:嵌入、标签和折叠。
最后一个数据集操作是拆分为训练集、验证集和测试集。为此,请使用 filter() 方法并将折叠字段(1 到 5 之间的整数)用作条件。
cached_ds = main_ds.cache()
train_ds = cached_ds.filter(lambda embedding, label, fold: fold < 4)
val_ds = cached_ds.filter(lambda embedding, label, fold: fold == 4)
test_ds = cached_ds.filter(lambda embedding, label, fold: fold == 5)
有了 YAMNet 嵌入向量和标签,下一步是训练一个分类器来学习什么是狗的声音,什么是猫的声音。
分类器模型非常简单,只有两层密集层,但正如您将看到的,这对于使用的数据量来说已经足够了。
my_model = tf.keras.Sequential([
tf.keras.layers.Input(shape=(1024), dtype=tf.float32, name='input_embedding'),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(len(my_classes))
])
训练的模型可以正常工作并且具有良好的准确率,但它所期望的输入不是音频波形,而是一个嵌入数组。为了解决这个问题,最终模型将 YAMNet 作为输入层,并将刚刚训练的模型组合在一起。这样,最终模型将接受波形并输出类别
input_segment = tf.keras.layers.Input(shape=(), dtype=tf.float32,
name='audio')
embedding_extraction_layer = hub.KerasLayer('https://tfhub.dev/google/yamnet/1', trainable=False)
scores, embeddings, spectrogram = embedding_extraction_layer(input_segment)
serving_outputs = my_model(embeddings_output)
serving_outputs = ReduceMeanLayer(axis=0, name='classifier')(serving_outputs)
serving_model = tf.keras.Model(input_segment, serving_outputs)
serving_model.save(saved_model_path, include_optimizer=False)
要尝试重新加载的模型,您可以使用之前在 colab 中使用它的方式
reloaded_model = tf.saved_model.load(saved_model_path)
reloaded_results = reloaded_model(testing_wav_data)
cat_or_dog = my_classes[tf.argmax(reloaded_results)]
此模型也可以与 TensorFlow Serving 一起使用,使用 'serving_default'
serving_results = reloaded_model.signatures['serving_default'](testing_wav_data)
cat_or_dog = my_classes[tf.argmax(serving_results['classifier'])]
在这篇文章中,您学习了如何使用 YAMNet 模型进行迁移学习,以识别来自 ESC-50 数据集的狗和猫的音频。
请查看 tfhub.dev 上的 YAMNet 模型和 tensorflow.org 上的教程。您可以将此技术应用于您自己的数据集,或应用于 ESC-50 数据集中的其他类别。
我们很想知道您可以用它构建什么!使用标签 #TFHub 在社交媒体上与我们分享您的项目。
我们要感谢许多同事对这项工作的贡献:Dan Ellis、Manoj Plakal 和 Eduardo Fonseca 为我们提供了出色的 YAMNet 模型,并支持 colab 和多次审阅。
Mark Daoust 和 Elizabeth Kemp 极大地改善了本文和相关教程中材料的演示。
2021 年 3 月 2 日 - 作者:Luiz GUStavo Martins,开发者倡导者迁移学习 是一种流行的机器学习技术,您可以通过重复使用先前模型学习的信息来训练新模型。迁移学习最常见的应用是视觉领域,使用少量数据来训练准确的图像分类器或对象检测器,或者用于文本,其中使用预训练的文本嵌入或 BERT 等语言模型来改进自然语言理解任务,例如情感分析或问答。…