移动端深度学习部署:TFlite

1.TFlite介绍

1TFlite概念

  • tflite是谷歌自己的一个轻量级推理库。主要用于移动端。
  • tflite使用的思路主要是从预训练的模型转换为tflite模型文件,拿到移动端部署。
  • tflite的源模型可以来自tensorflowsaved model或者frozen model,也可以来自keras

2TFlite优点

用Flatbuffer序列化模型文件,这种格式磁盘占用少,加载快

可以对模型进行量化,把float参数量化为uint8类型,模型文件更小、计算更快。

可以对模型进行剪枝、结构合并和蒸馏。

对NNAPI的支持。可调用安卓底层的接口,把异构的计算能力利用起来。

3TFlite量化

a.量化的好处        

  • 较小的存储大小:小模型在用户设备上占用的存储空间更少。例如,一个使用小模型的 Android 应用在用户的移动设备上会占用更少的存储空间。
  • 较小的下载大小:小模型下载到用户设备所需的时间和带宽较少。
  • 更少的内存用量:小模型在运行时使用的内存更少,从而释放内存供应用的其他部分使用,并可以转化为更好的性能和稳定性。

b.量化的过程

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

Tensorflow官方量化文档

 

 

c.量化的实现

训练后动态量化

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
#converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
tflite_model1 = converter.convert()
open("xxx.tflite", "wb").write(tflite_model1)

训练后float16量化

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float16]
tflite_quant_model = converter.convert()
tflite_model1 = converter.convert()
open("xxx.tflite", "wb").write(tflite_model1)

训练后int8量化

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
def representative_dataset_gen():
  for _ in range(num_calibration_steps):
    # Get sample input data as a numpy array in a method of your choosing.
    yield [input]
converter.representative_dataset = representative_dataset_gen
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8  # or tf.uint8
converter.inference_output_type = tf.int8  # or tf.uint8
tflite_model1 = converter.convert()
open("xxx.tflite", "wb").write(tflite_model1)

注:float32和float16量化可以运行再GPU上,int8量化只能运行再CPU上

2.TFlite模型转换

1)在训练的时候就保存tflite模型

import tensorflow as tf
img = tf.placeholder(name="img", dtype=tf.float32, shape=(1, 64, 64, 3))
val = img + tf.constant([1., 2., 3.]) + tf.constant([1., 4., 4.])
out = tf.identity(val, name="out")
with tf.Session() as sess:
  tflite_model = tf.lite.toco_convert(sess.graph_def, [img], [out])
  open("converteds_model.tflite", "wb").write(tflite_model)

2)使用其他格式的TensorFlow模型转换成tflite模型

        首先要安装Bazel,参考:https://docs.bazel.build/versions/master/install-ubuntu.html ,只需要完成Installing using binary installer这一部分即可。然后克隆TensorFlow的源码:

git clone https://github.com/tensorflow/tensorflow.git

        接着编译转换工具,这个编译时间可能比较长:

cd tensorflow/
bazel build tensorflow/python/tools:freeze_graph
bazel build tensorflow/lite/toco:toco

        获得到转换工具之后,开始转换模型,以下操作是冻结图:

  • input_graph对应的是.pb文件;
  • input_checkpoint对应mobilenet_v1_1.0_224.ckpt.data-00000-of-00001,使用时去掉后缀名。
  • output_node_names这个可以在mobilenet_v1_1.0_224_info.txt中获取。

./freeze_graph --input_graph=/mobilenet_v1_1.0_224/mobilenet_v1_1.0_224_frozen.pb \
  --input_checkpoint=/mobilenet_v1_1.0_224/mobilenet_v1_1.0_224.ckpt \
  --input_binary=true \
  --output_graph=/tmp/frozen_mobilenet_v1_224.pb \
  --output_node_names=MobilenetV1/Predictions/Reshape_1

将冻结的图转换成tflite模型:

  • input_file是已经冻结的图;
  • output_file是转换后输出的路径;
  • output_arrays这个可以在mobilenet_v1_1.0_224_info.txt中获取;
  • input_shapes这个是预测数据的shape

./toco --input_file=/tmp/mobilenet_v1_1.0_224_frozen.pb \
  --input_format=TENSORFLOW_GRAPHDEF \
  --output_format=TFLITE \
  --output_file=/tmp/mobilenet_v1_1.0_224.tflite \
  --inference_type=FLOAT \
  --input_type=FLOAT \
  --input_arrays=input \
  --output_arrays=MobilenetV1/Predictions/Reshape_1 \
  --input_shapes=1,224,224,3

3)使用检查点进行模型转换

  • 将tensorflow模型保存成.pb文件

import tensorflow as tf
from tensorflow.python.framework import graph_util
from tensorflow.python.platform import gfile
 
if __name__ == "__main__":
    a = tf.Variable(tf.constant(5.,shape=[1]),name="a")
    b = tf.Variable(tf.constant(6.,shape=[1]),name="b")
    c = a + b
    init = tf.initialize_all_variables()
    sess = tf.Session()
    sess.run(init)
    #
