无法在 Keras 2.1.0(使用 Tensorflow 1.3.0)中保存的 Keras 2.4.3(使用 Tensorflow 2.3.0)中加载 Keras 模型
Posted
技术标签:
【中文标题】无法在 Keras 2.1.0(使用 Tensorflow 1.3.0)中保存的 Keras 2.4.3(使用 Tensorflow 2.3.0)中加载 Keras 模型【英文标题】:Unable to load Keras model in Keras 2.4.3 (with Tensorflow 2.3.0) that was saved in Keras 2.1.0 (with Tensorflow 1.3.0) 【发布时间】:2020-12-24 16:59:27 【问题描述】:我正在实现一个带有自定义批量重整化层的 Keras 模型,它有 4 个权重(beta、gamma、running_mean 和 running_std)和 3 个状态变量(r_max、d_max 和 t):
self.gamma = self.add_weight(shape = shape, #NK - shape = shape
initializer=self.gamma_init,
regularizer=self.gamma_regularizer,
name='_gamma'.format(self.name))
self.beta = self.add_weight(shape = shape, #NK - shape = shape
initializer=self.beta_init,
regularizer=self.beta_regularizer,
name='_beta'.format(self.name))
self.running_mean = self.add_weight(shape = shape, #NK - shape = shape
initializer='zero',
name='_running_mean'.format(self.name),
trainable=False)
# Note: running_std actually holds the running variance, not the running std.
self.running_std = self.add_weight(shape = shape, initializer='one',
name='_running_std'.format(self.name),
trainable=False)
self.r_max = K.variable(np.ones((1,)), name='_r_max'.format(self.name))
self.d_max = K.variable(np.zeros((1,)), name='_d_max'.format(self.name))
self.t = K.variable(np.zeros((1,)), name='_t'.format(self.name))
当我检查模型时,只有 gamma、beta、running_mean 和 running_std 被保存(如预期的那样),但是当我尝试加载模型时,我收到此错误:
Layer #1 (named "batch_renormalization_1" in the current model) was found to correspond to layer batch_renormalization_1 in the save file. However the new layer batch_renormalization_1 expects 7 weights, but the saved weights have 4 elements.
所以看起来模型期望所有 7 个权重都成为保存文件的一部分,即使其中一些是状态变量。
关于如何解决这个问题的任何见解?
编辑:我意识到问题在于模型是在 Keras 2.1.0(使用 Tensorflow 1.3.0 后端)上训练和保存的,我只在使用加载模型时出现错误Keras 2.4.3(带有 Tensorflow 2.3.0 后端)。我可以使用 Keras 将模型加载到 2.1.0。
所以真正的问题是 - Keras/Tensorflow 发生了什么变化,有没有办法加载旧模型而不会收到此错误?
【问题讨论】:
【参考方案1】:您不能以这种方式加载模型,因为 keras.models.load_model 将加载已定义的配置,而不是 self_customed。
要克服这个问题,您应该重新加载模型架构并尝试从中加载权重:
model = YourModelDeclaration()
model.load_weights("checkpoint/h5file")
我在自定义 BatchNormalize 时遇到了同样的问题,所以我很确定这是加载它的唯一方法。
【讨论】:
感谢您的回复,但 load_weights 也不起作用。经过一番挖掘,我发现该错误实际上是由保存然后尝试在不同版本的 Keras/Tensorflow 上加载引起的。所以真正的问题是,是否有办法加载保存在旧版本 Keras 中的模型而不会遇到此错误。 显然,您不应该只在不同的版本中保存权重,然后将其加载到较新的版本中。但奇怪的是,即使保存整个模型也不能让你来回移动:D 这似乎是一个常见问题。在这种情况下,我尝试使用其他人创建的模型,但他们没有提供有关他们使用的 Tensorflow/Keras 版本的详细信息。因此,需要进行一些猜测和检查才能使事情正常进行。在我看来,模型加载应该跨版本工作,否则共享模型将非常困难。【参考方案2】:在 Keras 中,有两种方法可以保存模型的状态。
您可以调用model.save()
和model.save_weights()
函数。
model.save()
保存整个模型,包括权重和梯度。在您的情况下,4 个权重和 3 个状态变量都将通过此方法保存。您可以简单地使用load_model("path.h5")
方法来恢复您的模型。
model.save_weights()
函数只保存模型的权重,根本不保存结构。这里需要注意的重要一点是,Keras 检查点回调在底层使用了model.save_weights()
方法。如果您想使用检查点权重,您必须实例化您的模型结构model = customModel()
,然后将权重加载到其中model.load_weights("checkpoint.h5")
【讨论】:
感谢您的回复,但 load_weights 也不起作用。经过一番挖掘,我发现该错误实际上是由保存然后尝试在不同版本的 Keras/Tensorflow 上加载引起的。所以真正的问题是,是否有办法加载保存在旧版本 Keras 中的模型而不会遇到此错误。 据我了解,保存和加载模型时不能在 Keras/tf 版本之间移动。以上是关于无法在 Keras 2.1.0(使用 Tensorflow 1.3.0)中保存的 Keras 2.4.3(使用 Tensorflow 2.3.0)中加载 Keras 模型的主要内容,如果未能解决你的问题,请参考以下文章
tensor.shape 在使用 tf.keras 时返回一个无值列表
TypeError:张量是不可散列的。相反,使用 tensor.ref() 作为键。在 Keras 外科医生
如何在 Keras 中将 report_tensor_allocations_upon_oom 添加到 RunOptions
分割层输出时,Keras 抛出“Tensor”对象没有属性“_keras_shape”
Keras (Tensor conversion requested dtype int32 for Tensor with dtype float32: 'Tensor("embe
keras 报错 ValueError: Tensor conversion requested dtype int32 for Tensor with dtype float32: 'Ten