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

保存含自定义WeightedSum层的Keras复合模型报NoneType错误如何解决

问题根因
  • 报错核心原因是自定义WeightedSum层中,你将add_weight生成的可训练权重存储在普通Python列表self.ensemble_weights中,Keras的模型序列化机制无法追踪普通列表内的变量,导致序列化时读取变量属性失败抛出类型错误。
  • 额外冗余问题:self.output_init变量完全不需要提前定义,直接在call方法中初始化输出张量即可,validate_shape=False的参数也会干扰序列化逻辑。
  • 缺失序列化必要方法:自定义Keras层必须实现get_config方法,才能在保存/加载时正确传递初始化参数。
修改后的自定义层代码
import tensorflow.keras as krs
import tensorflow as tf

class WeightedSum(krs.layers.Layer):
    def __init__(self, n_models=2, name='weighted_sum_0'):
        super(WeightedSum, self).__init__(name=name)
        self.n_models = n_models

    def build(self, input_shape):
        # 直接定义形状为(n_models,)的权重张量,无需循环添加+列表存储
        self.ensemble_weights = self.add_weight(
            shape=(self.n_models,),
            initializer='ones',
            trainable=True
        )
        super().build(input_shape)

    def call(self, inputs):
        # 输入是长度为n_models的张量列表,堆叠后乘权重再求和归一化
        input_stack = tf.stack(inputs, axis=-1)
        weighted_sum = tf.reduce_sum(input_stack * self.ensemble_weights, axis=-1)
        normalizer = tf.reduce_sum(self.ensemble_weights)
        return weighted_sum / normalizer

    # 实现get_config方法用于序列化参数传递
    def get_config(self):
        config = super().get_config()
        config.update({
            "n_models": self.n_models
        })
        return config

如果你坚持保留原有循环添加多个独立权重的写法,只需要把__init__中的普通列表self.ensemble_weights = []替换为可追踪列表self.ensemble_weights = krs.utils.TrackableList()即可,Keras会自动识别列表内的可训练变量。

保存&加载注意事项
  • 保存模型不需要修改原有代码,仍使用krs.models.save_model(linked_model,"test_failed_save.mdl")即可
  • 加载模型时需要通过custom_objects参数指定自定义层:
linked_model = krs.models.load_model("test_failed_save.mdl", custom_objects={"WeightedSum": WeightedSum})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 06:45:01