【免费教学】Tensorflow Lite极简入门

边缘计算时代离我们越来越近,当前嵌入式设备的智能框架还是 TensorFlow Lite比较成熟,这里我准备用一系列免费课程和大家一起讨论下 TensorFlow Lite在移动设备上的应用,让我们的设备智能起来。

我们先来看下 YouTube 上开通的TensorFlow 视频频道的一段视频:

视频内容

TensorFlow Lite 介绍

TensorFlow Lite 的目标是移动和嵌入式设备,它赋予了这些设备在终端本地运行机器学习模型的能力,从而不再需要向云端服务器发送数据。这样一来,不但节省了网络流量、减少了时间开销,而且还充分帮助用户保护自己的隐私和敏感信息。TensorFlow Lite 目前仍处于“积极开发”状态,目前仅有少量预训练AI模型面世,比如MobileNet、用于计算机视觉物体识别的Inception v3、用于自然语言处理的Smart Reply,当然,TensorFlow Lite上也可以部署用自己的数据集定制化训练的模型。

TensorFlow Lite可以与Android 8.1中发布的神经网络API完美配合,即便在没有硬件加速时也能调用CPU处理,确保模型在不同设备上的运行。

模型相关的文件

模型相关的文件有很多类型,比如:Graph Definition, Checkpoints 以及 Frozen Graph。各种类型的数据都需要使用 Protocol Buffers(简称 ProtoBuff)来定义数据结构,有了这些 ProtoBuff 代码,你就可以使用工具来生成对应的 C 和 Python 或者其它语言的代码,方便装载、保存和使用数据。

ProtoBuff 的相关内容,可以从这个网址得到:

https://developers.google.cn/protocol-buffers/

Graph Def

关于 Graph Def(Graph Definition)文件,有两种格式。拓展名为 .pb 的是二进制 binary 文件;而 .pbtxt 格式的则是更具可读性的文本文件。但是,实际使用中,二进制文件有着相当高的执行效率和内存优势。

Graph Def 是你训练的模型的核心,它定义了 node 的关系结构,方便由其他的进程来读取。比如下面这个 Graph Def 就定义了“矩阵 A 与矩阵 B 相乘得到矩阵 C”的描述。

node {
  name: "a"
  op: "matmul"
}

node {
  name: "b"
  op: "matmul"
  input: "a:0"
}

node {
  name: "c"
  op: "matmul"
  input: "a:0"
  output: "b:0"
}

Checkpoint

Checkpoint 文件是来自 TensorFlow 图的序列化变量。这个文件当中没有图的结构,所以不会被解释。在训练学习的过程中,Checkpoint 文件记录了不同的 Iteration 中变量的取值。

Frozen Graph

用 Graph Def 和 Checkpoint 生成 Frozen Graph 的过程叫做“冷冻”。为什么称之为冷冻呢?我们知道,生成 Frozen Graph 所需要的量都是从 Checkpoint 当中得到的,那么这个变量转为常量的过程就被形象地称之为“冷冻”了。

TensorFlow Lite 模型

TensorFlow Lite 所用的模型是使用 TOCO 工具从 TensorFlow 模型转化而来的,来源就是经过冷冻生成的 Frozen Graph。假如你已经得到了一个“够用”的模型了,而且你也没有源代码或者数据来重新进行训练,那么就使用当前的模型吧,没有任何问题。但如果你有源代码和数据,直接使用 TOCO 工具进行模型转化将会是最好的选择。示例代码如下:

with tf.Session() as sess:
  tflite_model = tf.contrib.lite.toco_convert(sess.graph_def, [img], [out])
  open("converted_model.tflite","wb").write(tflite_model)

TensorFlow Lite 兼容的公开模型

视频中提到的兼容性指南的链接为:

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/g3doc/tf_ops_compatibility.md

在 TensorFlow Lite 中兼容的模型是 Inception v3 和 MobileNets,Inception v3 主要用于验证 ImageNet 数据集,这是一个被学界广泛认定为图片验证指标的数据集。MobileNets 则是转为移动设备而设计的模型,具有低能耗的特征,但相应的缺点就是准确度不如 Inception v3。

  • 第一部分,如何用 MobileNets 对图像分类:

https://codelabs.tensorflowers.cn/codelabs/tensorflow-for-poets/index.html

  • 第二部分,如何将第一部分生成的模型构建成一个 APK:

https://codelabs.tensorflowers.cn/codelabs/tensorflow-for-poets-2/index.html

现在我们对 TensorFlow Lite 的概念和模型转化有了认识,接下来讲述 TensorFlow Lite 模型文件格式,并可视化以帮助大家记忆理解,也包含 TensorFlow Lite 的具体加载运行过程,并给出关键的数据结构描述,我们先来看段视频:

视频内容

看完视频,我们一起总结回顾一下:

首先,我们需要在PC上设计、训练出目标模型,并将其转化成 TensorFlow Lite 的格式。接着,此格式文件在 TensorFlow Lite 中会被内置了 Neon 指令集的解析器加载到内存,并执行相应的计算。由于 TensorFlow Lite 对硬件加速接口良好的支持,开发者可以设计出性能更优的 App 供用户使用。

