keras NotImplementedError:参数在`__init__`中的图层必须覆盖`get_config`

ruyhziif  于 2023-08-06  发布在  其他
关注(0)|答案(6)|浏览(133)

我试图使用model.save()保存我的TensorFlow模型,但是-我得到了这个错误。
模型摘要如下所示:Model Summary
Transformer模型的代码:

def transformer(vocab_size, num_layers, units, d_model, num_heads, dropout, name="transformer"):
    inputs = tf.keras.Input(shape=(None,), name="inputs")
    dec_inputs = tf.keras.Input(shape=(None,), name="dec_inputs")

    enc_padding_mask = tf.keras.layers.Lambda(
        create_padding_mask, output_shape=(1, 1, None),
        name='enc_padding_mask')(inputs)
    # mask the future tokens for decoder inputs at the 1st attention block
    look_ahead_mask = tf.keras.layers.Lambda(
        create_look_ahead_mask,
        output_shape=(1, None, None),
        name='look_ahead_mask')(dec_inputs)
    # mask the encoder outputs for the 2nd attention block
    dec_padding_mask = tf.keras.layers.Lambda(
        create_padding_mask, output_shape=(1, 1, None),
        name='dec_padding_mask')(inputs)

    enc_outputs = encoder(
        vocab_size=vocab_size,
        num_layers=num_layers,
        units=units,
        d_model=d_model,
        num_heads=num_heads,
        dropout=dropout,
    )(inputs=[inputs, enc_padding_mask])

    dec_outputs = decoder(
        vocab_size=vocab_size,
        num_layers=num_layers,
        units=units,
        d_model=d_model,
        num_heads=num_heads,
        dropout=dropout,
    )(inputs=[dec_inputs, enc_outputs, look_ahead_mask, dec_padding_mask])

    outputs = tf.keras.layers.Dense(units=vocab_size, name="outputs")(dec_outputs)

    return tf.keras.Model(inputs=[inputs, dec_inputs], outputs=outputs, name=name)

字符串
我不明白为什么它会给出这个错误,因为模型训练得很好。如果你能帮忙的话,我将不胜感激。
我的保存代码以供参考:

print("Saving the model.")
saveloc = "C:/tmp/solar.h5"
model.save(saveloc)
print("Model saved to: " + saveloc + " succesfully.")

2jcobegt

2jcobegt1#

这不是一个bug,这是一个功能。
这个错误让你知道TF无法保存你的模型,因为它将无法加载它。
具体来说,它将无法重新示例化您的自定义Layer类:encoderdecoder

**要解决这个问题,只需根据您添加的新参数覆盖他们的get_config**方法。

层配置是包含层配置的Python字典(可序列化)。相同的层可以稍后从该配置中恢复(没有其训练的权重)。
例如,如果你的encoder类看起来像这样:

class encoder(tf.keras.layers.Layer):

    def __init__(
        self,
        vocab_size, num_layers, units, d_model, num_heads, dropout,
        **kwargs,
    ):
        super().__init__(**kwargs)
        self.vocab_size = vocab_size
        self.num_layers = num_layers
        self.units = units
        self.d_model = d_model
        self.num_heads = num_heads
        self.dropout = dropout

    # Other methods etc.

字符串
那么你只需要覆盖这个方法:

def get_config(self):

        config = super().get_config().copy()
        config.update({
            'vocab_size': self.vocab_size,
            'num_layers': self.num_layers,
            'units': self.units,
            'd_model': self.d_model,
            'num_heads': self.num_heads,
            'dropout': self.dropout,
        })
        return config


当TF看到这一点时(对于两个类),您将能够保存模型。
因为现在当模型被加载时,TF将能够从config重新示例化相同的层。

**Layer.from_config**的源代码可以更好地了解它的工作原理:

@classmethod
def from_config(cls, config):
  return cls(**config)

u91tlkcl

u91tlkcl2#

此问题是由keras和tf.keras库之间的混合导入引起的,这是不受支持的。
到处使用tf.keras.models或usrkeras.models
你不应该在这些库之间混合导入,因为这样做将不起作用,并产生各种奇怪的错误消息。这些错误随着keras和tensorflow的版本而变化。

eoigrqb6

eoigrqb63#

我建议您尝试以下操作:

model = tf.keras.Model(...)
model.save_weights("some_path")
...
model.load_weights("some_path")

字符串

mf98qq94

mf98qq944#

我认为简单的解决方案是为gpu安装tensorflow==2.4.2 tensorflow-gpu==2.4.2,我面对这个问题并调试了一整天,但没有解决。最后我安装了较旧的稳定版本,错误消失了

h7wcgrx3

h7wcgrx35#

添加 * 保存_format='tf'* 参数为我解决了这个问题:

model.save(MODEL_PATH, save_format='tf')

字符串

ru9i0ody

ru9i0ody6#

我们有两种模型保存格式:
Tensorflow SavedModel或HDF 5
1/SavedModel保存执行图。因此,SavedModels能够保存自定义对象,如子类模型和自定义层,而不需要原始代码。如果您只提供已保存模型的名称,例如model.save('my_model'),则保存的模型格式将默认为TF savedmodel。
2/要以HDF 5格式保存自定义对象:
你的对象中有get_config方法,也可以有from_config类方法等(参见文档)如果你提供了H5文件扩展名,例如model.save('my_model.h5'),则保存的模型格式将为HDF 5。
我使用了第一种方法(保存的模型格式),它与我一起工作,没有错误

相关问题