python - NotImplementedError:在 `__init__` 中有参数的层必须覆盖 `get_config`
问题描述
我正在尝试使用 保存我的 TensorFlow 模型model.save()
,但是 - 我收到了这个错误。
此处提供模型摘要: 模型摘要
变压器模型的代码:
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.")
解决方案
这不是一个错误,这是一个功能。
此错误让您知道 TF 无法保存您的模型,因为它无法加载它。
具体来说,它将无法重新实例化您的自定义Layer
类:encoder
和decoder
.
要解决这个问题,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.xml 重新实例化同一层。
Layer.from_config
的源代码可以更好地理解它的工作原理:
@classmethod
def from_config(cls, config):
return cls(**config)
推荐阅读
- html - 使内部 div 填充列高度 - 适用于 Chrome,但不适用于 Safari/Firefox
- json - 将 Koa 请求正文转换为字符串时转义特殊字符
- python - 从断言中给出的字符串中提取电子邮件地址并在列表中给出它们的函数
- jgit - 区分 JGit 中的轻量级标签和带注释的标签
- django - 如何在 Django 中打印单个对象的所有值?
- ios - UIPresentationController 呈现导航控制器视图
- .net - 框架提供的 SetSocketOption 枚举具有重复的条目。这是如何运作的?
- html - HTML 电子邮件 CSS:将表格和表格内容居中,最受支持的解决方案
- html - 角度响应式设计 - 当屏幕小于某个宽度时添加换行符
- flask - 如何在 gitlab CI 中将 docker-compose flask 项目部署到 AWS ECS