我们先来看下关键的数据结构描述:

模型文件格式

Model 结构体:模型的主结构

table Model {
    version: uint;
    operator_codes: [OperatorCode];
    subgraphs: [SubGraph];

    description: string;
    buffers: [Buffer]
}

其中operator_codes 定义了整个模型的所有算子,subgraphs 定义了所有的子图。子图当中,第一个元素是主图。buffers 属性则是数据存储区域,主要存储的是模型的权重信息。

SubGraph 结构体:Model 中最重要的部分

table SubGraph {
    tensors: [Tensor];
    inputs: [int];
    outputs: [int];
    operators: [Operator];

    name: string;
}

tensors 定义了子图的各个 Tensor,inputsoutputs 用索引的维护着子图中 Tensor 与输入输出之间的对应关系。operators 定义了子图当中的算子。

Tensor 结构体:包含维度、数据类型、Buffer 位置等信息

table Tensor {
    shape: [int];
    type: TensorType;
    buffer: uint;

    name: string;
}

buffer 以索引量的形式,给出了这个 Tensor 需要用到子图的哪一个 buffer。

Operator 结构体:SubGraph 中最重要的结构体

table Operator {
    opcode_index: uint;
    inputs: [int];
    outputs: [int];

    ...
}

opcode_index 用索引方式指明该 Operator 对应了哪个算子。 inputsoutputs 则是 Tensor 的索引值,指明该 Operator 的输入输出信息。

解析器概况

那么 TensorFlow Lite 的解析器又是如何工作的呢?

一开始,终端设备会通过 mmap 以内存映射的形式将模型文件载入客户端内存中,其中包含了所有的 Tensor,Operator 和 Buffer 等信息。出于数据使用的需要,TensorFlow Lite 会同时创建 Buffer 的只读区域和分配可写 Buffer 区域。

由于解析器中包含了集体执行计算的代码,这一部分被称为 Kernel。模型中的各个 Tensor 会被加载为 TfLiteTensor 的格式并集中存放在 TfLiteContext 中。

每个 Tensor 的指针都指向了内存中的只读 Buffer 区域或是一开始新分配的可写入 Buffer 区域。

模型中的 Operator 被重新加载为 TfLiteNode,它包含输入输出的 Tensor 索引值。这些 Node 对应的操作符存储于 TfLiteRegistration 中,它包含了指向 Kernel 的函数指针。OpResolver 负责维护函数指针的对应关系。

TensorFlow Lite 加载模型的过程中会确定执行 Node 的顺序,然后依次执行。

大家如果想要更好掌握 TensorFlow Lite 的技术细节,一定要阅读以下文件:

  • lite/context.h
  • lite/model.h
  • lite/interpreter.h
  • lite/kernels/register.h

其他

TensorFlow Lite 的代码位置

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite

模型的模式文件位于:

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/schema/schema.fbs

原文发布于微信公众号 - 人人都是极客(rrgeek)

原文发表时间:2018-06-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AI研习社

自动文本摘要

摘要的主要思想是找到包含整个集合的“信息”的数据子集。这种技术在今天的工业中被广泛使用。搜索引擎就是一个例子;其他的例子包括文档、图像集合和视频的汇总。文档摘要...

3801
来自专栏Spark学习技巧

复习:聊聊hive随机采样①

数据量大的时候,对数据进行采样,然后再做模型分析。作为数据仓库的必备品hive,我们如何对其进行采样呢?

2603
来自专栏机器学习算法工程师

深入理解TensorFlow中的tf.metrics算子

本文翻译自Avoiding headaches with tf.metrics,原作者保留版权。

3802
来自专栏吉浦迅科技

DAY19:阅读纹理内存之Texture Gather

3844
来自专栏生信宝典

R语言可视化学习笔记之ggridges包

作者:严涛 浙江大学作物遗传育种在读研究生(生物信息学方向)伪码农,R语言爱好者,爱开源。

1774

Apache Spark中使用DataFrame的统计和数学函数

我们在Apache Spark 1.3版本中引入了DataFrame功能, 使得Apache Spark更容易用. 受到R语言和Python中数据框架的启发, ...

2.7K6
来自专栏何俊林

OpenGL ES总结(一)OpenGL 初识

导读:OpenGL是在图形图像中,非常优秀的渲染库,文中Demo下载地址:https://github.com/hejunlin2013/OpenGL31,看下...

3548
来自专栏CreateAMind

神经网络图灵机(Neural Turing Machines, NTM)论文完整翻译

1524
来自专栏Python攻城狮

Python数据科学(六)- 资料清理(Ⅰ)1.Pandas1.资料筛选2.侦测遗失值3.补齐遗失值

成功爬取到我们所需要的数据以后,接下来应该做的是对资料进行清理和转换, 很多人遇到这种情况最自然地反应就是“写个脚本”,当然这也算是一个很好的解决方法,但是,p...

1373
来自专栏机器之心

专栏 | 深度好奇提出文档解析框架:面向对象的神经规划

29110

扫码关注云+社区

领取腾讯云代金券