创建一款基本的音频分类应用

1. 准备工作

TensorFlow 是一个多用途机器学习框架。它可用于跨云端集群训练大型模型,或在手机等嵌入式系统本地运行模型。

本 Codelab 使用 TensorFlow Lite 在 Android 设备上运行音频分类模型。

学习内容

  • 如何查找可供使用的预训练机器学习模型。
  • 如何对实时捕获的音频进行音频分类。
  • 如何使用 TensorFlow Lite 支持库预处理模型输入以及后处理模型输出。
  • 如何使用 Audio Task 库执行所有音频相关工作。

您将构建的内容

一个简单的音频识别器应用,运行 TensorFlow Lite 音频识别模型,实时识别麦克风中输入的音频

33af0fdb0a027fa8.png

所需条件

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

2. 获取示例代码

下载代码

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

下载源代码

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

注意:您可以根据需要克隆代码库:

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

audio_classification/codelab1/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/codelab1/android/starter)。

7c0f27882a2698ac.png

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

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

运行 starter 应用

现在,您已将项目导入 Android Studio,接下来就可以首次运行该应用了。

通过 USB 线将 Android 设备连接到计算机,然后点击 Android Studio 工具栏中的 Run 图标 (execute.png)。

5518972c21705945.png

3. 查找预训练模型

如需完成音频分类,您需要一个模型。先使用预训练模型,这样就无需自己训练模型。

如需查找预训练模型,您可以使用 TensorFlow Hub (www.tfhub.dev)。

91e39900ff58818c.png

模型会按领域进行分类。您现在所需解决的问题位于 Audio Issue Domains

9d44d38c297bf3dc.png

对于您的应用,可以使用 YAMNet 模型进行事件分类

YAMNet 是一个音频事件分类器,它会将音频波形作为输入,并分别为 521 个音频事件做出独立预测。

yamnet/classification 模型可以转换到 TensorFlow Lite,并且具有特定的元数据,这些元数据启用了 TFLite Task 库的音频,这样更便于在移动设备上使用模型。

65dc0f610eb27762.png

选择正确的标签页:TFLite (yamnet/classification/tflite),然后点击下载。您还可以在底部看到模型的元数据。

cfb3cfeb310e1f51.png

此模型文件 (lite-model_yamnet_classification_tflite_1.tflite) 将在下一步中使用。

4. 将新模型导入基本应用

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

在 Android Studio 的项目资源管理器中,右键点击 assets 文件夹。

7cca2c22ed8cf4c8.png

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

95e0eca881d35f6b.png

然后将下载的模型复制到其中。

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

703b1842fb09e893.png

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

现在,您需要执行一些 TODO 步骤,并使用在上一步中刚刚添加到项目的模型来进行音频分类。

为了便于查找 TODO,请在 Android Studio 中转到菜单:View > Tool Windows > TODO。系统会打开一个包含 TODO 列表的窗口,您只需点击 TODO 项即可直接转到相应代码。

在文件 build.gradle(模块版本)中,您会看到第一个任务。

TODO 1:添加 Android 依赖项。

implementation 'org.tensorflow:tensorflow-lite-task-audio:0.2.0'

其余的所有代码更改都将在 MainActivity 中进行

TODO 2.1:使用模型名称创建变量,以便在后续步骤中加载模型。

var modelPath = "lite-model_yamnet_classification_tflite_1.tflite"

TODO 2.2:定义一个最低阈值,以接受来自模型的预测。稍后会用到这个变量。

var probabilityThreshold: Float = 0.3f

TODO 2.3:从 assets 文件夹加载模型。在 Audio Task 库中定义的 AudioClassifier 类已准备好加载模型,并为您提供运行推断和创建音频录制器所需的所有方法。

val classifier = AudioClassifier.createFromFile(this, modelPath)

6. 获取音频

Audio Tasks API 提供了一些辅助方法,可帮助您使用模型预期的正确配置(例如采样率、比特率、声道数)创建音频录制器。这样一来,您无需手动查找配置,也无需创建配置对象。

TODO 3.1:创建张量变量,该变量将存储用于推断的录音,并为录制器设置格式规范。

val tensor = classifier.createInputTensorAudio()
val format = classifier.requiredTensorAudioFormat

TODO 3.2:显示上一步中由模型的元数据定义的音频录制器规范。

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

92e81894674a5b0.png

TODO 3.3:创建音频录制器并开始录制。

val record = classifier.createAudioRecord()
record.startRecording()

到目前为止,您的应用已经可以监听手机麦克风的音频,但仍然不会作出任何推断。您将在下一步中解决此问题。

7. 将推断功能添加到模型中

在此步骤中,您将向应用添加推断代码并将其显示在屏幕上。该代码已包含一个每半秒执行一次的定时器线程,并且这个线程会控制推断的运行。

scheduleAtFixedRate 方法的参数包含代码开始执行前所等待的时间,以及连续执行任务之间的时间间隔,在下面的代码中设置为每 500 毫秒。

Timer().scheduleAtFixedRate(1, 500) {
...
}

TODO 4.1:添加代码来使用该模型。首先将录音加载到音频张量中,然后将其传递给分类器:

tensor.load(record)
val output = classifier.classify(tensor)

TODO 4.2:为了获得更准确的推断结果,需要过滤掉任何概率非常低的分类。在此步骤,您将使用在上一步 (probabilityThreshold) 中创建的变量:

val filteredModelOuput = output[0].categories.filter {
   it.score > probabilityThreshold
}

TODO 4.3:为了便于读取结果,我们使用过滤后的结果来创建一个字符串。

val outputStr = filteredModelOuput.map { "${it.label} -> ${it.score} " }
   .joinToString(separator = "\n")

TODO 4.4:更新界面。在此简易应用中,结果仅显示在 TextView 中。由于分类不在主线程上,您需要使用处理程序来执行此更新。

runOnUiThread {
   textView.text = outputStr
}

您已添加了执行以下操作所需的所有代码:

  • 从 assets 文件夹加载模型
  • 使用正确配置创建音频录制器
  • 运行推断
  • 在屏幕上显示最佳结果

现在,您需要做的就是测试应用。

8. 运行 final 应用

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

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

首次执行时,您需要向应用授予音频录制权限。

获得授权后,该应用在启动时将使用手机的麦克风。为了进行测试,请开始在手机附近讲话,因为语音是 YAMNet 检测的其中一个类。另一个容易测试的类是打响指或拍手。

您还可以尝试检测犬吠声以及许多其他可能的事件 (521)。如需查看完整列表,请查看其源代码,也可以直接使用标签文件读取元数据

33af0fdb0a027fa8.png

9. 恭喜!

在此 Codelab 中,您了解了如何查找用于音频分类的预训练模型,并使用 TensorFlow Lite 将其部署到您的移动应用。如需详细了解 TFLite,请查看其他 TFLite 示例

所学内容

  • 如何在 Android 应用中部署 TensorFlow Lite 模型。
  • 如何从 TensorFlow Hub 查找和使用模型。

后续步骤

  • 使用您自己的数据自定义模型。

了解详情

是否存在任何疑问?

报告问题