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

Keras自定义类模型保存触发NotImplementedError问题求助

Why can't I save my custom Keras Model subclass but can save a Sequential model?

刚从PyTorch转Keras的话,确实容易踩这个坑,我来给你把问题讲明白:

核心原因:Keras模型的两种构建方式差异

Keras里有两种主要的模型构建方式,它们对模型序列化(也就是save()操作)的支持不一样:

  1. 子类化模型(你最开始用的方式):这种方式继承tf.keras.Model,在call()方法里定义前向传播逻辑,属于动态图模式。Keras没法自动追踪你在call()里写的所有操作细节,也就没法完整保存整个模型的结构和计算图,所以调用save()就会抛出NotImplementedError,提示你只能用save_weights()来保存权重参数。
  2. 静态图模型(Sequential/Functional API):像你后来改成的Sequential模型,或者用Functional API拼接的模型,属于静态图范畴——每一层的输入输出连接关系都是显式定义好的,Keras可以完整记录模型的结构、权重和配置,自然支持完整的save()操作。

针对你的情况的解决方案

如果你想继续用子类化模型

只能保存和加载权重,不能直接保存整个模型结构:

# 保存权重
mynet.save_weights('mynet_weights.h5')

# 加载权重(注意:子类化模型需要先运行一次前向传播初始化权重)
new_mynet = MyNet()
# 喂一个样本让模型构建权重形状
new_mynet(tf.ones(shape=(1, 3, 224, 224)))
new_mynet.load_weights('mynet_weights.h5')

如果你需要完整保存模型(结构+权重)

优先选择Sequential或者Functional API来构建模型,就像你后来做的那样。比如用Functional API写你的模型也可以:

inputs = tf.keras.Input(shape=(3,224,224))
x = tf.keras.layers.Conv2D(32, 5, strides=(2,2), data_format='channels_first')(inputs)
x = tf.keras.layers.BatchNormalization(axis=1)(x)
x = tf.keras.layers.Activation('relu')(x)
x = tf.keras.layers.GlobalAveragePooling2D(data_format='channels_first')(x)
outputs = tf.keras.layers.Dense(10)(x)

my_net_functional = tf.keras.Model(inputs=inputs, outputs=outputs)
# 同样可以正常save
my_net_functional.save('mynet_functional.hdf5')

简单总结:子类化模型胜在灵活,适合复杂自定义逻辑;Sequential/Functional胜在便捷,支持完整的模型序列化和很多内置工具,根据你的需求选就好~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 08:47:40