前言

深度学习在图像处理、语音识别、自然语言处理领域的应用取得了巨大成功,但是它通常在功能强大的服务器端进行运算。如果智能手机通过网络远程连接服务器,也可以利用深度学习技术,但这样可能会很慢,而且只有在设备处于良好的网络连接环境下才行,这就需要把深度学习模型迁移到智能终端。

由于智能终端CPU和内存资源有限,为了提高运算性能和内存利用率,需要对服务器端的模型进行量化处理并支持低精度算法。TensorFlow版本增加了对Android、iOS和Raspberry Pi硬件平台的支持,允许它在这些设备上执行图像分类等操作。这样就可以创建在智能手机上工作并且不需要云端每时每刻都支持的机器学习模型,带来了新的APP。

本文主要基于看花识名APP应用,讲解TensorFlow模型如何应用于Android系统;在服务器端训练TensorFlow模型,并把模型文件迁移到智能终端;TensorFlow Android开发环境构建以及应用开发API。

看花识名APP

使用AlexNet模型、Flowers数据以及Android平台构建了“看花识名”APP。TensorFlow模型对五种类型的花数据进行训练。如下图所示:

Daisy:雏菊

(点击放大图像)

Dandelion:蒲公英

(点击放大图像)

Roses:玫瑰

(点击放大图像)

Sunflowers:向日葵

(点击放大图像)

Tulips:郁金香

(点击放大图像)

在服务器上把模型训练好后,把模型文件迁移到Android平台,在手机上安装APP。使用效果如下图所示,界面上端显示的是模型识别的置信度,界面中间是要识别的花:

(点击放大图像)

TensorFlow模型如何应用于看花识名APP中,主要包括以下几个关键步骤:模型选择和应用、模型文件转换以及Android开发。如下图所示:

(点击放大图像)

(点击放大图像)

模型训练及模型文件

本章采用AlexNet模型对Flowers数据进行训练。AlexNet在2012取得了ImageNet最好成绩,top 5准确率达到80.2%。这对于传统的机器学习分类算法而言,已经相当出色。模型结构如下:

(点击放大图像)

