You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keras训练正常的模型保存后加载出现Graph disconnected错误如何解决

Keras模型训练正常、保存后加载报Graph disconnected错误解决方案

错误根源

报错的核心原因是你手动遍历子模型层调用时,保留了原各个子模型自带的输入层节点,同时直接修改层的_name私有属性破坏了Keras内部的依赖记录。训练时动态图模式下可以正常运行,但保存序列化时计算图依赖没有正确记录,加载时校验失败。具体来说报错里提到的InputLucaSchifoso就是model_LucaSchifoso自带的输入层,该节点没有和你自定义的全局输入层input_layer建立正确的连接,加载时找不到该节点的上游输入,因此报计算图断开错误。

解决方法

  • 方案一:权重加载法(无需修改训练代码,可快速解决问题)
    不需要直接加载整个保存的模型文件,先完全复现训练时的模型构建代码,得到和训练时结构完全一致的空白模型,再单独加载权重即可:
# 复制训练时的模型构建代码,得到结构完全一致的空白modellone
modellone = build_your_model() 
# 仅加载保存的权重
modellone.load_weights("best/variables/variables")
  • 方案二:重构模型构建逻辑(彻底解决序列化问题,方便后续保存加载)
  1. 不要直接遍历子模型的每层逐个调用,也不要手动修改层的_name私有属性,改为先截断子模型到需要的输出层,再整体调用截断后的子模型,自动规避子模型输入层残留的问题:
layers_dict = {}
extra_out = {}
input_layer = tfk.layers.Input(shape=input_shape, name="input_layer")

for model_name in preprocessing_function_dict:
    # 预处理层
    proc_out = tfk.layers.Lambda(
        preprocessing_function_dict[model_name], name="lambda_" + model_name
    )(input_layer)
    if model_name == "LucaSchifoso":
        # 截断子模型到第10层输出,自动丢弃原输入层
        sub_model = tfk.Model(
            inputs=model_dict[model_name].input,
            outputs=model_dict[model_name].layers[10].output,
            name=f"sub_{model_name}"
        )
        luca_out = sub_model(proc_out)
        # 后续自定义处理
        extra_out["LucaSchifoso"] = tfkl.Flatten(name='flatten_LucaSchifoso1')(
            tfkl.MaxPooling2D(name='maxpool_LucaSchifoso1', pool_size = (3, 3))(luca_out)
        )
    else:
        # 其他模型截断到第2层输出
        sub_model = tfk.Model(
            inputs=model_dict[model_name].input,
            outputs=model_dict[model_name].layers[2].output,
            name=f"sub_{model_name}"
        )
        layers_dict[model_name] = sub_model(proc_out)

# 拼接层
concatenate_layer = tfkl.Concatenate()([
    layers_dict["InceptionV3"],
    layers_dict["MobileNetV2"],
    extra_out["LucaSchifoso"], 
    layers_dict["Resnet50"]
])
  1. 尽量避免使用Lambda层封装预处理逻辑,改为实现自定义可序列化层,重写get_config方法,保证序列化时依赖不会丢失。
  2. 子模型加载时直接指定name参数,让Keras自动给子模型所有层添加前缀,无需手动修改层名避免冲突。
  • 方案三:加载时指定自定义对象
    如果用到了自定义层、自定义损失或者Lambda层,加载时在custom_objects参数中传入对应的对象即可:
model = tf.keras.models.load_model('best', custom_objects={
    # 传入你用到的自定义层、预处理函数等
})

内容的提问来源于stack exchange,提问作者Axelitama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 12:36:04