TensorFlow Lite 和 TensorFlow 的关系
下面将着重介绍 模型结构格式(Model Format) 和 解析器概况(Interpreter)
TensorFlow Lite Model File
Model File 的代码位于 tensorflow-master/tensorflow/lite/schema文件夹中,模型文件的主结构如下 Model 结构体所示
Model 结构体定义了该模型用到的算子 operator_codes
Model 结构体中的 subgraphs 定义了各个子图,其中第一个子图 subgraphs[0] 为主图
Model 结构体中的 buffers为数据存储区域,主要用来存放模型权重
SubGraph
SubGraph 是 Model 里最重要的结构体,它定义了图的具体结构
SubGraph 的 tensors 定义了子图中的各个 Tensor
SubGraph 的 inputs和outputs根据索引值的形式定义了哪些 tensor 负责输入输出
SubGraph 的 operators 定义了子图中的各个算子
Tensor 的具体结构
Tensor 结构体包含了维度(shape)信息,
数据类型(type), 以及 buffer 位置
Tensor 中的 buffer 通过索引值的形式指出了此 Tensor 使用了哪个具体 Buffer
Operator 的具体结构
Operator 是 SubGraph中最重要的结构体,它起到的联立关系最终定义了图的结构
Operator 中的 opcode_index 通过索引值的形式指明了该 operator 所对应的具体算子
Operator 中的 inputs 和 outputs 是 tensors 的索引值,指明了该 operator 的输入输出,这样我们可以成功地将数据流图以 FlatBuffer 的形式表达出来
Interpreter 细节
数据流图可以用边(TfLiteTensor)和节点(TfLiteNode)来表达,边就是 Tensor, 节点则为 Operator, 输入边 Tensor 经过节点 Operator 后得到 输出边Tensor
Interpreter (解析器)中实现数据流图的运算概要如下:
- 首先我们将模型文件通过 mmap 内存映射加载进内存,这样我们在内存里有了Tensors, Operators以及Buffer等内容。
-
模型的Buffer一般来说是只读的,通常用来记录权重信息,为了表示那些数值可变的Tensor,我们额外分配了可写的Buffer区域
- Interpreter 还包含了具体执行计算的代码,我们称之为 kernel
- 模型中的各个 Tensor 被加载为TfLiteTensor 格式,并集中存放在 TfLiteContext中,每个Tensor的指针指向内存映射的只读数据区域或新分配的可写数据区域
- 模型中的 Operator 被加载为 TfLiteNode ,它包含了输入输出Tensor的索引值
-
TfLietNode 对应的操作符存储于 TfLiteRegistration 中,它包含了指向 kernel 的函数指针
-
OpResolver 负责维护函数指针映射关系
以上就为TensorFlow Lite Interpreter的核心,在加载模型时我们会确认执行 TfLiteNode 的顺序, TfLiteTensor, TfLiteContext, TfLiteNode, TfLietRegistration 是重要的数据结构
更多细节请阅读以下关键文件:
tensorflow-master/tensorflow/lite/context.h
tensorflow-master/tensorflow/lite/model.h
tensorflow-master/tensorflow/lite/interpreter.h
tensorflow-master/tensorflow/lite/register.h