移动端机器学习实战
上QQ阅读APP看书,第一时间看更新

1.3 TensorFlow Lite

TensorFlow Lite框架由5个高级的组件构成。这些组件都针对移动平台进行过优化,整个架构如下图所示。

下面是TensorFlow Lite架构核心单元的介绍。

  • TensorFlow Lite转换器——用于将已经存在的模型转换为TensorFlow Lite兼容的模型(.tflite),并将经过训练的模型保存在硬盘上。还可以在移动或者嵌入式应用程序中使用提前训练过的模型。
  • Java/C++ API——用于载入.tflite模型并调用解释器。这些API适用于所有平台。Java API是在C++ API上进行了一层封装,只能应用在Android系统上。
  • 解释器和内核——解释器模块在操作系统内核的帮助下工作。它会根据选择地载入内核模块,核心解释器的大小为75KB。相对于TensorFlow Mobile需要使用1.1MB的核心解释器来说,TensorFlow Lite的内核已经减少了相当多。加上所有相关操作,核心解释器的大小上升到了400KB。开发者可以选择包含哪些操作,这样就能减少内核占用的空间。
  • 硬件加速的代理——在所选的Android设备上,解释器将会使用Android神经网络API(Android Neural Network API,NNAPI)来实现硬件加速,如果NNAPI不可用,就会使用CPU进行默认加速。

可以使用C++ API实现自定义内核,这个自定义内核也可以由解释器使用。

1.3.1 支持的平台

TensorFlow Lite当前支持Android/iOS平台,也支持Linux(如Raspberry Pi)平台(见下图)。在嵌入式设备(如Raspberry Pi)中,Python API将会很有帮助。TensorFlow Lite平台同样支持Core ML模型以及iOS平台。

在iOS平台上,可以直接将预训练的TensorFlow 模型在格式上转换为Core ML模型,这样应用程序就可以直接运行在Core ML运行时中。

当只有单一模型的时候,通过格式转换可以让它既运行在Android平台上,也运行在iOS平台上(见下图)。

1.3.2 TensorFlow Lite的内存使用情况和性能

TensorFlow模型使用了FlatBuffers。FlatBuffers是一个跨平台、开源的序列化库。使用FlatBuffers的主要优点是在打包/解包的过程中不需要辅助表征(secondary representation)。FlatBuffers通常与逐对象的内存分配(per-object memory allocation)搭配使用。相对于Protocol Buffers而言,FlatBuffers更节约内存,因为它有助于保持较小的内存占用量。

FlatBuffers最开始是针对游戏平台开发的。出于性能原因,它也应用在其他领域。在转换过程中,TensorFlow Lite提前处理了激活和偏差的问题,让TensorFlow Lite执行得更快。解释器使用静态内存和执行计划,这可以加快载入速度。优化过的内核可以在NEON和ARM平台上运行得更快。

TensorFlow充分利用了这些设备上硅片级的创新。TensorFlow Lite支持Android NNAPI。在编写本书的时候,不少Oracle企业管理器(Oracle Enterprise Manager,OEM)已经开始使用NNAPI了。TensorFlow Lite直接使用了图形加速,也就是说,在Android上使用开放图形库(Open Graphics Library,OpenGL),在iOS上使用Metal。

为了优化性能,分层方式有一些更改。采用一种存储数字和对数字执行运算的技术。TensorFlow Lite提供的帮助有两方面。首先,只要模型越小,TensorFlow Lite就越适合小型设备。其次,很多处理器使用专门的synthe指令集,该指令集处理定点数的速度远远大于处理浮点数的速度。所以,一种非常原始的分层方式就是在训练之后简单地缩小权重和激活数量。不过这样会导致次优的准确率。

TensorFlow Lite的性能是MobileNet和Inception V3上TensorFlow性能的3倍。虽然TensorFlow Lite仅支持推断,但是它很快就会拥有一个训练模块。TensorFlow Lite支持将近50个常见的操作。

它支持MobileNet、Inception V3、RedNet50、SqueezeNet、DenseNet、Inception V4、SmartReply以及其他网络(见下图)。

 

图中纵轴的单位是毫秒。

1.3.3 动手使用TensorFlow Lite

借助TensorFlow Lite,可以使用一个已有模块迅速开始构建第一个基于TensorFlow Lite的应用程序(见下图)。

