将Keras RetinaNet的.h5模型转为TensorFlow SavedModel时遇KeyError: 'inputs'
解决Keras RetinaNet转SavedModel的KeyError: 'inputs'问题
问题原因
keras-retinanet的自定义层(如锚点生成、检测头相关层)的call方法参数未使用标准的inputs命名,TensorFlow在序列化SavedModel时会尝试寻找名为inputs的参数,找不到就抛出KeyError。
解决方案
方案1:导出推理专用模型(推荐)
原训练模型包含训练相关分支(损失计算),先提取纯推理模型再保存,结构更符合TF序列化要求:
import tensorflow as tf from keras_retinanet import models # 加载训练好的模型 model = models.load_model("model.h5", backbone_name="resnet50") # 提取推理模型,仅保留检测输出:boxes, scores, labels inference_model = models.convert_model(model) # 运行一次推理让TF确定输入输出形状(可选但能避免序列化时的形状推断问题) dummy_input = tf.random.normal([1, 512, 512, 3]) _ = inference_model.predict(dummy_input) # 保存为SavedModel格式 inference_model.save('model_tf', save_format='tf')
方案2:手动指定输入签名保存
若需保留原模型结构,可通过tf.function包装推理逻辑并指定输入签名,明确告诉TF输入输出的规范:
import tensorflow as tf from keras_retinanet import models model = models.load_model("model.h5", backbone_name="resnet50") # 定义输入签名,根据你的训练输入尺寸调整shape参数 input_signature = [tf.TensorSpec(shape=(None, None, None, 3), dtype=tf.float32)] # 包装推理函数,指定训练模式为False(推理模式) @tf.function(input_signature=input_signature) def predict_fn(inputs): boxes, scores, labels = model(inputs, training=False) return {"boxes": boxes, "scores": scores, "labels": labels} # 保存模型并指定服务签名 tf.saved_model.save(model, 'model_tf', signatures={"serving_default": predict_fn})
方案3:修改自定义层参数名(不推荐)
找到keras-retinanet库中报错的自定义层(如AnchorBoxes、DetectionHead等),将其call方法的第一个参数改为inputs,重新训练或加载模型后保存。该方法需要修改库源码,维护性差,仅作为备选方案。
内容的提问来源于stack exchange,提问作者Egorundel
相关产品推荐
相关产品推荐

