直接使用JCenter库方式:
移动设备上使用谷歌开源的深度学习框架 Tensorflow Lite,最新源码位置:
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite
要求:
Android Studio 3.0
SDK Version API25,或者API26
NDK Version 14
步骤:
1 导入tensorflow/contrib/lite/java/demo 这个项目到Studio,
2 如果没有gradle,则安装好gradle,根据Studio的提示进行安装就好(测试使用的是2.3.1)
3 下载移动端的模型(model)和标签数据(lables)(https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_224_android_quant_2017_11_08.zip)
4 下载完成解压mobilenet_v1_224_android_quant_2017_11_08.zip文件得到一个xxx.tflite和labes.txt文件,分别是模型和标签文件,并且把这两个文件复制到assets文件夹下。
5 构建app,在run一下不出意外应该是可以看到以下画面:
自行构建Tensorflow Lite demo
1 首先clone tensorflow库 (https://github.com/tensorflow/tensorflow)
2 安装构建工具Bazel (https://docs.bazel.build/versions/master/install.html)
(注:Bazel目前不支持Android的Windows上的构建。gradle/ CMake将来会被支持,在Windows预构建二进制代替。)
3 确保机器安装了Android SDK和Android NDK,如果没安装则先安装.(https://developer.android.com/tools/revisions/build-tools.html)
4 修改Tensroflow 下面的WORKSPACE 文件中的sdk和ndk指向:
Android_sdk_repository (
name = "androidsdk",
api_level = 23,
build_tools_version = "23.0.2",
path = "/home/xxxx/android-sdk-linux/", )
android_ndk_repository(
name="androidndk",
path="/home/xxxx/android-ndk-r10e/",
api_level=19)
5 用命令开始构建源代码
使用bazel 构建一个demo app :
(注意:构建app时,由于bazel 存在的bug,需要在python2 的环境中进行)
关于mobilenet_v1_224_android_quant_2017_11_08.zip模型
demo是调整每个摄像机的图像帧(224宽×224高)与量化室移动模型被使用。调整后的图像是由排尺寸1×224×224×3字节转换成一个字节缓冲区的行,其中1是在一批224×224图像的数量是3个字节的图像的宽度和高度是三种颜色的像素。本程序使用java API tensorflow Lite推理模型以单输入单输出提供。这输出一个二维数组,第一个维度是类别索引,第二个维度是分类的自信度。该室移动模型具有1001个不同的类别和应用程序类型的所有类别的概率,显示前三个可能性。
关于Tensorflow Lite
根据不同的使用情况下,可以选择使用一个流行的开源模型如inceptionv3或mobilenets,重新训练这些模型用自己的自定义数据集或甚至建立自己的自定义模型。
直接使用一个预训练好的模型
mobilenets是tensorflow移动计算机视觉模型家族,这个设计有效地提高精度并且在的资源受限的设备或嵌入式应用。mobilenets的优点是模型资源小、低延迟、低功耗模型参数来满足各种使用情况下的资源约束。他们可以建立在分类、检测、嵌入和分割类似于其他流行的大型模型,如成立以来,使用。谷歌提供了16个预训练的ImageNet分类检查用于各种尺寸的移动项目mobilenets
以上例子中使用的inception-v3:
是图像识别模型与1000类一般物体识别,达到了较高的精度,如“斑马”、“狗”、“洗碗机”。该模型采用卷积神经网络的输入图像提取的一般特点和分类的基础上的特征完全连接和softmax层。
其他预训练好的模型下载地址可以在 tensorflow/tensorflow/contrib/lite/g3doc/models.md 文件中找到。
使用inception-v3或MobileNet为自定义的数据集
上述预先训练模式已经被训练在ImageNet数据集,包括1000个预定义的类。如果这些类对给定的用例不相关或有用,则需要对模型进行再培训。这项技术被称为迁移学习,开始用一个模型已经训练上的问题,将被训练在一个类似的问题。从零开始深入学习可能需要几天时间,但是转移学习可以很快完成。为了做到这一点,开发人员需要生成与相关类标记的自定义数据集。
训练自定义模型
第二种利用已经有的网络框架训练自己的数据基本可以满足大部分需求,但是除了以上方式,也可以自定义网络模型。如:先使用python构建出深度网络,训练好以后进行数据导出,大概会有这些文件xxx.pb,xxx.ckpt等文件,可以根据这些文件转换成Lite 可用的模型xxx.tflite。具体见下文。
模型格式转换
把一个标准的tensorflow模型转换成mobileNets 。标准模型中有保护 .pb 或者 .pbtxt 图( GraphDef ) 文件。如果应用程序开发人员使用预先培训过的模型(如上面步骤1中所定义的),他们可以从这里下载一个现成的、已经转换过的模型。使用再培训(即迁移学习)或自定义模型生成的模型需要使用下面提到的步骤进行转换。
(GraphDef ) xxx.pb :一个protobuf表示tensorflow培训或计算图。这包含运算符、张量和变量定义。
(CheckPoint) xxx.ckpt:这是一个GraphDef 延伸变量,这个文件一般无法被单独解释。
(FrozenGraphDef) graphdef不含变量的子类。一个graphdef可以转换为一个冻结状态的graphdef通过CheckPoint 和graphdef转换每个变量
(TensorFlow lite model ).lite:文件是序列化flatbuffer,含tensorflow Lite算子和张量的tensorflow Lite的翻译。这是最类似于TensorFlow frozen GraphDefs冻结“图”要在TensorFlow Lite中使用此.pb GraphDef文件,我们需要包含经过训练的权重参数的CheckPoint。 .pb只包含图形的结构。 合并CheckPoint值与图形结构的过程称为“冻结”图形。
首先要确检查点文件夹存在的位置,或者也可以下载一个预先训练的模型的检查点(例如:这里是一个MobileNets的链接)。
图冻结可以使用下面的命令完成(并适当地修改参数)
bazel build tensorflow/python/tools:freeze_graph
bazel-bin/tensorflow/python/tools/freeze_graph\
--input_graph=/tmp/mobilenet_v1_224.pb \
--input_checkpoint=/tmp/checkpoints/mobilenet-10202.ckpt \
--input_binary=true --output_graph=/tmp/frozen_mobilenet_v1_224.pb \
--output_node_names=MobileNet/Predictions/Reshape_1
用户必须首先使用bazel构建freeze_graph脚本,然后运行脚本。 必须启用input_binary标志以确保protobuf以二进制格式读取和写入。 用户必须输入.pb和.ckpt文件才能冻结图形。output_node_names可能在构建模型的代码之外不明显。 找到它们的最简单方法是用graphviz或tensorboard可视化图形。
这个冻结的Graphdef现在已经准备好转换为flatbuffer格式(.lite),以便在Android或iOS上使用。 在Android用户可以使用Tensorflow Optimizing Converter工具,灵活地使用冻结graphdef的浮点或量化版本(如果有的话)。
下面是一个示例命令行,用于将冻结的Graphdef转换为“.lite”格式。Tensorflow Optimizing Converter支持浮点模型和量化模型,但是,根据是否使用FLOAT或QUANTIZED模式,需要使用不同的配置参数。
bazel build tensorflow/contrib/lite/toco:toco
bazel run --config=opt tensorflow/contrib/lite/toco:toco -- \
--input_file=(pwd)/mobilenet_v1_1.0_224/frozen_graph.pb \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--output_file=/tmp/mobilenet_v1_1.0_224.lite --inference_type=FLOAT \
--input_type=FLOAT --input_arrays=input \
--output_arrays=MobilenetV1/Predictions/Reshape_1 --input_shapes=1,224,224,3
参数说明:
input_file参数应指向包含模型体系结构的冻结GraphDef文件。
output_file参数应指向TensorFlow Lite模型文件的生成位置。
input_type和inference_type参数应设置为FLOAT,除非转换量化的模型。
设置input_array,output_array和input_shape参数有点棘手。 找到这些值最简单的方法是测试TensorBoard中的图形。 用户应该重用现有的freeze_graphstep中用于指定输出节点进行推理的参数。
请注意,也可以通过protos使用Tensorflow Optimizing Converter,可以将转换步骤整合到模型设计工作流程中,以确保模型可以轻松转换为移动推理图。 例如:
import tensorflow as tf
img = tf.placeholder(name="img", dtype=tf.float32, shape=(1, 64, 64, 3))
val = img + tf.constant([1., 2., 3.]) + tf.constant([1., 4., 4.])
out = tf.identity(val, name="out")
with tf.Session() as sess:
tflite_model = tf.contrib.lite.toco_convert(sess.graph_def, [img], [out])
open("converteds_model.tflite", "wb").write(tflite_model)