NotImplementedError:\`__init__\` 中带有参数的图层必须覆盖 \`get_config\`

新手上路,请多包涵

我正在尝试使用 model.save() 保存我的 TensorFlow 模型,但是 - 我收到此错误。

此处提供了模型摘要: 模型摘要

变压器模型的代码:

 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.")

原文由 Shaheryar Sohail 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 625
2 个回答

这不是一个错误,这是一个功能。

此错误让您知道 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 将能够从配置中重新实例化同一层。


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

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

原文由 EliadL 发布,翻译遵循 CC BY-SA 4.0 许可协议

此问题是由 keras 和 tf.keras 库之间混合导入引起的,这是不支持的。

到处使用 tf.keras.models 或 usr keras.models

你永远不应该在这些库之间混合导入,因为它不会工作并且会产生各种奇怪的错误消息。这些错误随着 keras 和 tensorflow 的版本而改变。

原文由 John Nash 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题