我目前正在尝试通过 keras/tensorflow 构建神经网络并解决一些示例问题。目前我试图了解如何通过 model.save()/.load() 正确保存和加载我当前的模型。我希望,如果一切设置正确,加载预训练模型并继续训练应该不会破坏我之前的准确性,而只是从我离开的地方继续。
然而,事实并非如此。加载模型后,我的准确度开始大幅波动,需要一段时间才能真正恢复到之前的准确度:
首次运行
继续运行
在通过各种可能的解释深入研究之后(没有一个适用于我的发现)我想我找到了原因:
<罢工> 我使用 tf.keras.optimizers.Adam 进行权重优化,并在检查其初始化程序后
def __init__(self, [...], **kwargs):
super(Adam, self).__init__(**kwargs)
with K.name_scope(self.__class__.__name__):
self.iterations = K.variable(0, dtype='int64', name='iterations')
[...]
def get_config(self):
config = {
'lr': float(K.get_value(self.lr)),
'beta_1': float(K.get_value(self.beta_1)),
'beta_2': float(K.get_value(self.beta_2)),
'decay': float(K.get_value(self.decay)),
'epsilon': self.epsilon,
'amsgrad': self.amsgrad
}
似乎“迭代”计数器总是重置为 0,当整个模型被保存为它不是配置字典的一部分时,它的当前值既不存储也不加载。这似乎与 model.save 保存 “优化器的状态,允许在您停止的地方准确地恢复训练。” 的说法相矛盾(https://keras.io/getting-started/faq/)。由于迭代计数器是控制 Adam 算法中学习率指数“丢失”的计数器
1. / (1. + self.decay * math_ops.cast(self.iterations,
K.dtype(self.decay))))
我的模型将始终以初始“大”学习率重新启动,即使我将 model.fit() 中的“initial_epoch”参数设置为保存我的模型的实际纪元编号(参见上面上传的图片).
所以我的问题是:
罢工>- <罢工>
- 这是有意为之的行为吗?
- 如果是这样,这与 keras 常见问题解答中引用的 model.save()“准确地在您停止的地方恢复训练”的陈述一致吗?
有没有办法真正保存和恢复 Adam 优化器包括迭代计数器无需编写我自己的优化器(我已经发现这是一个可能的解决方案,但我想知道是否真的没有更简单的方法)
编辑 我找到了原因/解决方案:我在 load_model 之后调用了 model.compile,这会在保持权重的同时重置优化器(另请参见 Does model.compile() initialize all the weights and biases in Keras (tensorflow backend)?)
最佳答案
iterations
值已恢复,如下面的代码片段所示。
model.save('dense_adam_keras.h5')
mdl = load_model('dense_adam_keras.h5')
print('iterations is ', K.get_session().run(mdl.optimizer.iterations))
iterations is 46
当调用'load_model
'时,调用deserialize
方法创建优化器对象,然后调用set_weights
方法恢复来自保存的权重的优化器状态。
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/keras/optimizers.py
关于python - 为什么在 Keras 中 Adam.iterations 总是设置为 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56851288/