本文采用TensorFlow官方Slim(https://github.com/tensorflow/models/tree/master/slim)AlexNet模型进行训练。

  • 首先下载Flowers数据,并转换为TFRecord格式:

    DATA_DIR=/tmp/data/flowers
    python download_and_convert_data.py --dataset_name=flowers
    --dataset_dir="${DATA_DIR}"
  • 执行模型训练,经过36618次迭代后,模型精度达到85%
    TRAIN_DIR=/tmp/data/train
    python train_image_classifier.py --train_dir=${TRAIN_DIR}
    --dataset_dir=${DATASET_DIR} --dataset_name=flowers
    --dataset_split_name=train --model_name=alexnet_v2
    --preprocessing_name=vgg
  • 生成Inference Graph的PB文件
    python export_inference_graph.py  --alsologtostderr
    --model_name=alexnet_v2 --dataset_name=flowers --dataset_dir=${DATASET_DIR}
    --output_file=alexnet_v2_inf_graph.pb
  • 结合CheckPoint文件和Inference GraphPB文件,生成Freeze Graph的PB文件
    python freeze_graph.py  --input_graph=alexnet_v2_inf_graph.pb
    --input_checkpoint= ${TRAIN_DIR}/model.ckpt-36618 --input_binary=true
    --output_graph=frozen_alexnet_v2.pb --output_node_names=alexnet_v2/fc8/squeezed
  • 对Freeze Graph的PB文件进行数据量化处理,减少模型文件的大小,生成的quantized_alexnet_v2_graph.pb为智能终端中应用的模型文件
    bazel-bin/tensorflow/tools/graph_transforms/transform_graph
    --in_graph=frozen_alexnet_v2.pb --outputs="alexnet_v2/fc8/squeezed"
    --out_graph=quantized_alexnet_v2_graph.pb --transforms='add_default_attributes
    strip_unused_nodes(type=float, shape="1,224,224,3") remove_nodes(op=Identity,
    op=CheckNumerics) fold_constants(ignore_errors=true) fold_batch_norms
    fold_old_batch_norms quantize_weights quantize_nodes
    strip_unused_nodes sort_by_execution_order'

为了减少智能终端上模型文件的大小,TensorFlow中常用的方法是对模型文件进行量化处理,本文对AlexNet CheckPoint文件进行Freeze和Quantized处理后的文件大小变化如下图所示:

(点击放大图像)

量化操作的主要思想是在模型的Inference阶段采用等价的8位整数操作代替32位的浮点数操作,替换的操作包括:卷积操作、矩阵相乘、激活函数、池化操作等。量化节点的输入、输出为浮点数,但是内部运算会通过量化计算转换为8位整数(范围为0到255)的运算,浮点数和8位量化整数的对应关系示例如下图所示:

(点击放大图像)

量化Relu操作的基本思想如下图所示:

(点击放大图像)

TensorFlow Android应用开发环境构建

在Android系统上使用TensorFlow模型做Inference依赖于两个文件libtensorflow_inference.so和libandroid_tensorflow_inference_java.jar。这两个文件可以通过下载TensorFlow源代码后,采用bazel编译出来,如下所示:

  • 下载TensorFlow源代码

    git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git

  • 下载安装Android NDK
  • 下载安装Android SDK
  • 配置tensorflow/WORKSPACE中android开发工具路径
    android_sdk_repository(name = "androidsdk", api_level = 23, build_tools_version = "25.0.2", path = "/opt/android",)
    android_ndk_repository(name="androidndk", path="/opt/android/android-ndk-r12b", api_level=14)
  • 编译libtensorflow_inference.so
    bazel build -c opt //tensorflow/contrib/android:libtensorflow_inference.so
    --crosstool_top=//external:android/crosstool --host_crosstool_top=
    @bazel_tools//tools/cpp:toolchain --cpu=armeabi-v7a
  • 编译libandroid_tensorflow_inference_java.jar
    bazel build //tensorflow/contrib/android:android_tensorflow_inference_java

TensorFlow提供了Android开发的示例框架,下面基于AlexNet模型的看花识名APP做一些相应源码的修改,并编译生成Android的安装包:

  • 基于AlexNet模型,修改Inference的输入、输出的Tensor名称

    private static final String INPUT_NAME = "input";
    private static final String OUTPUT_NAME = "alexnet_v2/fc8/squeezed";
  • 放置quantized_alexnet_v2_graph.pb和对应的labels.txt文件到assets目录下,并修改Android文件路径
    private static final String MODEL_FILE = "file:///android_asset/quantized_alexnet_v2_graph.pb";
    private static final String LABEL_FILE = "file:///android_asset/labels.txt";
  • 编译生成安装包
    bazel build -c opt //tensorflow/examples/android:tensorflow_demo
  • 拷贝tensorflow_demo.apk到手机上,并执行安装,太阳花识别效果如下图所示:

    (点击放大图像)

TensorFlow移动端应用开发API

在Android系统中执行TensorFlow Inference操作,需要调用libandroid_tensorflow_inference_java.jar中的JNI接口,主要接口如下:

  • 构建TensorFlow Inference对象,构建该对象时候会加载TensorFlow动态链接库libtensorflow_inference.so到系统中;参数assetManager为android asset管理器;参数modelFilename为TensorFlow模型文件在android_asset中的路径。

    TensorFlowInferenceInterface inferenceInterface = new
    TensorFlowInferenceInterface(assetManager, modelFilename);
  • 向TensorFlow图中加载输入数据,本App中输入数据为摄像头截取到的图片;参数inputName为TensorFlow Inference中的输入数据Tensor的名称;参数floatValues为输入图片的像素数据,进行预处理后的浮点值;[1,inputSize,inputSize,3]为裁剪后图片的大小,比如1张224*224*3的RGB图片。
    inferenceInterface.feed(inputName, floatValues, 1, inputSize, inputSize, 3);
  • 执行模型推理; outputNames为TensorFlow Inference模型中要运算Tensor的名称,本APP中为分类的Logist值。
    inferenceInterface.run(outputNames);
  • 获取模型Inference的运算结果,其中outputName为Tensor名称,参数outputs存储Tensor的运算结果。本APP中,outputs为计算得到的Logist浮点数组。
    inferenceInterface.fetch(outputName, outputs);

总结

本文基于看花识名APP,讲解了TensorFlow在Android智能终端中的应用技术。首先回顾了AlexNet模型结构,基于AlexNet的slim模型对Flowers数据进行训练;对训练后的CheckPoint数据,进行Freeze和Quantized处理,生成智能终端要用的Inference模型。然后介绍了TensorFlow Android应用开发环境的构建,编译生成TensorFlow在Android上的动态链接库以及java开发包;文章最后介绍了Inference API的使用方式。

参考文献

  1. http://www.tensorflow.org
  2. 深度学习利器:分布式TensorFlow及实例分析
  3. 深度学习利器:TensorFlow使用实战
  4. 深度学习利器:TensorFlow系统架构与高性能程序设计
  5. 深度学习利器:TensorFlow与深度卷积神经网络
  6. 深度学习利器:TensorFlow与NLP模型

深度学习利器:TensorFlow在智能终端中的应用——智能边缘计算,云端生成模型给移动端下载,然后用该模型进行预测的更多相关文章

  1. 深度学习之tensorflow框架(中)

    会话 开启会话 tf.Session用于完整的程序中 tf.InteractiveSession用于交互式上下文中的tensorflow 查看张量的值 都必须在会话里面 c_new_value=new ...

  2. 分享《机器学习实战基于Scikit-Learn和TensorFlow》中英文PDF源代码+《深度学习之TensorFlow入门原理与进阶实战》PDF+源代码

    下载:https://pan.baidu.com/s/1qKaDd9PSUUGbBQNB3tkDzw <机器学习实战:基于Scikit-Learn和TensorFlow>高清中文版PDF+ ...

  3. 深度学习利器: TensorFlow系统架构及高性能程序设计

    2015年11月9日谷歌开源了人工智能平台TensorFlow,同时成为2015年最受关注的开源项目之一.经历了从v0.1到v0.12的12个版本迭代后,谷歌于2017年2月15日发布了TensorF ...

  4. 深度学习之TensorFlow构建神经网络层

    深度学习之TensorFlow构建神经网络层 基本法 深度神经网络是一个多层次的网络模型,包含了:输入层,隐藏层和输出层,其中隐藏层是最重要也是深度最多的,通过TensorFlow,python代码可 ...

  5. 深度学习(TensorFlow)环境搭建:(三)Ubuntu16.04+CUDA8.0+cuDNN7+Anaconda4.4+Python3.6+TensorFlow1.3

    紧接着上一篇的文章<深度学习(TensorFlow)环境搭建:(二)Ubuntu16.04+1080Ti显卡驱动>,这篇文章,主要讲解如何安装CUDA+CUDNN,不过前提是我们是已经把N ...

  6. 【原创 深度学习与TensorFlow 动手实践系列 - 3】第三课:卷积神经网络 - 基础篇

    [原创 深度学习与TensorFlow 动手实践系列 - 3]第三课:卷积神经网络 - 基础篇 提纲: 1. 链式反向梯度传到 2. 卷积神经网络 - 卷积层 3. 卷积神经网络 - 功能层 4. 实 ...

  7. 深度学习(TensorFlow)环境搭建:(一)硬件选购和主机组装

    一.硬件采购 近年来,人工智能AI越来越多被人们所了解,尤其是AlphaGo的人机围棋大战之后,机器学习的热潮也随之高涨.最近,公司采购了几批设备,通过深度学习(TensorFlow)来研究金融行业相 ...

  8. 转发——谷歌云官方:一小时掌握深度学习和 TensorFlow

    转发——谷歌云官方:一小时掌握深度学习和 TensorFlow 本文转发自新智元,链接如下: http://mp.weixin.qq.com/s?__biz=MzI3MTA0MTk1MA==& ...

  9. Ubuntu16.04搭建深度学习框架——TensorFlow

    TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库,说白了,就是一个库. 小编自己在Ubuntu搭建了深度学习框架TensorFlow,感觉挺简单,现 ...

随机推荐

  1. 【java并发】(1)深入理解volatile关键字

    volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...

  2. 实现Brush对象的五种图形

    本实例将使用Graphics类绘制五种图形来分别演示SolidBrush.HatchBrush.TextureBrush.LinearGradientBrush.PathGradientBrush这五 ...

  3. 【转载】linux环境下大数据网站搬家

    这里说的大数据是指你的网站数据库大小至少超过了500M,当然只有50M的网站也同样可以用这样的方法来轻松安全的实现网站搬家,前提是你使用的是linux环境下的VPS或者独立服务器. 我们假设你的网站域 ...

  4. Deutsch lernen (13)

    1.  die Sicherheit, -en  安全(性) Was ist Ihnen wichtiger: Freiheit oder Sicherheit? Wie ist es mit der ...

  5. Arduino LM35温度检测

    一. 接线原理图 二.实物图 三.代码例子

  6. Dispatch Queues and Thread Safety

    Dispatch Queues and Thread Safety It might seem odd to talk about thread safety in the context of di ...

  7. Unicode转换为UTF-8过程Demo

    碎碎念:这几天在学习Python对Unicode的支持 上学的时候,计算机基础课上总能听到老师讲什么字节,字符,Unicode,UTF-8吧啦吧啦一堆,反正我是只记住了名字,至于具体这些名字所表达的含 ...

  8. 01 DOS常用命令

    有时候没有可视化窗口,命令行对文件进行操作更方便快捷 cmd 命令弹出 dir 查看当前所在目录下的文件 ctrl+c 退出 \a 显示隐藏文件 cd /改变到根目录 dir /a 显示隐藏文件 di ...

  9. tomcat8版本实现虚拟主机

    vim /etc/hosts192.168.30.21   www.crushlinux.com192.168.30.21   www.cloud.com [root@localhost ~]# cd ...

  10. 【转载】深入理解Java的接口和抽象类

    深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...