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

加载含自定义对象的Keras模型时出现AttributeError问题求助

解决Keras加载自定义嵌套损失模型时的AttributeError问题

问题原因

  • 你的自定义损失采用嵌套函数结构,模型保存时Keras实际记录的是内层函数conditional_BCE2,但加载时你在custom_objects中注册的是外层的conditional_BCE函数,两者无法匹配,导致Keras错误地将外层函数当作损失张量处理,触发'function' object has no attribute 'get_shape'报错。
  • 你使用的Keras 2.0.8 + TensorFlow 1.2.1属于老旧版本,对嵌套式自定义损失的序列化/反序列化支持不完善,进一步放大了这个问题。

解决方案

方案一:重构损失函数,避免嵌套结构

将嵌套式损失改为直接接收所有参数的形式,编译时通过partial绑定额外参数:

from keras import backend as K
from functools import partial
from keras.losses import register_loss

@register_loss
def conditional_BCE(y_true, y_pred, input_mask, flag):
    loss = flag * K.binary_crossentropy(y_true, y_pred) * input_mask 
    return K.sum(loss) / K.sum(input_mask)

# 训练时绑定额外参数
loss_func = partial(conditional_BCE, input_mask=input_mask_tensor, flag=flag_value)
model.compile(optimizer='adam', loss=loss_func)

加载模型时,只需在custom_objects中注册重构后的损失函数:

from keras.models import load_model

load_model('path_to_your_model.h5', custom_objects={'Self_Attention': Self_Attention, 'conditional_BCE': conditional_BCE})

方案二:匹配保存时的内层损失函数

模型保存时记录的是内层的conditional_BCE2,加载前需先生成与训练时完全一致的内层函数实例并注册:

from keras.models import load_model

# 必须使用与训练时完全相同的input_mask和flag
input_mask = ...  # 训练时传入的input_mask张量
flag = ...        # 训练时传入的flag值
custom_loss = conditional_BCE(input_mask, flag)

# 加载时注册内层函数(注意键名是conditional_BCE2)
load_model('path_to_your_model.h5', custom_objects={'Self_Attention': Self_Attention, 'conditional_BCE2': custom_loss})

方案三:升级依赖版本(推荐长期维护)

Keras 2.0.8和TensorFlow 1.2.1的自定义对象序列化机制存在诸多缺陷,升级到Python 2.7支持的较新版本(如Keras 2.2.5 + TensorFlow 1.14.0),可大幅改善这类兼容性问题,很多情况下无需修改代码即可正常加载模型。

验证步骤

  1. 若采用方案一,重新训练并保存模型,再尝试加载,确认无报错;
  2. 若采用方案二,确保input_mask和flag与训练时完全一致,加载后测试推理或继续训练的效果;
  3. 若采用方案三,升级依赖后重新加载原模型,验证功能正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 08:50:07