在实际情况下,使用TensorFlow Lite包含4步。

(1)要么使用一个已经存在的模型,要么使用自己的模型并训练它。

(2)一旦准备好模型,就需要使用转换器将其转换为.tflite格式。

(3)在这个模型之上编写各种类型的优化操作。

(4)开始实现hello world项目。

从这里开始,直接进入代码部分。

1.3.4 将SavedModel转换为TensorFlow Lite格式

只需要调用一行转换函数,就可以将ML模型转换为TensorFlow Lite模型。下面是一段简单的Python代码,它会将已经存在的模型转换为TensorFlow Lite格式。可以输入已经存在的模型,并将它转换为.tflite格式。

import sys
from tf.contrib.lite import convert_savedmodel
convert_savedmodel.convert(
                            saved_model_directory="/tmp/your_model",
                            output_tflite_file="/tmp/my_model.tflite")

这段代码将从其他框架创建的模型转换为使用FlatBuffers的TensorFlow Lite格式。下面是一些转换策略。

策略

我们实现了下列策略。

  • 使用固化图形文件(frozen graphdef)或者SavedModel。
  • 避免不支持的操作符。
  • 使用可视化器来理解模型(TensorBoard和TensorFlow Lite可视化器)。
  • 针对任何缺失的功能,使用自定义操作符。
  • 如果在转换过程中漏掉了一些内容,请向社区提交问题。

后面的章节将会结合实际应用程序探讨这些策略的细节。

1.3.5 在Android上使用TensorFlow Lite

我们可以从TensorFlow GitHub仓库的示例应用程序开始学习。示例是一个相机应用程序,它使用浮点数的Inception V3模型或者量化的MobileNet模型持续对图片进行分类。尝试使用Android 5.0版本或者更早的版本。

 

示例应用程序参见GitHub网站。

这个应用程序用于实时地按帧分类。它显示了最可能的分类,同时还会显示检测每张图片所需的时间。

通过3种方法可以让这个示例应用程序运行在设备上。

  • 下载提前编译好的APK文件。
  • 使用Android Studio构建应用程序并运行。
  • 使用Bazel下载TensorFlow Lite的源代码,并在命令行中运行应用程序。

1.下载APK文件

这是尝试运行示例应用程序最简单的方法。

安装了示例应用程序之后,打开它。首次打开这款应用程序的时候,它会提示你使用运行时权限访问设备相机。一旦具有了访问权限,你就可以使用这款应用程序实时识别相机视图中的对象了。在结果中,可以看到已识别对象的前3种分类,以及分类花费的时间。

2.使用Android Studio构建TensorFlow Lite应用程序

按照下面的步骤可以直接通过Android Studio下载并构建TensorFlow Lite。

(1)下载并安装最新版本的Android Studio。

(2)在Android Studio的设置中,确保NDK的版本大于14,SDK的版本大于26。本书中的应用程序使用的SDK的版本是27。后面将会详细介绍如何配置。

(3)从GitHub网站下载tflitecamerademo应用程序。

(4)按照Android Studio的提示,下载所有Gradle的相关依赖项。

为了在应用程序中使用模型,需要提供一个模型。要么使用已经存在的模型,要么训练自己的模型。在这个应用程序中,使用一个已经存在的模型。

可以从GitHub网站下载已经存在的模型,也可以从GitHub网站下载压缩过的模型文件。

可以下载Inception V3浮点模型或者最新的MobileNet模型。首先,将合适的.tflite文件复制到Android应用程序的assets文件夹中。然后,更改Camera2BasicFragment.java文件,该文件位于tensorflow/contrib/lite/java/demo/app/src/main/assets/中。

 

可以从GitHub网站下载已经存在的models.md模型。

现在,可以开始构建并运行示例应用程序。

3.从源代码中构建TensorFlow Lite示例应用程序

复制TensorFlow的代码仓库。需要使用Bazel来构建APK。

git clone https://github.com/tensorflow/tensorflow

4.安装Bazel

如果系统中还没有安装Bazel,那么首先要安装它。本书的编写环境基于macOS High Sierra 10.13.2。可以使用Homebrew来安装Bazel。

5.安装Homebrew

请按照下面的步骤安装Homebrew。

(1)因为Homebrew依赖JDK,所以首先要安装JDK。从Oracle官方网站下载并安装最新的JDK。