导出当前计算图的GraphDef部分
    graph_def = tf.get_default_graph().as_graph_def()
    #保存指定的节点,并将节点值保存为常数
    output_graph_def = graph_util.convert_variables_to_constants(sess,graph_def,['add'])
    #将计算图写入到模型文件中
    model_f = tf.gfile.GFile("model.pb","wb")
    model_f.write(output_graph_def.SerializeToString())

  • 模型文件的读取

Bash
 sess = tf.Session()
    #
将保存的模型文件解析为GraphDef
    model_f = gfile.FastGFile("model.pb",'rb')
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(model_f.read())
    c = tf.import_graph_def(graph_def,return_elements=["add:0"])
    print(sess.run(c))
    #[array([ 11.], dtype=float32)]

  • pb文件转tflite

Python
import tensorflow as tf
 
in_path=r'D:\tmp_mobilenet_v1_100_224_classification_3\output_graph.pb'
out_path=r'D:\tmp_mobilenet_v1_100_224_classification_3\output_graph.tflite'
 
input_tensor_name=['Placeholder']
input_tensor_shape={'Placeholder':[1,224,224,3]}
 
class_tensor_name=['final_result']
 
convertr=tf.lite.TFLiteConverter.from_frozen_graph(in_path,input_arrays=input_tensor_name
                                                   ,output_arrays=class_tensor_name
                                                   ,input_shapes=input_tensor_shape)
 
# convertr=tf.lite.TFLiteConverter.from_saved_model(saved_model_dir=in_path,input_arrays=[input_tensor_name],output_arrays=[class_tensor_name])
tflite_model=convertr.convert()
 
with open(out_path,'wb') as f:
    f.write(tflite_model)

 

3.Android端调用TFlite模型文件

1Android studio中调用TFlite模型实现推理的流程

  • 定义一个interpreter
  • 初始化interpreter(加载tflite模型)
  • 在Android中加载图片到buffer中
  • 用解释器执行图形(推理)
  • 将推理的结果在app中进行显示

2)在Android Studio中导入TFLite模型步骤

  • 新建或打开现有Android项目工程。
  • 通过菜单项 File > New > Other > TensorFlow Lite Model 打开TFLite模型导入对话框。
  • 选择后缀名为.tflite的模型文件。模型文件可以从网上下载或自行训练。
  • 导入的.tflite模型文件位于工程的 ml/ 文件夹下面。

模型主要包括如下三种信息:

  • 模型:包括模型名称、描述、版本、作者等等。
  • 张量:输入和输出张量。比如图片需要预先处理成合适的尺寸,才能进行推理。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/39152.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

初识protobuf

Protobuf 全称Protocol Buffers(协议缓冲区),是一种轻量级、高效的数据序列化格式,由Google开发。它被设计用于结构化数据的序列化、反序列化以及数据交换,常用于网络通信和数据存储等领域。 Protobuf使用简洁的消息描…

解决appium-doctor报 bundletool.jar cannot be found

一、下载bundletool.jar 下载地址:https://github.com/google/bundletool/releases 二、重命名 重命名这个jar包为bundletool.jar,在android sdk目录下,新建bundle-tool目录,把bundletool.jar包放入其中。 三、配置环境 path后追加…

re学习(19)[ACTF新生赛2020]easyre1(UPX脱壳)

文章链接:BUUCTF在线评测 参考视频:B站 【新手教程三】小Z带你学习什么是ESP定律和什么是堆栈平衡 ? - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn 题解: 工具脱壳 key"*F\"N,\"…

蒲公英打包环境搭建碰到问题

一:证书那边选择手动,不要自动,——》debug配置dev证书,release配置ad-hoc证书 二:证书有时候不生效,删除重新下载。~/Library/MobileDevice/Provisioning Profiles 三:更新测试手机时&#…

# Linux终端控制字符详解以及简单应用实践

