tensorflow 19: tflite 概念理解

概述

学术界对精度、自由度的要求和工业界对速度、精简度的要求形成了反差,这就使得越来越多的框架开始把training和inference分开,各公司都开始针对移动设备纷纷推出高性能inference库。

tflite

tflite其实就是谷歌自己的一个轻量级推理库。主要用于移动端。之前的tensorflow mobile那一套到2019年就不再维护了。

tflite使用的思路主要是从预训练的模型转换为tflite模型文件,拿到移动端部署。

tflite的源模型可以来自tensorflow的saved model或者frozen model,也可以来自keras。
tensorflow 19: tflite 概念理解_第1张图片

tflite做了哪些优化

  • 用Flatbuffer序列化模型文件,这种格式磁盘占用少,加载快
  • 量化。这个特性是可以开关的,可以把float参数量化为uint8类型,模型文件更小、计算更快。
  • 剪枝、结构合并和蒸馏。我也不是很确定,敢写在这里主要来自两个官方文件,具体链接在本文最下方参考资料里。一个是《Model optimization》,这里提到了优化模型用到了模型优化方法,另一个是《Converter command-line examples》,里面一张对比优化前后的计算图显示tflite在转换时确实进行了结构调整。但是这个特性没有很多人讲,有可能这方面tflite做的不是很多,只是浅尝辄止。
  • 对NNAPI的支持。上三个特性都是转换模型文件的特性,这个是运行时的特性。也就是调用安卓底层的接口,把异构的计算能力利用起来。虽然 TFLite 基于 NNAPI,理论上是可以利用上各种运算芯片的,但目前还没有很多运算芯片支持 NNAPI。

量化

对量化的理解主要来自《用 TensorFlow 压缩神经网络》。

tflite的量化并不是全程使用uint8计算。而是存储每层的最大和最小值,然后把这个区间线性分成 256 个离散值,于是此范围内的每个浮点数可以用八位 (二进制) 整数来表示,近似为离得最近的那个离散值。比如,最小值是 -3 而最大值是 6 的情形,0 字节表示 -3,255 表示 6,而 128 是 1.5。

每个操作都先用整形计算,输出时重新转换为浮点型。下图就是量化Relu的示意图。
tensorflow 19: tflite 概念理解_第2张图片 tensorflow 19: tflite 概念理解_第3张图片

如果连续一串操作都有等价的浮点操作,则会有许多相邻的量化/去量化操作。当发现这种模式之后,转换程序会把相互抵消的那些操作移除,比如:

tensorflow 19: tflite 概念理解_第4张图片

由于每层最大值最小值不一样,所以没法把整形从头算到尾,中间还是有不少量化/去量化操作。

tfite的缺陷

TFLite 目前仅提供有限的算子,主要以 CNN 中使用到的算子为主,如卷积、池化等。
有可能遇到的情况就是,模型的某些算子tflite不支持(比如反卷积),你可以自定义一个 TFLite 算子,将其注册在 TFLite 的 kernels 列表中,这样编译得到的 TFLite 库就可以处理该算子了。同时,在模型转换时,还需要加上 --allow_custom_ops 选项,将 TFLite 默认不支持的算子也保留在模型中。(本段来自《有道云笔记是如何使用 TensorFlow Lite 的》)

tflite支持的算子列表在《TensorFlow Lite & TensorFlow Compatibility Guide》这个页面上。

如何将tensorflow模型文件转换为tflite文件

本节来自《Tensorflow lite for 移动端安卓开发(二)——完整详细过程训练自己的模型》

生成float inference模型

cd /home/liuli/tensorflow
bazel build tensorflow/contrib/lite/toco:toco
bazel run --config=opt tensorflow/contrib/lite/toco:toco -- \
  --input_file=/home/liuli/work/Tensorflow/1_frozen.pb \
  --output_file=/home/liuli/work/Tensorflow/7_float.tflite \
  --inference_type=FLOAT \
  --input_shape=1,224,224,3 \
  --input_array=input \
  --output_array=MobilenetV1/Predictions/Reshape_1

生成Quant inference模型

cd /home/liuli/tensorflow
bazel build tensorflow/contrib/lite/toco:toco
bazel run --config=opt tensorflow/contrib/lite/toco:toco -- \
  --input_file=/home/liuli/work/Tensorflow/1_frozen.pb \
  --output_file=/home/liuli/work/Tensorflow/7.tflite \
  --input_format=TENSORFLOW_GRAPHDEF \
  --output_format=TFLITE \
  --inference_type=QUANTIZED_UINT8 \
  --input_shape=1,224,224,3 \
  --input_array=input \
  --output_array=MobilenetV1/Predictions/Reshape_1 \
  --default_ranges_min=0 \
  --default_ranges_max=6 \
  --std_value=127.5 \
  --mean_value=127.5

量化的效果

参考了《tflite现成的模型》,这个页面是tensorflow的github。

float类型的tflite模型(未量化):
tensorflow 19: tflite 概念理解_第5张图片

量化的效果:
tensorflow 19: tflite 概念理解_第6张图片
看来还是要量化,否则调用太慢。这里的结果看来量化的精度损失不大,但是网上有人测试效果差挺远,所以要具体分析。

查看输入输出节点

编译:

Bazel build tensorflow/tools/graph_transforms:summarize_graph  (查看模型结构,找出输入输出)

该命令查看整个Tensorflow模型概况,使用命令如下,运行之后,得到自己整个网络结构,从中可以找到自己模型的输入输出,如下图(模型比较乱。。。)

# “--in_graph=” 后面是模型存储的位置
bazel-bin/tensorflow/tools/graph_transforms/summarize_graph --in_graph=../mz_graph.pb

本节主要来自:《Tensorflow 模型转 tflite ,在安卓端使用》

参考资料

官方文档

  • Introduction to TensorFlow Lite
  • Post-training quantization
  • Model optimization
  • tflite现成的模型
  • Converter command-line examples
  • TensorFlow Lite & TensorFlow Compatibility Guide

大神的博客中文翻译:用 TensorFlow 压缩神经网络(详细解释了为何量化有效)

Tensorflow 模型转 tflite ,在安卓端使用(介绍了ftlite的基本流程和概念)

知乎大神:从TensorFlow Lite源码入门CNN量化

有道云笔记是如何使用 TensorFlow Lite 的

GEMM-通用矩阵乘法:

  • 深度学习中GEMM的前世今生
  • Why GEMM is at the heart of deep learning

Tensorflow lite for 移动端安卓开发(二)——完整详细过程训练自己的模型

你可能感兴趣的:(tensorflow,机器学习,python,DL/ML/AI,深度学习)