(2)安装Homebrew。

可以直接在Terminal中运行如下脚本。

/usr/bin/ruby -e "$(curl -fsSL \
   https://github.com/Homebrew/)"

一旦Homebrew安装完毕,可以使用以下命令安装Bazel。

brew install bazel

现在,所需的软件已经安装好,可以使用下面的命令确认Bazel的版本。

bazel version

如果已经安装了Bazel,那么可以使用下面的命令升级Bazel的版本。

brew upgrade bazel

 

Bazel当前在Windows系统上不支持Android版本。Windows用户应该下载已经构建好的二进制文件。

6.安装Android NDK和SDK

构建TensorFlow Lite代码需要Android NDK。Android NDK Archives 可以从Android Developers网站下载。

SDK工具中有Android Studio,需要使用V23或者更高版本的构建工具。(运行应用程序的设备需要API的版本至少为21。)

可以在根目录的WORKSPACE文件中更新API等级以及SDK和NDK的路径。

在根节点中更新api_level和SDK以及NDK的位置。如果在Android Studio中打开SDK Manager,就会看到SDK的路径。比如,下面的SDK配置方式。

android_sdk_repository (
 name = "androidsdk",
 api_level = 27,
 build_tools_version = "27.0.3",
 path = "/Users/coco/Library/Android/sdk",
)

Android NDK的配置方式如下。

android_ndk_repository(
 name = "androidndk",
 path = "/home/coco/android-ndk-r14b/",
 api_level = 19,
)

在编写本书的时候,NDK Archives使用的是android-ndk-r14b-darwin-x86_64.zip。可以根据实际需要调整前面的参数。

现在,可以开始构建源代码了。为了构建示例应用程序,运行Bazel。

bazel build --cxxopt=--std=c++11
 //tensorflow/contrib/lite/java/demo/app/src/main:TfLiteCameraDemo

 

由于一个Bug,Bazel现在仅支持Python 2的环境。

 

MobileNet是新手学习ML的一个很好的起点。这个数据库中的模型图片的大小是299×299像素。不过,相机捕捉的画面是224×224像素,需要重新调整大小以适配模型。在硬盘上每张图片会占224×224×3字节,之后这些字节会逐行转换为ByteBuffer。在这里,数字3表示每个像素的RGB值。

示例应用程序使用了TensorFlow Lite的Java API,它首先以一张图片作为输入,然后生成这张图片的输出内容。输出内容包含一个二维数组。数组的第一维包含分类索引值,第二维包含分类的置信度。根据这些值,示例应用程序在前端向用户显示排名前三的分类。

1.3.6 在iOS上使用TensorFlow Lite

现在,我们将在iOS环境下构建相同的应用程序。这个应用程序包含与Android版本相同的功能,我们还使用相同的MobileNet分类模型。这次将会在真正的iOS设备上运行应用程序,使用设备上的拍摄功能。这个应用程序在模拟器上无法正常运行。

1.前提

为了正常使用XCode,我们需要在官方网站上注册一个Apple开发者ID。这个应用程序还需要一部iPhone,因为它需要使用相机的功能。另外,还需要在指定的机器上安装配置文件。只有这样,才能在设备上构建并运行设备。

我们需要复制完整的TensorFlow仓库,但是运行这个应用程序并不需要完整的源代码。如果已经下载了代码,那么不需要重复下载。

git clone https://github.com/tensorflow/tensorflow

使用命令行工具安装XCode,代码如下。

xcode-select --install

2.构建iOS示例应用程序

如果你不熟悉iOS应用程序的构建方法,请参考相关教程。为了安装依赖项,首先需要安装cocoapods

sudo gem install cocoapods

下面是一个脚本文件,它的作用是下载运行应用程序所需的模块文件。

sh tensorflow/contrib/lite/examples/ios/download_models.sh

现在可以进入项目目录,并在命令行中安装pod。

cd tensorflow/contrib/lite/examples/ios/camera
pod install
pod update

一旦更新完成,你就会看到tflite_camera_example.xcworkspace。然后,就可以在XCode中打开应用程序。当然,也可以使用下面的命令行完成这个操作。

open tflite_camera_example.xcworkspace

现在,可以开始在iPhone上构建并运行应用程序了。

你需要允许应用程序获得使用相机的权限。使用相机对准某个对象拍照,就会看到分类结果了。