承接移动端目标识别(2)
使用TensorFlow Lite在移动设备上运行
在本节中,我们将向您展示如何使用TensorFlow Lite获得更小的模型,并允许您利用针对移动设备优化的操作。
TensorFlow Lite是TensorFlow针对移动和嵌入式设备的轻量级解决方案。它支持端上的机器学习推理,具有低延迟和小二进制模型大小。
TensorFlow Lite使用了许多技术,例如允许更小和更快(定点数学)模型的量化内核。
对于本节,您需要从源代码构建TensorFlow以获得对SSD模型的TensorFlow Lite支持。您还需要安装bazel构建工具。
(好像我以前博客有教程,不过网上的编译还是可能有各种问题,解决问题也算是base skill吧,多动手!)
为了使这些命令更容易运行,让我们设置一些环境变量:(设置环境变量,而不把一些变量直接写在代码里面也是安全和规范的方式)
export CONFIG_FILE=PATH_TO_BE_CONFIGURED/pipeline.config # pipeline.config 是使用tensorflow models object detection api中要配置的 export CHECKPOINT_PATH=PATH_TO_BE_CONFIGURED/model.ckpt # 训练后保存的模型文件。(我比较奇怪的是,这在pipeline.config中不是有的吗,可能还得继续往后看才知道。) export OUTPUT_DIR=/tmp/tflite # 输出的文件 这里的pipeline.config 我们选择:ssdlite_mobilenet_v2_coco.config (其实,下载model zoom里面ssdlite_mobilenet_v2_coco 有pipeline.config,我后面也用这个)这里的model.ckpt我们从model zoom里面(就不用自己的模型啦)选择和pipeline对应的:ssdlite_mobilenet_v2_coco http://download.tensorflow.org/models/object_detection/ssdlite_mobilenet_v2_coco_2018_05_09.tar.gzmodel zoom :https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.mdoutput 就默认吧。
我们从一个检查点开始,获得一个TensorFlow冻结图,其中包含我们可以与TensorFlow Lite一起使用的兼容操作。
首先,您需要安装这些python库。然后,要获取冻结图,请使用以下命令从models / research目录运行export_tflite_ssd_graph.py脚本(为此我还红专门从源代码编译安装将tensorflow 1.3升级1.9):
object_detection/export_tflite_ssd_graph.py --pipeline_config_path=$CONFIG_FILE --trained_checkpoint_prefix=$CHECKPOINT_PATH --output_directory=$OUTPUT_DIR --add_postprocessing_op=true 在/tmp/tflite目录中,我们现在应该看到两个文件:tflite_graph.pb(18.5MB)和tflite_graph.pbtxt(53.1MB)。请注意,add_postprocessing标志使模型能够利用自定义优化的检测后处理操作,该操作可以被视为替换tf.image.non_max_suppression。确保不要将在同一目录中的export_tflite_ssd_graph与export_inference_graph混淆。两个脚本都输出冻结的图形:export_tflite_ssd_graph将输出我们可以直接输入到TensorFlow Lite的冻结(frozen)图形,并且是我们将要使用的图形。 接下来,我们将通过使用TensorFlow Lite优化转换器TOCO来获得TensorFlow Lite优化模型。这将通过以下命令将生成的冻结图形(tflite_graph.pb)转换为TensorFlow Lite flatbuffer format(detect.tflite)。
对于量化模型,请从tensorflow /目录(就是源码编译的那个目录)运行(注意要使用bazel-0.12或以上的编译,我之前就是没有source ~/.bashrc 导致一直用的是bazel-0.5.4报错了。可以用bazel version看版本。):
bazel run --config=opt tensorflow/contrib/lite/toco:toco -- --input_file=$OUTPUT_DIR/tflite_graph.pb --output_file=$OUTPUT_DIR/detect.tflite --input_shapes=1,300,300,3 --input_arrays=normalized_input_image_tensor --output_arrays=‘TFLite_Detection_PostProcess‘,‘TFLite_Detection_PostProcess:1‘,‘TFLite_Detection_PostProcess:2‘,‘TFLite_Detection_PostProcess:3‘ --inference_type=QUANTIZED_UINT8 --mean_values=128 --std_values=128 --change_concat_input_ranges=false --allow_custom_ops 然后就进入漫长的编译等待(一般是第一次编译耗时,后面再运行就不会了)。其实,tensorflow也是根据需要的操作opeater进行编译的
INFO: Build completed successfully, 3249 total actions
2018-07-28 19:41:25.155435: I tensorflow/contrib/lite/toco/import_tensorflow.cc:1366] Converting unsupported operation: TFLite_Detection_PostProcess
2018-07-28 19:41:25.165617: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Before Removing unused ops: 1070 operators, 1570 arrays (0 quantized)
2018-07-28 19:41:25.194800: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Before general graph transformations: 1070 operators, 1570 arrays (0 quantized)
2018-07-28 19:41:25.224629: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] After general graph transformations pass 1: 116 operators, 310 arrays (1 quantized)
2018-07-28 19:41:25.226254: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Before pre-quantization graph transformations: 116 operators, 310 arrays (1 quantized)
2018-07-28 19:41:25.227209: F tensorflow/contrib/lite/toco/tooling_util.cc:1589] Array FeatureExtractor/MobilenetV2/Conv/Relu6, which is an input to the DepthwiseConv operator producing the output array FeatureExtractor/MobilenetV2/expanded_conv/depthwise/Relu6, is lacking min/max data, which is necessary for quantization. Either target a non-quantized output format, or change the input graph to contain min/max information, or pass --default_ranges_min= and --default_ranges_max= if you do not care about the accuracy of results.
Aborted (core dumped)
此命令设置每个摄像机图像帧调整为300x300像素后,并输入张量normalized_input_image_tensor。量化模型的输出被命名 ‘TFLite_Detection_PostProcess‘, ‘TFLite_Detection_PostProcess:1‘, ‘TFLite_Detection_PostProcess:2‘, and ‘TFLite_Detection_PostProcess:3‘ 并表示四个数组:detection_boxes,detection_classes,detection_scores和num_detections。此命令中使用的其他标志的文档在此处:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/toco/g3doc/cmdline_reference.md。如果成功运行,您现在应该在/tmp/tflite目录中看到第三个文件名为detect.tflite(然后,发现是 0 bytes,什么情况??,不过unint8不行,下面float是可以的)。此文件包含图形和所有模型参数,可以通过Android设备上的TensorFlow Lite解释程序运行。对于浮点模型,请从tensorflow /目录运行:
bazel run --config=opt tensorflow/contrib/lite/toco:toco -- --input_file=$OUTPUT_DIR/tflite_graph.pb --output_file=$OUTPUT_DIR/detect.tflite --input_shapes=1,300,300,3 --input_arrays=normalized_input_image_tensor --output_arrays=‘TFLite_Detection_PostProcess‘,‘TFLite_Detection_PostProcess:1‘,‘TFLite_Detection_PostProcess:2‘,‘TFLite_Detection_PostProcess:3‘ --inference_type=FLOAT --allow_custom_ops 然后输出的detect.tflite (18MB)
在Android上运行我们的模型 要在设备上运行我们的TensorFlow Lite模型,我们需要安装Android NDK和SDK。目前推荐的Android NDK版本为14b,可以在NDK Archives页面上找到(https://developer.android.com/ndk/downloads/older_releases.html#ndk-14b-downloads)。Android SDK和构建工具可以单独下载,也可以作为Android Studio的一部分使用。要构建TensorFlow Lite Android演示,构建工具需要API> = 23(但它将在API> = 21的设备上运行)。其他详细信息可在TensorFlow Lite Android App页面上找到。接下来,我们需要将应用程序指向新的detect.tflite文件,并为其指定新标签的名称。具体来说,我们将使用以下命令将TensorFlow Lite flatbuffer 复制到app 资源目录: cp /tmp/tflite/detect.tflite tensorflow/contrib/lite/java/demo/app/src/main/assets/
(官网上面是:cp /tmp/tflite/detect.tflite //tensorflow/contrib/lite/examples/android/app/src/main/assets ) 我们还需要将新的labelmap labels_list.txt复制到assets目录,这里就直接用已经有的labels_mobilenet_quant_v1_224.txt。 我们现在将编辑BUILD文件以指向这个新模型。首先,打开BUILD文件tensorflow/contrib/lite/examples/android/BUILD。然后找到assets部分,并替换该行,“@tflite_mobilenet_ssd_quant//detect.tflite”(默认情况下指向COCO预训练模型带有新TFLite模型的路径“tensorflow/contrib/lite/examples/android/assets/detect.tflite”。最后,更改assets部分以使用新的标签映射(这个我没改哈)。 我们还需要告诉我们的应用程序使用新的标签映射。为此,在文本编辑器中打开tensorflow/contrib/lite/examples/android/src/org/tensorflow/demo/DetectorActivity.java文件,找到TF_OD_API_LABELS_FILE的定义。更新此路径以指向新的标签映射文件:“file///android_asset/labels_list.txt”。(没有就不用改这个操作,我没改)请注意,如果量化了模型,则标志TF_OD_API_IS_QUANTIZED设置为true,如果模型是浮点,则标志TF_OD_API_IS_QUANTIZED设置为false(没有找到这个flag,估计是后面改掉了)。现在,对于量化模型,DetectorActivity.java的这一新部分应如下所示:
private static final boolean TF_OD_API_IS_QUANTIZED = true;(没有找到,就不处理) private static final String TF_OD_API_MODEL_FILE = "detect.tflite"; private static final String TF_OD_API_LABELS_FILE = "file:///android_asset/labels_list.txt";(这个我保留原样"file:///android_asset/coco_labels_list.txt")
复制TensorFlow Lite文件并编辑BUILD和DetectorActivity.java文件后,您可以构建演示应用程序,从tensorflow目录运行此bazel命令:
bazel build -c opt --config=android_arm{,64} --cxxopt=‘--std=c++11‘ "//tensorflow/contrib/lite/examples/android:tflite_demo"然后报错了:bazel build -c opt --config=android_arm{,64} --cxxopt=‘--std=c++11‘ "//tensorflow/contrib/lite/examples/android:tflite_demo"WARNING: The following configs were expanded more than once: [android, cross_compile]. For repeatable flags, repeats are counted twice and may lead to unexpected behavior.WARNING: option ‘--crosstool_top‘ was expanded to from both option ‘--config=cuda‘ (source /home/lyz/code/tensorflow/.tf_configure.bazelrc) and option ‘--config=android_arm‘ (source command line options)WARNING: option ‘--cpu‘ was expanded to from both option ‘--config=android_arm‘ (source command line options) and option ‘--config=android_arm64‘ (source command line options)WARNING: option ‘--fat_apk_cpu‘ was expanded to from both option ‘--config=android_arm‘ (source command line options) and option ‘--config=android_arm64‘ (source command line options)ERROR: No default_toolchain found for cpu ‘arm64-v8a‘. Valid cpus are: [ k8, local, armeabi-v7a, x64_windows, x64_windows_msvc, x64_windows_msys, s390x, ios_x86_64,]将命令修改为(android知识不太懂,但是我的手机可以armeabi-v7a): bazel build -c opt --config=armeabi-v7a --cxxopt=‘--std=c++11‘ "//tensorflow/contrib/lite/examples/android:tflite_demo"还是报错:~/code/tensorflow$ bazel build -c opt --config=armeabi-v7a --cxxopt=‘--std=c++11‘ "//tensorflow/contrib/lite/examples/android:tflite_demo"INFO: Options provided by the client: Inherited ‘common‘ options: --isatty=1 --terminal_columns=102INFO: Reading rc options for ‘build‘ from /home/lyz/code/tensorflow/tools/bazel.rc: ‘build‘ options: --distinct_host_configuration=false --define framework_shared_object=true --define=use_fast_cpp_protos=true \--define=allow_oversize_protos=true --define=grpc_no_ares=true --spawn_strategy=standalone --genrule_strategy=standalone -c optINFO: Reading rc options for ‘build‘ from /etc/bazel.bazelrc: ‘build‘ options: --action_env=PATH --action_env=LD_LIBRARY_PATH --action_env=TMPDIR --test_env=PATH --test_env=LD_LIBRARY_PATHINFO: Reading rc options for ‘build‘ from /home/lyz/code/tensorflow/.tf_configure.bazelrc: ‘build‘ options: --action_env PYTHON_BIN_PATH=/usr/bin/python --action_env PYTHON_LIB_PATH=/usr/lib/python2.7/dist-packages --python_path=/usr/bin/python \ --define with_jemalloc=true --define with_gcp_support=true --action_env TF_NEED_OPENCL_SYCL=0 --action_env TF_NEED_CUDA=1 \--action_env CUDA_TOOLKIT_PATH=/usr/local/cuda-8.0 --action_env TF_CUDA_VERSION=8.0 --action_env CUDNN_INSTALL_PATH=/usr/local/cuda-8.0 \--action_env TF_CUDNN_VERSION=6 --action_env TF_NCCL_VERSION=1 --action_env TF_CUDA_COMPUTE_CAPABILITIES=5.2,5.2 \--action_env LD_LIBRARY_PATH=:/usr/local/cuda/lib64 --action_env TF_CUDA_CLANG=0 --action_env GCC_HOST_COMPILER_PATH=/usr/bin/gcc \--config=cuda --define grpc_no_ares=true --strip=alwaysINFO: Found applicable config definition build:cuda in file /home/lyz/code/tensorflow/tools/bazel.rc: [email protected]_config_cuda//crosstool:toolchain 、--define=using_cuda=true --define=using_cuda_nvcc=trueERROR: Config value armeabi-v7a is not defined in any .rc file 现在通过(其实还没成功...)Android Debug Bridge(adb)在支持调试的Android手机上安装演示:
adb install bazel-bin/tensorflow/contrib/lite/examples/android/tflite_demo.apk
-------------------------------------------------------------------------------------------------------------------这里暂时hold住。 上面就是https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/running_on_mobile_tensorflowlite.md 的内容了,但是还是报错,就说明缺少了一些配置。因为报错信息是:ERROR: Config value armeabi-v7a is not defined in any .rc file,回到之前tensorflow lite的介绍,并找到Android Demo App:https://www.tensorflow.org/mobile/tflite/demo_android?hl=zh-cn Android演示应用 GitHub上提供了使用TensorFLow Lite的示例Android应用程序(https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/java/demo)。该演示是一个示例相机应用程序,使用量化的Mobilenet模型或浮点Inception-v3模型连续分类图像。要运行演示,需要运行Android 5.0(API 21)或更高版本的设备。 在演示应用程序中,使用TensorFlow Lite Java API进行推理。该演示应用程序实时对帧进行分类,显示最可能的分类。它还显示检测对象所用的时间。将演示应用程序添加到您的设备有三种方法: 1、下载预编译好的二进制APK。(http://download.tensorflow.org/deps/tflite/TfLiteCameraDemo.apk?hl=zh-cn) 2、使用Android Studio构建应用程序。 3、下载TensorFlow Lite的源代码和演示,并使用bazel构建它。 下载预先构建的二进制文件:尝试演示的最简单方法是下载预先构建的二进制APK。安装APK后,单击应用程序图标以启动该程序。第一次打开应用程序时,它会要求运行时权限以访问设备相机。演示应用程序打开设备的后置摄像头,识别摄像机视野中的物体。在图像的底部(如果设备处于横向模式,则位于图像的左侧),它显示分类的前三个对象和分类延迟。 使用JCenter的TensorFlow Lite AAR在Android Studio中构建:使用Android Studio尝试更改项目代码并编译演示应用程序: × 安装最新版本的Android Studio。 × 确保Android SDK版本大于26且NDK版本大于14(在Android Studio设置中)。 × 将tensorflow/contrib/lite/java/demo目录导入为新的Android Studio项目。 × 安装它请求的所有Gradle扩展。 现在您可以构建并运行演示应用程序。构建过程下载量化的Mobilenet TensorFlow Lite模型,并将其解压缩到assets目录:tensorflow/contrib/lite/java/demo/app/src/main/assets/。TF Lite Android App页面上提供了一些其他详细信息(https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/java/demo/README.md)。
报错信息为:
ERROR: /home/xxxx/code/tensorflow/third_party/clang_toolchain/cc_configure_clang.bzl:3:1: file ‘@bazel_tools//tools/cpp:cc_configure.bzl‘ does not contain symbol ‘cc_autoconf_impl‘
ERROR: error loading package ‘‘: Extension file ‘third_party/clang_toolchain/cc_configure_clang.bzl‘ has errors
ERROR: error loading package ‘‘: Extension file ‘third_party/clang_toolchain/cc_configure_clang.bzl‘ has errors
解决方案是:这是bazel版本的问题,参考这个:https://github.com/tensorflow/serving/issues/851,装过bazel 版本即可.
经过最后测试,是代码的问题,代码升级到最新,按照官网是可以的,接下来就是模型调整,压缩设计的问题了,可以开启落地之路啦
原文地址:https://www.cnblogs.com/YouXiangLiThon/p/9382700.html