Keras自定义类模型保存触发NotImplementedError问题求助
Why can't I save my custom Keras Model subclass but can save a Sequential model?
刚从PyTorch转Keras的话,确实容易踩这个坑,我来给你把问题讲明白:
核心原因:Keras模型的两种构建方式差异
Keras里有两种主要的模型构建方式,它们对模型序列化(也就是save()操作)的支持不一样:
- 子类化模型(你最开始用的方式):这种方式继承
tf.keras.Model,在call()方法里定义前向传播逻辑,属于动态图模式。Keras没法自动追踪你在call()里写的所有操作细节,也就没法完整保存整个模型的结构和计算图,所以调用save()就会抛出NotImplementedError,提示你只能用save_weights()来保存权重参数。 - 静态图模型(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
相关产品推荐
相关产品推荐

