深度学习利器:TensorFlow在智能终端中的应用——智能边缘计算,云端生成模型给移动端下载,然后用该模型进行预测
前言
深度学习在图像处理、语音识别、自然语言处理领域的应用取得了巨大成功,但是它通常在功能强大的服务器端进行运算。如果智能手机通过网络远程连接服务器,也可以利用深度学习技术,但这样可能会很慢,而且只有在设备处于良好的网络连接环境下才行,这就需要把深度学习模型迁移到智能终端。
由于智能终端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的使用方式。
参考文献
- http://www.tensorflow.org
- 深度学习利器:分布式TensorFlow及实例分析
- 深度学习利器:TensorFlow使用实战
- 深度学习利器:TensorFlow系统架构与高性能程序设计
- 深度学习利器:TensorFlow与深度卷积神经网络
- 深度学习利器:TensorFlow与NLP模型
深度学习利器:TensorFlow在智能终端中的应用——智能边缘计算,云端生成模型给移动端下载,然后用该模型进行预测的更多相关文章
- 深度学习之tensorflow框架(中)
会话 开启会话 tf.Session用于完整的程序中 tf.InteractiveSession用于交互式上下文中的tensorflow 查看张量的值 都必须在会话里面 c_new_value=new ...
- 分享《机器学习实战基于Scikit-Learn和TensorFlow》中英文PDF源代码+《深度学习之TensorFlow入门原理与进阶实战》PDF+源代码
下载:https://pan.baidu.com/s/1qKaDd9PSUUGbBQNB3tkDzw <机器学习实战:基于Scikit-Learn和TensorFlow>高清中文版PDF+ ...
- 深度学习利器: TensorFlow系统架构及高性能程序设计
2015年11月9日谷歌开源了人工智能平台TensorFlow,同时成为2015年最受关注的开源项目之一.经历了从v0.1到v0.12的12个版本迭代后,谷歌于2017年2月15日发布了TensorF ...
- 深度学习之TensorFlow构建神经网络层
深度学习之TensorFlow构建神经网络层 基本法 深度神经网络是一个多层次的网络模型,包含了:输入层,隐藏层和输出层,其中隐藏层是最重要也是深度最多的,通过TensorFlow,python代码可 ...
- 深度学习(TensorFlow)环境搭建:(三)Ubuntu16.04+CUDA8.0+cuDNN7+Anaconda4.4+Python3.6+TensorFlow1.3
紧接着上一篇的文章<深度学习(TensorFlow)环境搭建:(二)Ubuntu16.04+1080Ti显卡驱动>,这篇文章,主要讲解如何安装CUDA+CUDNN,不过前提是我们是已经把N ...
- 【原创 深度学习与TensorFlow 动手实践系列 - 3】第三课:卷积神经网络 - 基础篇
[原创 深度学习与TensorFlow 动手实践系列 - 3]第三课:卷积神经网络 - 基础篇 提纲: 1. 链式反向梯度传到 2. 卷积神经网络 - 卷积层 3. 卷积神经网络 - 功能层 4. 实 ...
- 深度学习(TensorFlow)环境搭建:(一)硬件选购和主机组装
一.硬件采购 近年来,人工智能AI越来越多被人们所了解,尤其是AlphaGo的人机围棋大战之后,机器学习的热潮也随之高涨.最近,公司采购了几批设备,通过深度学习(TensorFlow)来研究金融行业相 ...
- 转发——谷歌云官方:一小时掌握深度学习和 TensorFlow
转发——谷歌云官方:一小时掌握深度学习和 TensorFlow 本文转发自新智元,链接如下: http://mp.weixin.qq.com/s?__biz=MzI3MTA0MTk1MA==& ...
- Ubuntu16.04搭建深度学习框架——TensorFlow
TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库,说白了,就是一个库. 小编自己在Ubuntu搭建了深度学习框架TensorFlow,感觉挺简单,现 ...
随机推荐
- 安装sql server 2008 R2出现 创建usersettings/microsoft.sqlserver.configuration.landingpage.properties.setter
造成这个原因是由于先装了VS(我之前安装的是vs2012)开发环境造成的,需要删除 路径为 C:\Users\Administrator\AppData\Local\Microsoft_Corpora ...
- 复习java基础第二天(异常处理)
一.常见的异常类型: public class TestException { public static void main(String[] args) { int i = 10; //数学异常: ...
- SLAM: 图像角点检测的Fast算法(时间阈值实验)
作为角点检测的一种快速方法,FastCornerDetect算法比Harris方法.SIft方法都要快一些,应用于实时性要求较高的场合,可以直接应用于SLAM的随机匹配过程.算法来源于2006年的Ed ...
- 在 ef 中执行 DbContext.Table.AddRange(Enitites).ToList() 会发生什么
在 ef 中执行 DbContext.Table.AddRange(Enitites).ToList() 会发生什么 昨天和朋友摸鱼,无意之间聊到了执行 DbContext.Table.AddRang ...
- 【C++】颜色的设置
1.改变整个控制台的颜色用 system("color 0A"); 其中color后面的0是背景色代号,A是前景色代号.各颜色代码如下: 0=黑色 1=蓝色 2=绿色 3=湖蓝色 ...
- 【ng-zorro-antd】加入in-memory-web-api插件后icon不显示
在ng-zorro-antd框架下,根据angular的技术文档demo,加入in-memory-web-api后icon不显示 解决方案: 在app.module.ts中的imports:[]加入 ...
- cocos creator 底部按钮touch延迟
cocos论坛里有这个问题: http://forum.cocos.com/t/ios-touchstart-bug/63367我的引擎版本:"engine_version": & ...
- [Java]链表的打印,反转与删除
class Node{ public int value; public Node next=null; public Node(int value) { this.value=value; } }p ...
- eas之kdtable格式化
设置表.列.行或单元的格式化字符串 // 设置表table.getStyleAttributes().setNumberFormat(formatString); // 设置列column.getSt ...
- vue: This relative module was not found
这是今天运行vue项目报的一个错误,特地在此记录一下. 错误信息如下: ERROR Failed to compile with 1 errors This relative module was n ...