在 Android 上使用 TensorFlow Lite
2018 年 3 月 30 日
Laurence Moroney 发表,开发者倡导者

什么是 TensorFlow Lite?

TensorFlow Lite 是 TensorFlow 为移动设备和嵌入式设备提供的轻量级解决方案。它允许您在移动设备上以低延迟运行机器学习模型,因此您可以利用它们进行分类、回归或任何您想要的操作,而无需进行服务器往返。

它目前通过 C++ API 在 Android 和 iOS 上得到支持,此外还为 Android 开发人员提供 Java 包装器。此外,在支持它的 Android 设备上,解释器还可以使用 Android 神经网络 API 进行硬件加速,否则它将默认使用 CPU 执行。在这篇文章中,我将重点介绍如何在 Android 应用中使用它。

TensorFlow Lite 由一个 *运行时* 组成,您可以在该运行时上运行 *预先存在的* 模型,以及一套可用于准备模型以在移动设备和嵌入式设备上使用的工具。

它尚未设计用于 *训练* 模型。相反,您可以在功能更强大的机器上训练模型,然后将该模型 *转换为* .TFLITE 格式,然后将其加载到移动解释器中。
TensorFlow Lite architecture
TensorFlow Lite 目前处于开发者预览版,因此可能不支持所有 TensorFlow 模型中的所有操作。尽管如此,它 *确实* 支持常见的图像分类模型,包括 **Inception** 和 **MobileNets**。在本文中,您将了解如何在 Android 上运行 MobileNet 模型。该应用将查看相机馈送并使用训练过的 MobileNet 对图片中的主要图像进行分类。

将 TensorFlow Lite 与 MobileNets 配合使用

例如,在这张图片中,我将相机对准了我最喜欢的咖啡杯,发现它主要被分类为“杯子”,考虑到它的形状,很容易理解为什么!有趣的是,它还有一个大而宽的把手,您可以看到它非常像茶壶!
classifying coffee mug
那么,这是如何运作的呢?它使用 MobileNet 模型,该模型专为移动设备上的多种图像场景而设计和优化,包括目标检测、分类、面部属性检测和地标识别。
MobileNets
MobileNet 有多种变体,TensorFlow Lite 的训练模型托管在 此网站 上。您会注意到,每个模型都是一个包含两个文件的 zip 文件——一个 labels.txt 文件,其中包含模型训练的目标标签,以及一个 .tflite 文件,其中包含一个可与 TensorFlow Lite 一起使用的模型版本。如果您想继续并构建一个使用 MobileNets 的 Android 应用,则需要从该网站下载模型。您将在稍后看到这一点。

您可以在此视频中了解有关 TensorFlow Lite 的更多信息
介绍 TensorFlow Lite — 编码 TensorFlow

构建一个使用 TensorFlow Lite 的 Android 应用

要构建一个使用 TensorFlow Lite 的 Android 应用,您需要做的第一件事是将 tensorflow-lite 库添加到您的应用中。这可以通过在 build.gradle 文件的依赖项部分添加以下行来完成
compile ‘org.tensorflow:tensorflow-lite:+’
完成此操作后,您可以导入 TensorFlow Lite 解释器。解释器加载模型并允许您通过提供一组输入来运行它。然后,TensorFlow Lite 将执行模型并写入输出,就这么简单。
import org.tensorflow.lite.Interpreter;
要使用它,您需要创建一个解释器的实例,然后用 MappedByteBuffer 加载它。
protected Interpreter tflite;
tflite = new Interpreter(loadModelFile(activity));
GitHub 上的 TensorFlow Lite 示例 中有一个为此提供的辅助函数。只需确保 getModelPath() 返回一个指向 assets 文件夹中文件的字符串,模型就应该加载。
/** Memory-map the model file in Assets. */
private MappedByteBuffer loadModelFile(Activity activity) throws IOException {
  AssetFileDescriptor fileDescriptor = activity.getAssets().openFd(getModelPath());
  FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
  FileChannel fileChannel = inputStream.getChannel();
  long startOffset = fileDescriptor.getStartOffset();
  long declaredLength = fileDescriptor.getDeclaredLength();
  return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
}
然后,要对图像进行分类,您只需要调用 Interpeter 上的 **run** 方法,将图像数据和标签数组传递给它,它将完成其余的工作。
tflite.run(imgData, labelProbArray);
详细介绍如何从相机获取图像并将其准备用于 tflite 超出了本文的范围,但在 tensorflow github 中有一个完整的示例说明如何执行此操作。通过逐步浏览此示例,您可以了解它是如何从 gamera 获取图像、准备用于分类的数据以及如何通过将模型的加权输出优先级列表映射到标签数组来处理输出。

您可以在此视频中了解有关构建使用 TensorFlow Lite 的 Android 应用的更多信息
适用于 Android 的 TensorFlow Lite — 编码 TensorFlow
获取和运行 Android 示例

要运行示例,请确保您拥有完整的 TensorFlow 源代码。您可以使用以下命令获取它
> git clone https://www.github.com/tensorflow/tensorflow
完成此操作后,您可以从 Android Studio 中的 /tensorflow/contrib/lite/java/demo 文件夹打开 TensorFlow 示例项目。

演示文件不包含任何模型,它期望使用 mobilenet_quant_v1_224.tflite 文件,因此请务必从 此网站 下载模型。解压缩它并将其放入 assets 文件夹中。
您现在应该能够运行该应用。

请注意,该应用可能同时支持 Inception 和量化 MobileNet。它默认使用后者,因此您需要确保模型存在,否则应用将失败!从相机捕获数据并将其转换为可加载到模型中的字节缓冲区的代码可以在 ImageClassifier.java 文件中找到。

功能的核心可以在 Camera2BasicFragment.java 文件中的 classifyFrame() 方法中找到。
/** Classifies a frame from the preview stream. */
private void classifyFrame() {
  if (classifier == null || getActivity() == null || cameraDevice ==   null) {
  showToast(“Uninitialized Classifier or invalid context.”)
  return;
}
Bitmap bitmap = textureView.getBitmap(
  classifier.getImageSizeX(), classifier.getImageSizeY());
String textToShow = classifier.classifyFrame(bitmap);
bitmap.recycle();
showToast(textToShow);
}
在这里您可以看到位图被加载并调整为分类器所需的适当大小。然后,classifyFrame() 方法将返回包含与图像匹配的前 3 个类的列表及其权重的文本。

TensorFlow Lite 仍在不断发展,您可以通过 https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite 跟踪它的最新进展。

下一篇
Using TensorFlow Lite on Android

Laurence Moroney 发表,开发者倡导者
什么是 TensorFlow Lite?TensorFlow Lite 是 TensorFlow 为移动设备和嵌入式设备提供的轻量级解决方案。它允许您在移动设备上以低延迟运行机器学习模型,因此您可以利用它们进行分类、回归或任何您想要的操作,而无需进行服务器往返。

它目前...