Linux终端控制字符详解以及简单应用实践 文章目录 Linux终端控制字符详解以及简单应用实践1 控制字符表2 控制字符 ESC (0x1B,^[)子参数表3 控制字符 ESC (0x1B,^[)子参数表 - 字符颜色参照表4 实践&#x…

SpringBoot+JWT实现单点登录解决方案

一、什么是单点登录? 单点登录是一种统一认证和授权机制,指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的系统,不需要重新登录验证。 单点登录一般用于互相授信的系统,实现单一位置登录,其他信任的…

【JavaEE面试题(九)线程安全问题的原因和解决方案】

多线程-初阶 4. 多线程带来的的风险-线程安全 (重点)4.1 观察线程不安全原因是 1.load 2. add 3. save 4.2 线程安全的概念4.3 线程不安全的原因最根本的是 操作系统对线程的调度是随机的★1. 修改共享数据(多个线程修改同一个变量)★2. 操作不是原子性★…

EIK+Filebeat+Kafka

目录 Kafka 概述 为什么需要消息队列(MQ) 使用消息队列的好处 消息队列的两种模式 Kafka 定义 Kafka 简介 Kafka 的特性 Kafka 系统架构 Partation 数据路由规则: 分区的原因 部署 kafka 集群 1.下载安装包 2.安装 Kafka 修改配…

前端 | (七)浮动 | 尚硅谷前端html+css零基础教程2023最新

学习来源:尚硅谷前端htmlcss零基础教程,2023最新前端开发html5css3视频 文章目录 📚浮动介绍🐇元素浮动后的特点🐇浮动小练习🔥盒子1右浮动🔥盒子1左浮动🔥所有盒子都浮动&#x1f5…

后端Linux软件安装大全[JDK、Tomcat、MySQL、Irzsz、Git、Maven、Redis...持续更新中]

文章目录 前言1.软件安装方式2.安装jdk3.安装Tomcat4.安装MySQL5.安装lrzsz6. 安装Git7. 安装Maven8. 安装Redis 总结 前言 为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的…

Vue第三篇:最简单的vue购物车示例

本文参考&#xff1a;Vue Cli&#xff08;脚手架&#xff09;实现购物车小案例 - - php中文网博客 效果图&#xff1a; 编写流程&#xff1a; 1、首先通过vue/cli创建工程 vue create totalprice 2、改写App.vue代码如下&#xff1a; <template><div><div v…

【深度学习笔记】训练 / 验证 / 测试集

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记&#xff0c;视频由网易云课堂与 deeplearning.ai 联合出品&#xff0c;主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习&#xff0c;视频的链接如下&#xff1a; 神经网络和…

【电路原理学习笔记】第3章:欧姆定律:3.1 电压、电流与电阻的关系

第3章&#xff1a;欧姆定律 3.1 电压、电流与电阻的关系 欧姆定律指出&#xff1a;电流与电压成正比&#xff0c;与电阻成反比。即 I V R I\frac{V}{R} IRV​ 3.1.1 电压与电流之间的线性关系 数学上&#xff0c;线性指的是变量之间的关系在图形上是一条直线。线性方程所对…

ChatGPT 最佳实践指南之:系统地测试变化

Test changes systematically 系统地测试变化 Improving performance is easier if you can measure it. In some cases a modification to a prompt will achieve better performance on a few isolated examples but lead to worse overall performance on a more representa…

分布式运用——存储系统Ceph

分布式运用——存储系统Ceph 一、Ceph 介绍1.Ceph 简介2、存储基础2.1 单机存储设备2.2 单机存储的问题2.3 商业存储解决方案2.4 分布式存储&#xff08;软件定义的存储 SDS&#xff09;2.5 分布式存储的类型 3.Ceph 优势3.1 高扩展性3.2 高可靠性3.3 高性能3.4 功能强大 4.Cep…

pwm呼吸灯

文章目录 一、呼吸灯二、代码实现三、引脚分配 一、呼吸灯 呼吸灯是指灯光在微电脑的控制之下完成由亮到暗的逐渐变化&#xff0c;使用开发板上的四个led灯实现1s间隔的呼吸灯。 二、代码实现 c module pwm_led( input clk ,input rst_n ,output reg [3:0] led ); …

mysql中的行格式之compact格式分析

mysql中的行格式之compact格式分析 mysql行格式 所谓行格式&#xff0c;就是指mysql一行数据的存储格式。 InnoDB 储存引擎支持有四种行储存格式&#xff1a;Compact、Redundant、Dynamic 和 Compressed。 Redundant是很古老的行格式了&#xff0c;因为占用空间最多&#x…

(1)ADS-B接收机

文章目录 前言 1.1 所需硬件 1.2 连接到自动驾驶仪 1.3 设置 1.4 ADSB输出配置 1.5 启用载人飞行器避障功能 1.6 飞行器数据库 1.7 开发者信息包括模拟 前言 本文介绍了如何安装和配置 ADS-B 模块&#xff0c;以便你的飞机能够知道附近的其他飞机和空中交通管制&#x…

CSS样式

1.高度和宽度 .c1{height:300px;width:500px;}注意事项&#xff1a; 宽度支持百分比&#xff0c;高度不支持。行内标签&#xff1a;默认无效会计标签&#xff1a;默认有效&#xff08;霸道&#xff0c;右侧区域空白&#xff0c;也不给你用&#xff09; 2.块级和行内标签 块…

微服务架构+创建微服务工程(商品/订单)

目录 1.微服务架构 1.1.单体应用架构 1.2.微服务应用 1.3 微服务架构的优势 1.4.微服务架构的缺点(挑战) 1.5. SpringCloud与微服务关系 1.6.SpringBoot和SpringCloud关系 2. 创建微服务工程 2.1.数据库 2.2.搭建父工程 2.2 创建公共模块 2.3.商品系统 2.4.订单微…