Tensorflow SavedModel转Keras .h5失败:_UserObject无_is_graph_network属性
解决SavedModel转Keras .h5格式及
_is_graph_network报错问题 报错原因
你遇到的AttributeError: '_UserObject' object has no attribute '_is_graph_network',本质是因为加载的TridentNet SavedModel是TensorFlow原生格式模型(以_UserObject类型存在),而非Keras原生的Model/Sequential对象。Keras的summary()、save()等方法仅支持自身定义的模型类,直接转换就会触发该错误。
解决方案:将TF SavedModel包装为Keras兼容模型
通过把加载后的TF模型包装成Keras模型,即可兼容Keras的基础函数,步骤如下:
1. 加载SavedModel
import tensorflow as tf # 替换为你的SavedModel目录路径 saved_model_dir = "./path/to/your/saved_model" loaded_tf_model = tf.saved_model.load(saved_model_dir)
2. 查看模型的输入输出签名
目标检测模型有固定的推理签名,先确认输入输出的张量名称和形状:
# 获取默认推理签名 infer_signature = loaded_tf_model.signatures["serving_default"] # 打印输入输出信息 print("输入张量列表:", list(infer_signature.structured_input_signature[1].keys())) print("输出张量列表:", list(infer_signature.structured_outputs.keys()))
执行后会得到类似input_image、detection_boxes、detection_classes这类名称,后续步骤需要用到。
3. 包装为Keras模型
根据输入输出信息,创建Keras模型包装TF推理函数:
from tensorflow.keras.layers import Input, Lambda from tensorflow.keras.models import Model # 定义输入层:替换为实际的输入张量名和形状(比如(None, None, 3)对应任意尺寸的RGB图像) input_tensor = Input(shape=(None, None, 3), name="input_image") # 替换为你的输入张量名 # 定义包装函数,调用TF模型的推理签名 def wrap_tf_model(inputs): # 调用推理签名,返回需要的输出(可根据需求返回多个输出) outputs = infer_signature(inputs) # 这里以返回检测框、类别、分数为例,替换为你的输出张量名 return [outputs["detection_boxes"], outputs["detection_classes"], outputs["detection_scores"]] # 用Lambda层包装TF模型 output_layers = Lambda(wrap_tf_model)(input_tensor) # 创建Keras模型 keras_model = Model(inputs=input_tensor, outputs=output_layers)
4. 使用Keras函数并保存为.h5格式
现在可以正常调用Keras的方法了:
# 查看模型结构(注意:仅能看到输入和Lambda层,内部TF结构不会展开) keras_model.summary() # 测试预测(输入需符合模型要求的格式,比如归一化后的图像数组) # test_image = ... # 准备你的输入图像 # predictions = keras_model.predict(test_image) # 保存为Keras .h5格式 keras_model.save("tridentnet_keras.h5")
特殊情况处理
如果你的TridentNet原本是用Keras构建后保存为SavedModel的,可尝试直接用Keras加载(需确保自定义层已定义):
from tensorflow.keras.models import load_model # 若有自定义层,需先导入或定义,再传入custom_objects参数 # keras_model = load_model(saved_model_dir, custom_objects={"TridentLayer": TridentLayer}) keras_model = load_model(saved_model_dir) keras_model.save("tridentnet.h5")
内容的提问来源于stack exchange,提问作者scuda
相关产品推荐
相关产品推荐

