Keras+TensorFlow训练二分类模型时ModelCheckpoint序列化报错求助
问题背景
在TensorFlow 2.10、Ubuntu 22.04、Python 3.9环境下,进行二分类图像分类模型训练时,配置ModelCheckpoint回调保存最优H5模型触发JSON序列化错误,注释该回调后训练可正常运行。核心报错信息:
TypeError: Unable to serialize [2.0896919 2.1128857 2.1081853] to JSON. Unrecognized type <class 'tensorflow.python.framework.ops.EagerTensor'>.
报错原因
H5格式保存完整模型时,ModelCheckpoint需要将模型配置序列化为JSON格式,但模型中存在未转换为Python原生类型的EagerTensor(比如自定义层参数、自定义指标返回值等),JSON无法识别TensorFlow的EagerTensor类型,导致序列化失败。
解决方法
1. 改用SavedModel格式保存(推荐)
SavedModel是TensorFlow原生的模型保存格式,对Tensor对象兼容性更好,无需手动处理类型转换。只需修改ModelCheckpoint的filepath,去掉.h5后缀:
callbacks = [ ModelCheckpoint(filepath="best_model", save_best_only=True, monitor="val_loss"), EarlyStopping(monitor='val_loss', patience=patience) ]
后续加载模型可直接使用tf.keras.models.load_model("best_model")。
2. 修复自定义组件的序列化逻辑
如果必须使用H5格式,检查模型中的自定义层、自定义损失或自定义指标,确保在get_config方法中将所有EagerTensor转换为Python原生类型(如numpy数组或列表):
class CustomLayer(tf.keras.layers.Layer): def __init__(self, some_tensor_param, **kwargs): super().__init__(**kwargs) self.some_tensor_param = some_tensor_param def get_config(self): config = super().get_config() # 将EagerTensor转为numpy数组后转成列表 config['some_tensor_param'] = self.some_tensor_param.numpy().tolist() return config
3. 调整TensorFlow版本
TensorFlow 2.10存在部分H5模型序列化的已知bug,可尝试降级到2.9.x版本或升级到2.11+版本,这些版本修复了相关兼容性问题。
4. 仅保存模型权重
如果不需要保存完整模型结构,可设置save_weights_only=True,只保存权重文件,绕过模型配置的JSON序列化步骤:
callbacks = [ ModelCheckpoint(filepath="best_model_weights.h5", save_best_only=True, monitor="val_loss", save_weights_only=True), EarlyStopping(monitor='val_loss', patience=patience) ]
后续加载权重时,需先重建模型结构再加载:
model = build_your_model() # 调用自定义的模型构建函数 model.load_weights("best_model_weights.h5")
内容的提问来源于stack exchange,提问作者Hassan Abedi

