最近一直在考虑在Android系统上做一些AI的项目,但现在的AI项目大多数采用Python语言。在网上搜了一些移动端AI的例子,觉得Google的TensorFlow Lite比较适合。看到这样一篇介绍Android上的TensorFlow Lite的文章,翻译出来和大家分享。
什么是TensorFlow Lite?
TensorFlow Lite是TensorFlow针对移动和嵌入式设备的轻量级解决方案。它可以在移动设备上高效运行机器学习模型,因此您可以利用这些模型进行分类、回归或其他功能,而无需和服务器交互。
目前它在Android和iOS上支持C++ API,并为Android开发人员提供Java Wrapper。另外,在支持它的Android设备上,解释器也可以使用Android神经网络API进行硬件加速,否则默认在CPU上执行。 在本文中,我将重点介绍如何在Android应用中使用它。
TensorFlow Lite包含一个运行时,在上面可以运行预先训练好的模型,还包含一套工具,您可以使用这些工具准备用于移动设备和嵌入式设备上的模型。
TensorFlow上还无法训练模型,您需要在更高性能的机器上训练模型,然后将该模型转换为.TFLITE格式,将其加载到移动端的解释器中。
TensorFlow Lite目前处于开发人员预览版,因此它可能不支持TensorFlow模型中的所有操作。 尽管如此,它仍然可以与常见的图像分类模型(包括Inception和MobileNets)一起工作。在本文中,您将看到在Android上运行MobileNet模型。该应用将接收摄像头数据,使用训练好的MobileNet对图片中的主体图像进行分类。
TensorFlow Lite中使用MobileNet
例如,在这幅图像中,我将相机指向了我最喜爱的咖啡杯,可以看到它主要被分类为“杯子”。考虑到其形状,很容易理解! 令人感兴趣的是,它有一个很大、很宽的手柄,也很像茶壶!
这是如何工作的? 它使用MobileNet模型,该模型针对移动设备上的多种图像场景进行设计和优化,包括对象检测、分类、面部属性检测和地标识别。
MobileNet有多种变体,该网站(https://goo.gl/tvaiY9)托管着许多TensorFlow Lite的训练模型。 您会注意到每个文件都是一个包含两个文件的zip文件 - 一个labels.txt文件,其中包含模型所训练的标签以及一个.tflite文件,其中包含可与TensorFlow Lite配合使用的模型。如果您想照着构建使用MobileNets的Android应用,则需要从此网站下载模型。稍后你会了解到这一过程。
您可以在此视频中了解有关TensorFlow Lite的更多信息:
构建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示例 (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/java/demo/app/src/main/java/com/example/android/tflitecamerademo/ImageClassifier.java) 中有一个辅助函数。只需确保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上有完成此操作的完整示例。深入到这个示例中,您可以看到它如何从相机中抓取、准备用于分类的数据,并通过将加权输出优先级列表映射模型到标签数组来处理输出。
您可以在此视频中了解有关构建TensorFlow Lite Android应用程序的更多信息:
获取并运行Android示例
要运行该示例,请确保您有完整的TensorFlow源码。 您可以使用命令:
git clone https://www.github.com/tensorflow/tensorflow
完成之后,您可以在Android Studio中打开的TensorFlow示例项目的/tensorflow/contrib/lite/java/demo文件夹:
该示例代码不包含任何模型,但示例需要mobilenet_quant_v1_224.tflite文件,因此请务必从该站点 (https://goo.gl/tvaiY9) 下载模型。解压并将其放入assets文件夹中。[注: 从该站点下载的模型文件命名稍微有些不同,你可能需要修改源码ImageClassifierQuantizedMobileNet.java,或者直接从https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_224_android_quant_2017_11_08.zip 下载]
现在您应该可以运行该应用程序。
请注意,该应用程序可支持初始(Inception)和量化(Quantized )的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个类的列表及其权重的文本。