【嵌入式AI】python转换tflite模型并在PC上调用

2023-12-02 00:40

本文主要是介绍【嵌入式AI】python转换tflite模型并在PC上调用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

用python转换tflite模型并在PC上调用



环境

  • python3.6
  • tf-nightly 1.13
  • win10 64位
  • i7 8550U



制作frozen模型

就是后缀为pb的模型文件,转换直接调用TF的接口来保存frozen模型文件即可。



转换为tflite模型



非量化转换

转换代码:

# -*- coding:utf-8 -*-
import tensorflow as tfin_path = "./model/frozen_graph.pb"
out_path = "./model/frozen_graph.tflite"
# out_path = "./model/quantize_frozen_graph.tflite"# 模型输入节点
input_tensor_name = ["input/x"]
input_tensor_shape = {"input/x":[1, 784]}
# 模型输出节点
classes_tensor_name = ["out/fc2"]converter = tf.lite.TFLiteConverter.from_frozen_graph(in_path,input_tensor_name, classes_tensor_name,input_shapes = input_tensor_shape)
#converter.post_training_quantize = True
tflite_model = converter.convert()with open(out_path, "wb") as f:f.write(tflite_model)

转换模型前后,模型文件大小几乎一样,都是12M左右。



量化转换

把上面代码里‘converter.post_training_quantize = True’启用就行了。
转换出的模型大小变为原来的约1/4, 只有3M左右。



PC上用python调用tflite模型



调用非量化模型

# -*- coding:utf-8 -*-
import os
os.environ["CUDA_VISIBLE_DEVICES"]="-1"  
import cv2
import numpy as np
import timeimport tensorflow as tftest_image_dir = './test_images/'
#model_path = "./model/quantize_frozen_graph.tflite"
model_path = "./model/frozen_graph.tflite"# Load TFLite model and allocate tensors.
interpreter = tf.lite.Interpreter(model_path=model_path)
interpreter.allocate_tensors()# Get input and output tensors.
input_details = interpreter.get_input_details()
print(str(input_details))
output_details = interpreter.get_output_details()
print(str(output_details))#with tf.Session( ) as sess:
if 1:file_list = os.listdir(test_image_dir)model_interpreter_time = 0start_time = time.time()# 遍历文件for file in file_list:print('=========================')full_path = os.path.join(test_image_dir, file)print('full_path:{}'.format(full_path))# 只要黑白的,大小控制在(28,28)img = cv2.imread(full_path, cv2.IMREAD_GRAYSCALE )res_img = cv2.resize(img,(28,28),interpolation=cv2.INTER_CUBIC) # 变成长784的一维数据new_img = res_img.reshape((784))# 增加一个维度,变为 [1, 784]image_np_expanded = np.expand_dims(new_img, axis=0)image_np_expanded = image_np_expanded.astype('float32') # 类型也要满足要求# 填装数据model_interpreter_start_time = time.time()interpreter.set_tensor(input_details[0]['index'], image_np_expanded)# 注意注意,我要调用模型了interpreter.invoke()output_data = interpreter.get_tensor(output_details[0]['index'])model_interpreter_time += time.time() - model_interpreter_start_time# 出来的结果去掉没用的维度result = np.squeeze(output_data)print('result:{}'.format(result))#print('result:{}'.format(sess.run(output, feed_dict={newInput_X: image_np_expanded})))# 输出结果是长度为10(对应0-9)的一维数据,最大值的下标就是预测的数字print('result:{}'.format( (np.where(result==np.max(result)))[0][0]  ))used_time = time.time() - start_timeprint('used_time:{}'.format(used_time))print('model_interpreter_time:{}'.format(model_interpreter_time))



调用非量化模型

方法不变,把模型路径改为量化的模型路径即可。



win10 python3.6下的时间对比

用11张图片测试,单独统计11次推理部分的时间之和,统计如下

方案frozen模型tflite模型量化tflite模型
时间634ms70ms80ms

很奇怪的是量化模型没有比非量化模型更快。个人猜测这可能跟intel CPU很强的浮点计算能力有关,量化来量化去反而增加了额外的时间。在ARM等移动终端上应该有另外的结论



识别准确率

经过测试,转换为tflite模型后,用mnist数据集里的1万个测试数据测试,准确率在**97.2%**左右,和转换前的97.48%没有明显区别。



命令行转换

从tf1.9开始,tflite_convert就作为和tensorflow一起安装的二进制工具了。以前版本的转换工具叫toco,测试发现toco在tf1.13仍然存在,但是和tflite_convert选项基本一致,可能已经合并了。



不支持的操作

转换模型中遇到一次错误:

Some of the operators in the model are not supported by the standard TensorFlow Lite runtime. If those are native Tensor
Flow operators, you might be able to use the extended runtime by passing --enable_select_tf_ops, or by setting target_op
s=TFLITE_BUILTINS,SELECT_TF_OPS when calling tf.lite.TFLiteConverter(). Otherwise, if you have a custom implementation f
or them you can disable this error with --allow_custom_ops, or by setting allow_custom_ops=True when calling tf.lite.TFL
iteConverter(). Here is a list of builtin operators you are using: ADD, CONV_2D, DEPTHWISE_CONV_2D, DIV, FLOOR, FULLY_CO
NNECTED, MAX_POOL_2D, MUL. Here is a list of operators for which you will need custom implementations: RandomUniform.

