构建自定义的预训练音频分类模型

1. 准备工作

在上一个 Codelab 中,您构建了一个用于音频分类的基本应用。

如果需要自定义音频分类模型,以识别预训练模型中不存在的其他类别的音频,该怎么办?或者,如果您希望使用自己的数据自定义模型,该怎么办?

在此 Codelab 中,您将自定义一个预训练的音频分类模型来检测鸟类鸣叫的声音。您可以将相同的方法运用到您自己的数据中。

前提条件

本 Codelab 专为希望获得机器学习经验并具有移动开发经验的开发者而设计。您应熟悉以下知识:

  • 使用 Kotlin 和 Android Studio 进行 Android 开发
  • 基本 Python 语法

学习内容

  • 如何在音频领域进行迁移学习
  • 如何创建自己的数据
  • 如何在 Android 应用中部署自己的模型

所需条件

  • 最新版本的 Android Studio (v4.1.2+)
  • 一台 Android 设备,搭载的 Android 版本为 API 23 (Android 6.0)
  • 示例代码
  • 使用 Kotlin 进行 Android 开发的基础知识

2. 鸟类数据集

您将使用一个已准备好的 Birdsong 数据集,这样更便于使用。所有音频文件都来自 Xeno-canto 网站

此数据集包含来自以下鸟类的鸣声:

名称:家麻雀

代码:houspa

由哥伦比亚亚美尼亚城的 Alejandro Bayer Tamayo 拍摄的家麻雀图片。

[音频]

名称:红交嘴雀

代码:redcro

由 Elaine Wilson 拍摄的红交嘴雀图片。

[音频]

名称:白胸林鹩

代码:wbwwre1

白胸林鹩图片,拍摄者未知。

[音频]

名称:栗顶蚁鸫

代码:chcant2

栗顶蚁鸫图片

[音频]

名称:阿氏针尾雀

代码:azaspi1

阿氏针尾雀图片。

[音频]

此数据集为 zip 文件,其内容如下:

  • 一个 metadata.csv 文件,包含每一个音频文件的全部信息,例如音频录制者、录音的位置、使用许可以及鸟类的名称。
  • 一个训练和测试文件夹。
  • 在训练/测试文件夹中,每种鸟类代码都包含一个文件夹。每个文件里面都有该种鸟类的所有 .wav 文件。

所有音频文件均采用 wav 格式,并遵循以下规范:

此规范非常重要,因为您将使用的基本模型需要这种格式的数据。如需了解详情,您可以在这篇博文中阅读更多信息。

为简化整个过程,您无需在计算机上下载数据集,您将在 Google Colab(本指南的后面部分)中使用该数据集。

如果您要使用自己的数据,则您的所有音频文件也必须符合此特定格式。

3. 获取示例代码

下载代码

点击下面的链接可下载本 Codelab 的所有代码:

下载源代码

或者,您也可以根据需要克隆代码库:

git clone https://github.com/googlecodelabs/odml-pathways.git

解压下载的 ZIP 文件。此操作会解压缩一个根文件夹 (odml-pathways),其中包含您需要的所有资源。对于此 Codelab,您只需要 audio_classification/codelab2/android 子目录中的源代码。

audio_classification/codelab2/android 代码库中的 android 子目录包含两个目录:

  • android_studio_folder.pngstarter - 在此 Codelab 中帮助您开始构建模型的起始代码。
  • android_studio_folder.pngfinal - 完成后的示例应用的完整代码。

导入 starter 应用

首先,将 starter 应用导入 Android Studio。

  1. 打开 Android Studio,然后选择 Import Project (Gradle, Eclipse ADT, etc.)
  2. 打开您之前所下载源代码中的 starter 文件夹 (audio_classification/codelab2/android/starter)。

7c0f27882a2698ac.png

为确保您的应用能使用所有的依赖项,在导入过程完成后,应将您的项目与 Gradle 文件同步。

  1. 从 Android Studio 工具栏中选择 Sync Project with Gradle Files 图标 (b451ab2d04d835f9.png)。

4. 了解 starter 应用

在第一个音频分类 Codelab 创建音频分类基本应用中,我们构建了一个应用,构建此应用的方法与之相同。

为了更好地了解代码的细节,建议您在继续之前先认真学习该 Codelab。

所有代码都在 MainActivity 中(尽可能保持简单)。

总而言之,该代码涉及以下任务:

  • 加载模型
val classifier = AudioClassifier.createFromFile(this, modelPath)
  • 创建音频录制器并开始录制
val tensor = classifier.createInputTensorAudio()

val format = classifier.requiredTensorAudioFormat
val recorderSpecs = "Number Of Channels: ${format.channels}\n" +
       "Sample Rate: ${format.sampleRate}"
recorderSpecsTextView.text = recorderSpecs

val record = classifier.createAudioRecord()
record.startRecording()
  • 创建用于运行推断的定时器线程scheduleAtFixedRate 方法的参数包含代码开始执行前所等待的时间以及连续执行任务之间的时间间隔。在下面的代码中,将在 1 毫秒后开始运行,并且每 500 毫秒再次运行一次。
Timer().scheduleAtFixedRate(1, 500) {
...
}
  • 对采集到的音频运行推断
val numberOfSamples = tensor.load(record)
val output = classifier.classify(tensor)
  • 过滤低得分分类
val filteredModelOutput = output[0].categories.filter {
   it.score > probabilityThreshold
}
  • 在屏幕上显示结果
val outputStr = filteredModelOutput.map { "${it.label} -> ${it.score} " }
   .joinToString(separator = "\n")

runOnUiThread {
   textView.text = outputStr
}

您现在可以运行应用并按原样使用它,但请注意,它使用的是更通用的预训练模型。

5. 使用 Model Maker 训练自定义音频分类模型

在上一步中,您已经下载了使用预训练模型对音频事件进行分类的应用。但有时您需要根据自己感兴趣的音频事件自定义此模型,或将其自定义成更为专业的版本。

如前所述,您需要针对鸟类鸣叫声音专门制作模型。下面是一个鸟类音频数据集(由 Xeno-canto 网站收选)。

Colaboratory

接下来,转到 Google Colab 训练自定义模型。

Google Colab

训练自定义模型大约需要 30 分钟。

如果您想跳过此步骤,则可以下载使用已提供数据集在 Colab 上训练过的模型,然后继续下一步

下载鸟鸣检测模型

6. 将自定义 TFLite 模型添加到 Android 应用

现在,您已经训练了自己的音频分类模型并将其保存在本地,接下来,您需要将其放置到 Android 应用的 assets 文件夹中。

第一步是将上一步中下载的模型移至应用中的 assets 文件夹。

  1. 在 Android Studio 中,从 Android Project 视图右键点击 assets 文件夹。

7cca2c22ed8cf4c8.png

  1. 您将看到一个带有选项列表的弹出式窗口。其中一项操作会在文件系统中打开文件夹。找到适用于您的操作系统的选项,并选择该项操作。在 Mac 上,此项操作为 Reveal in Finder,在 Windows 上为 Open in Explorer,而在 Ubuntu 上为 Show in Files

95e0eca881d35f6b.png

  1. 将下载的模型复制到该文件夹中。

完成上述操作后,请返回 Android Studio,您应该会在 assets 文件夹中看到相应文件。

52bda66abe201fe5.png

7. 在基本应用上加载新模型

基本应用已使用了一个预训练模型。您可以用刚训练的模型替换该预训练模型。

  1. TODO 1:如需在将新模型添加到 assets 文件夹后加载该模型,请更改 modelPath 变量的值:
var modelPath = "my_birds_model.tflite"

新模型有两个输出(head):

  • 一个输出是:来自您所使用基本模型(在本例中为 YAMNet)的原始通用输出。
  • 另一个输出是:您使用数据训练专门针对鸟类模型的输出。

这很有必要,因为 YAMNet 在识别多个常见类(例如,静音)方面做得非常出色。如此一来,您无需担心自己未添加到数据集中的所有其他类。

您现在要做的是,如果 YAMNet 分类显示鸟类得分较高,您就可以通过另一个输出来了解是哪种鸟。

37ce1c14e9e2d1b0.png

  1. TODO 2:读取并判断类的第一个 head 对这是鸟类鸣叫声音是否具有很高的置信度。在这里您将更改过滤方式,以便同时过滤掉非鸟类鸣叫的其他声音:
val filteredModelOuput = output[0].categories.filter {
   it.label.contains("Bird") && it.score > .3
}
  1. TODO 3:如果模型的基本 head 检测到音频中可能是鸟类的概率很高,在第二个 head 上将会获知是哪种鸟:
if (filteredModelOutput.isNotEmpty()) {
   Log.i("Yamnet", "bird sound detected!")
   filteredModelOutput = output[1].categories.filter {
       it.score > probabilityThreshold
   }
}

就这么简单。更改模型来使用您刚刚训练的模型非常容易。

下一步就是对其进行测试。

8. 使用新模型测试应用

您已将音频分类模型集成到该应用中,因此我们将对其进行测试。

  1. 连接您的 Android 设备,然后点击 Android Studio 工具栏中的 Run 图标 (execute.png)。

该应用应该能够正确预测各种鸟类的音频。为使测试过程更容易,您只需播放计算机提供的音频(在之前的步骤中完成),手机应该就能够对其进行检测。当检测到音频时,屏幕上会显示鸟的名称以及正确性的概率。

bec397de3c8aaf32.png

9. 恭喜

在此 Codelab 中,您了解了如何使用 Model Maker 创建自己的音频分类模型,以及如何使用 TensorFlow Lite 将其部署到您的移动应用。如需详细了解 TFLite,请查看其他 TFLite 示例

所学内容

  • 如何准备自己的数据集
  • 如何使用 Model Maker 进行音频分类的迁移学习
  • 如何在 Android 应用中使用您的模型

后续步骤

  • 尝试使用自己的数据
  • 与我们分享您的作品

了解详情

是否存在任何疑问?

报告问题