保存含自定义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
相关产品推荐
相关产品推荐