上面提示也比较清楚了,就是有不支持的算子:RandomUniform。通过tensorboard查看,发现这个算子在dropout里面。我简单的把dropout去掉了。实际生产中可以用L2正则化和BN来防止过拟合。

试着转换fater_rcnn模型,遇到很多不支持的操作:


2019-01-07 10:35:52.654913: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: Enter
2019-01-07 10:35:52.655148: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: TensorArrayV3
2019-01-07 10:35:52.655404: I tensorflow/lite/toco/import_tensorflow.cc:193] Unsupported data type in placeholder op: 20
2019-01-07 10:35:52.658516: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: TensorArrayScatterV3
2019-01-07 10:35:52.659010: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: LoopCond
2019-01-07 10:35:52.659219: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: Exit
2019-01-07 10:35:52.660613: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: Round
2019-01-07 10:35:52.661490: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: Reciprocal
2019-01-07 10:35:52.664014: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: Where
2019-01-07 10:35:52.670159: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: LoopCond
2019-01-07 10:35:52.670838: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: TensorArraySizeV3
2019-01-07 10:35:52.671080: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: TensorArrayReadV3
2019-01-07 10:35:52.671869: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: TensorArrayScatterV3
2019-01-07 10:35:52.672106: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: TensorArrayGatherV3
2019-01-07 10:35:52.673044: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: TensorArrayV3
2019-01-07 10:35:52.676008: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: CropAndResize
2019-01-07 10:35:52.677367: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: TensorArrayWriteV3
2019-01-07 10:35:52.678589: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: NonMaxSuppressionV2
2019-01-07 10:35:52.679152: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: Size
2019-01-07 10:35:52.686332: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: TensorArrayReadV3
2019-01-07 10:35:52.687485: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: Reciprocal
2019-01-07 10:35:52.689467: I tensorflow/lite/toco/import_tensorflow.cc:1327] Converting unsupported operation: NonMaxSuppressionV22019-01-07 10:35:52.744613: I tensorflow/lite/toco/graph_transformations/graph_transformations.cc:39] Before Removing unused ops: 1175 operators, 1717 arrays (0 quantized)
2019-01-07 10:35:52.828899: I tensorflow/lite/toco/graph_transformations/graph_transformations.cc:39] After Removing unused ops pass 1: 1144 operators, 1673 arrays (0 quantized)
2019-01-07 10:35:53.303533: I tensorflow/lite/toco/graph_transformations/graph_transformations.cc:39] Before dequantization graph transformations: 737 operators, 1102 arrays (0 quantized)
2019-01-07 10:35:53.351090: F tensorflow/lite/toco/tooling_util.cc:627] Check failed: dim >= 1 (0 vs. 1)



BUG 1

用提tf1.12把模型转换为tflite格式遇到错误‘No module named ‘_tensorflow_wrap_toco’’,搜索了下竟然是官方的问题。升级为tf-nightly1.13问题解决了。

另外一个同事说他用tf1.9也成功了。



BUG 2

在调用tflite模型的时候遇到一个问题,报错信息为:

ValueError: Cannot set tensor: Got tensor of type 3 but expected type 1 for input 9

出错位置为:

interpreter.set_tensor(input_details[0]['index'], image_np_expanded)

看样子是类型错误。通过打印发现我喂的图片是uint8的,而不是float32的。通过调用numpy的astype(‘float32’)方法可以解决这个问题。

同样的读取图片方法在普通的tensorflow模式下不会出错,在tflite下会出错。这说明普通的tensorflow模式下会进行隐式类型转换。



吐槽

据说contrib在tf2.0上要废止了。不知道到时接口又要变成什么样。

最近几个版本上的接口如下:

在这里插入图片描述



参考资料

官方文档:Converter Python API guide

tensorflow/tensorflow/lite/python/interpreter_test.py

tensorflow/tensorflow/lite/python/interpreter.py

tensorflow 20:搭网络、导出模型、运行模型


论坛帖子

How to load a tflite model in script?


github issue:

  • github上讨论‘No module named '_tensorflow_wrap_toco’的issue

  • 另外一个类似的issue

这篇关于【嵌入式AI】python转换tflite模型并在PC上调用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/443304

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

AI绘图怎么变现?想做点副业的小白必看!

在科技飞速发展的今天,AI绘图作为一种新兴技术,不仅改变了艺术创作的方式,也为创作者提供了多种变现途径。本文将详细探讨几种常见的AI绘图变现方式,帮助创作者更好地利用这一技术实现经济收益。 更多实操教程和AI绘画工具,可以扫描下方,免费获取 定制服务:个性化的创意商机 个性化定制 AI绘图技术能够根据用户需求生成个性化的头像、壁纸、插画等作品。例如,姓氏头像在电商平台上非常受欢迎,

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

从去中心化到智能化:Web3如何与AI共同塑造数字生态

在数字时代的演进中,Web3和人工智能(AI)正成为塑造未来互联网的两大核心力量。Web3的去中心化理念与AI的智能化技术,正相互交织,共同推动数字生态的变革。本文将探讨Web3与AI的融合如何改变数字世界,并展望这一新兴组合如何重塑我们的在线体验。 Web3的去中心化愿景 Web3代表了互联网的第三代发展,它基于去中心化的区块链技术,旨在创建一个开放、透明且用户主导的数字生态。不同于传统

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手!🌟 什么是Kimi? 一款月之暗面科技有限公司开发的AI办公工具,帮助用户快速生成高质量的演示文稿。 无论你是职场人士、学生还是教师,Kimi都能够为你的办公文

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal