如何正确导出keras_cv目标检测模型以用于推理?
解决Keras CV RetinaNet模型导出推理模型的报错问题
在TensorFlow 2.12环境下使用Keras CV构建并训练RetinaNet模型后,训练和运行均正常,但使用model.export()或tf.keras.export.ExportArchive导出时出现INVALID_ARGUMENT: You must feed a value for placeholder tensor 'inputs'及TypeError: bad argument type for built-in operation错误。
正确导出步骤
问题核心是输入签名不匹配以及Keras CV模型的内部实现特性,以下是两种可行的导出方式:
方式1:使用tf.saved_model.save并指定正确输入签名
RetinaNet的输入是批量图像张量,形状应为(None, None, None, 3)(对应批量大小、图像高度、宽度、通道数),而非你之前写的(None, 3)。可以先构建带输入签名的推理函数再保存:
import tensorflow as tf import keras_cv # 假设模型已训练完成 class_mapping = ... # 你的类别映射 model = keras_cv.models.RetinaNet.from_preset( "resnet50_imagenet", num_classes=len(class_mapping), bounding_box_format="xywh") # 定义适配输入格式的推理函数 @tf.function(input_signature=[tf.TensorSpec(shape=(None, None, None, 3), dtype=tf.float32)]) def predict_fn(inputs): return model(inputs, training=False) # 保存模型 tf.saved_model.save(model, "path/to/saved_model", signatures={"serve": predict_fn})
方式2:使用Keras CV专用导出方式(推荐)
Keras CV的部分模型针对导出做了优化,导出前先传入示例输入让TensorFlow构建完整计算图,再使用model.save保存:
# 传入示例输入,触发计算图构建 sample_input = tf.random.normal((1, 512, 512, 3)) _ = model(sample_input) # 保存模型 model.save("path/to/saved_model", save_format="tf")
错误原因说明
- 输入签名错误:你之前指定的
(None, 3)是单个像素的形状,而非批量图像的形状,导致模型无法识别输入占位符。 - 计算图未完全构建:Keras CV的RetinaNet在训练时可能延迟构建部分计算图,导出前未传入示例输入的话,TensorFlow无法确定完整的输入输出张量信息,从而抛出占位符相关错误。
- 直接调用
model.call的问题:model.call是内部方法,导出时应使用model(inputs)的方式,而非直接调用call,避免内部张量处理冲突。
内容的提问来源于stack exchange,提问作者Pawel
相关产品推荐
相关产品推荐

