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

使用tfa.optimizers.MultiOptimizer保存模型时触发TypeError:张量不可JSON序列化问题求助

TypeError When Saving Model with tfa.optimizers.MultiOptimizer and ModelCheckpoint

我之前踩过一模一样的坑!当你用tfa.optimizers.MultiOptimizer配合ModelCheckpoint回调保存模型时,出现的TypeError: ('Not JSON Serializable:', <tf.Tensor ...>)错误,本质是MultiOptimizer内部的梯度相关张量没有被正确处理——ModelCheckpoint保存模型时会尝试序列化优化器的状态,但默认的MultiOptimizer序列化逻辑会把未计算的梯度张量也包含进去,而这些张量是无法转成JSON格式的。

下面给你两个可行的解决方案,亲测有效:

方案1:自定义可序列化的MultiOptimizer包装类

我们可以写一个简单的包装类,重写序列化和反序列化方法,确保只保存必要的优化器配置,而不是带梯度的张量:

import tensorflow as tf
import tensorflow_addons as tfa
import tensorflow.keras.layers as l
import tensorflow.keras as ke
import numpy as np

# 自定义可序列化的MultiOptimizer
class SerializableMultiOptimizer(tfa.optimizers.MultiOptimizer):
    def get_config(self):
        # 重写get_config,只保留可序列化的优化器配置和层索引
        base_config = super().get_config()
        # 将优化器序列化为配置字典,替换原有的优化器对象
        base_config["optimizers_and_layers"] = [
            (tf.keras.optimizers.serialize(opt), layers)
            for opt, layers in self.optimizers_and_layers
        ]
        return base_config

    @classmethod
    def from_config(cls, config, custom_objects=None):
        # 反序列化时重建优化器和层的对应关系
        optimizers_and_layers = [
            (tf.keras.optimizers.deserialize(opt_cfg, custom_objects=custom_objects), layers)
            for opt_cfg, layers in config["optimizers_and_layers"]
        ]
        return cls(optimizers_and_layers)

然后修改你的模型构建函数,注意你原来的分层逻辑有问题——你的模型只有2层(Input层和Dense层),model.layers[:5]会包含所有层,model.layers[5:]是空列表,我帮你调整成合理的分层:

def build_model_1():
    model_input = l.Input(shape=(32,1))
    x = l.Dense(1)(model_input)
    model = ke.Model(inputs=model_input, outputs=x)
    
    optimizers = [tf.keras.optimizers.Adam(), tf.keras.optimizers.Adam()]
    # 修正分层:用第一个优化器训练Input层,第二个训练Dense层
    optimizers_and_layers = [(optimizers[0], model.layers[:1]), (optimizers[1], model.layers[1:])]
    # 使用自定义的可序列化优化器
    optimizer = SerializableMultiOptimizer(optimizers_and_layers)
    
    model.compile(optimizer=optimizer, loss='mse', metrics='mse')
    return model

方案2:改用SavedModel格式保存(更简单)

如果不想自定义类,直接把ModelCheckpoint的保存格式改成TensorFlow原生的SavedModel格式就行,它对复杂优化器的兼容性更好,不需要序列化到JSON:

# 注意不要加.h5后缀,SavedModel是文件夹形式
model_checkpoint = ke.callbacks.ModelCheckpoint(
    'best_model',
    monitor='val_mse', 
    mode='min', 
    save_best_only=True, 
    verbose=1,
    save_format='tf'  # 指定用SavedModel格式
)

验证效果

把上面任意一个方案替换到你的代码里,再运行训练,第一个epoch结束后ModelCheckpoint就能正常保存模型了,不会再出现序列化错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:03:14