自定义TensorFlow 2 SSD Mobilenet模型转TFLite运行报错如何解决?
问题定位
你遇到的报错是因为转换得到的TFLite模型输出张量维度不符合推理脚本的预期:脚本期望scores是包含所有检测框置信度的数组,但你得到的是单个float32标量,因此调用len()时报错。
问题出在两个环节:
- 用
export_tflite_graph_tf2.py导出SavedModel时,没有指定输入维度和SSD模型专属配置,导出的计算图默认压缩了输出的批量维度 - 转换TFLite时没有做维度保留配置,进一步导致输出张量被降维成标量
修复方案
你可以任选以下两种方案中的一种执行:
方案一:重新导出并转换模型(兼容性更好)
步骤1:重新导出适配TFLite的SavedModel
运行导出脚本时添加SSD模型必要参数,注意把300替换成你训练时配置的模型输入尺寸:
!python object_detection/export_tflite_graph_tf2.py \ --pipeline_config_path models/myssd_mobile/pipeline.config \ --trained_checkpoint_dir models/myssd_mobile \ --output_directory exported_models/tflite_model \ --input_shape=1,300,300,3 \ --ssd_use_regular_nms=true
步骤2:修改TFLite转换代码
转换时添加维度保留配置,避免输出被降维:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model( 'exported_models/tflite_model/saved_model', signature_keys=['serving_default'] ) converter.target_spec.supported_ops = [ tf.lite.OpsSet.TFLITE_BUILTINS, tf.lite.OpsSet.SELECT_TF_OPS ] converter.experimental_new_converter = True # 可选添加量化优化,减少模型体积提升树莓派运行速度 converter.optimizations = [tf.lite.Optimize.DEFAULT] tflite_model = converter.convert() open("converted_model.tflite", "wb").write(tflite_model)
方案二:直接修改推理脚本(无需重新转换,快速验证)
找到TFLite_detection_image.py中获取模型输出的代码段,添加维度兼容逻辑:
import numpy as np # 原获取输出的代码 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']) # 添加如下维度兼容逻辑 if len(boxes.shape) == 1: boxes = np.expand_dims(boxes, axis=0) if len(scores.shape) == 0: scores = np.expand_dims(scores, axis=0) if len(classes.shape) == 0: classes = np.expand_dims(classes, axis=0) # 再取第一个batch的结果 boxes = boxes[0] scores = scores[0] classes = classes[0] num = int(num_detections)
内容的提问来源于stack exchange,提问作者Obada Zayadneh
相关产品推荐
相关产品推荐

