EfficientDet模型saved_model.pb转TFLite格式报错及转换方法求助
EfficientDet-d0转TFLite异常解决方案
问题原因
你遇到的两个核心问题原因如下:
- 输入形状为[1,1,1,3]、量化参数全为0:转换时未正确导出适配TFLite的SavedModel,且全整数量化未提供校准数据集,导致转换器无法推断正确输入尺寸、无法生成有效量化参数。
- 数据类型报错:你转换的是uint8量化模型,要求输入为uint8类型,但你传入了float32格式数据,类型不匹配。
正确转换步骤
1. 导出适配TFLite的SavedModel
不要直接使用训练时保存的pb文件,使用TensorFlow Object Detection API自带的export_tflite_graph_tf2.py脚本导出专用SavedModel,提前指定输入类型为uint8,避免后续转换异常:
python object_detection/export_tflite_graph_tf2.py \ --pipeline_config_path=你的pipeline.config路径 \ --trained_checkpoint_dir=你的checkpoint保存目录 \ --output_directory=导出文件保存目录 \ --input_type=uint8
2. 带校准的全整数量化转换(树莓派推荐,速度最快)
全整数量化必须提供校准数据集才能生成有效量化参数,取训练集中100-200张无标注图片即可,转换代码如下:
import tensorflow as tf import numpy as np import os import cv2 # 校准数据集生成函数 def representative_data_gen(): calib_img_path = "你的校准图片文件夹路径" img_list = os.listdir(calib_img_path)[:200] for img_name in img_list: img = cv2.imread(os.path.join(calib_img_path, img_name)) # EfficientDet-d0默认输入尺寸为512x512 img = cv2.resize(img, (512, 512)) img = img.astype(np.uint8) yield [np.expand_dims(img, axis=0)] # 加载第一步导出的SavedModel converter = tf.lite.TFLiteConverter.from_saved_model("导出目录/saved_model") # 量化配置 converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_data_gen converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.uint8 converter.inference_output_type = tf.uint8 # 转换并保存 tflite_model = converter.convert() with open("efficientdet-d0_uint8.tflite", "wb") as f: f.write(tflite_model)
可选:float16量化(无需校准,兼容性更好)
如果不需要极致推理速度,也可以选择float16量化,不需要校准数据集,输入类型为float32,不会出现类型不匹配问题:
converter = tf.lite.TFLiteConverter.from_saved_model("导出目录/saved_model") converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_types = [tf.float16] tflite_model = converter.convert()
正确推理示例
使用uint8量化模型时,输入必须为[1,512,512,3]格式的uint8数据:
import tensorflow as tf import numpy as np import cv2 interpreter = tf.lite.Interpreter(model_path="efficientdet-d0_uint8.tflite") interpreter.allocate_tensors() input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() # 预处理输入图片 img = cv2.imread("测试图片路径") img = cv2.resize(img, (512, 512)) input_data = np.expand_dims(img.astype(np.uint8), axis=0) # 执行推理 interpreter.set_tensor(input_details[0]['index'], input_data) interpreter.invoke() # 读取输出 boxes = interpreter.get_tensor(output_details[0]['index']) classes = interpreter.get_tensor(output_details[1]['index']) scores = interpreter.get_tensor(output_details[2]['index']) num_detections = interpreter.get_tensor(output_details[3]['index'])
内容的提问来源于stack exchange,提问作者FabioMotta
相关产品推荐
相关产品推荐

