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

1. 准备工作

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

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

在此 Codelab 中,您将自定义一个预训练音频分类模型,以检测鸟的叫声。同一方法可利用您自己的数据进行复制。

前提条件

此 Codelab 面向希望获得机器学习相关经验的移动开发者。您应熟悉以下内容/操作:

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

学习内容

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

所需物品

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

2. 鸟类数据集

您将使用已准备好的 Birdsong 数据集以使其更易于使用。所有音频文件都来自 Xeno-canto 网站

此数据集包含来自以下来源的歌曲:

名称:House Sparrow

代码:houspa

来自亚美尼亚、亚历杭德罗·拜尔·塔马约 (Alejandro Bayer Tamayo) 拍摄的鸟类品种的图片。

[音频]

名称:Red Crossbill

代码:redcro

图片:伊莱恩·威尔逊的红十字会鸟的图片。

[音频]

名称:白色乳木木制扳手

代码:wbwwre1

作家未知的白胸木制扳手的图片。

[音频]

名称:栗鼠冠 Antpitta

代码:chcant2

图片:由栗树冠形的蚂蚁

[音频]

名称:Azara's Spinetail

代码:azaspi1

图片:Azara Spinetail Bird。

[音频]

此数据集位于 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 - 完成后的示例应用的完整代码。

导入起始应用

首先,将入门应用导入 Android Studio:

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

7c0f27882a2698ac.png

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

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

4.了解起始应用

此应用与首个 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 训练自定义模型。

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

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

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

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

第一步是将已下载的模型从上一步移至应用中的“素材资源”文件夹。

  1. 在 Android Studio 中,在 Android 项目视图中,右键点击资源文件夹。

7cca2c22ed8cf4c8.png

  1. 您将看到一个弹出式窗口,其中包含选项列表。其中一种方法是在文件系统中打开该文件夹。找到适合您的操作系统的操作系统,然后选择该操作系统。如果是在 Mac 上,则显示为在 Finder 中显示;在 Windows 中,则会显示为在资源管理器中打开;而在 Ubuntu 中则会显示为在“文件”中显示

95e0eca881d35f6b.png

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

完成此操作后,请返回到 Android Studio,您应该会在资源文件夹中看到您的文件。

52bda66abe201fe5.png

7. 在基础应用中加载新模型

基础应用已在使用预训练模型。请将其替换为您刚训练的模型。

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

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

  • 您使用的基本模型(本例中为 YAMNet)的更通用的原始输出。
  • 特定于训练时所用的鸟类的辅助输出。

这种做法很有必要,因为 YAMNet 很好地识别了多个常见的类别,例如 Silence。这样一来,您就不必担心尚未添加到数据集的所有其他类。

您现在要做的就是,如果 YAMNet 分类显示鸟类的最高分,则应该查看其他输出中是哪只鸟。

37ce1c14e9e2d1b0.png

  1. TODO 2:查看分类的第一个负责人是否有很大的把握确定其是鸟类声音。在这里,您将更改过滤条件,同时滤除除鸟类之外的所有内容:
val filteredModelOuput = output[0].categories.filter {
   it.label.contains("Bird") && it.score > .3
}
  1. TODO 3:如果模型的基础头部检测到音频中有鸟类,并且很可能是一个鸟类,您将获得二头鸟。
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 应用中使用模型

后续步骤

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

了解详情

有疑问?

报告问题