Keras 中的 TensorBoard 回调不尊重适合的初始时期?

Posted

技术标签:

【中文标题】Keras 中的 TensorBoard 回调不尊重适合的初始时期?【英文标题】:TensorBoard Callback in Keras does not respect initial_epoch of fit? 【发布时间】:2018-05-24 19:49:47 【问题描述】:

我正在尝试在单个显卡上并行训练多个模型。为了实现这一点,我需要从保存的权重中恢复模型的训练,这不是问题。 model.fit() 方法甚至有一个参数 initial_epoch,它可以让我告诉模型加载的模型在哪个纪元上。但是,当我将 TensorBoard 回调传递给 fit() 方法以监控模型的训练时,Tensorboard 上的所有数据都显示在 x=0 上。

有没有办法克服这个问题并调整张量板上的时代?

顺便说一句:我正在运行 Keras 2.0.6 和 Tensorflow 1.3.0。

self.callbacks = [TensorBoardCallback(log_dir='./../logs/'+self.model_name, histogram_freq=0, write_graph=True, write_images=False, start_epoch=self.step_num)]
self.model.fit(x=self.data['X_train'], y=self.data['y_train'], batch_size=self.input_params[-1]['batch_size'], epochs=1, validation_data=(self.data['X_test'], self.data['y_test']), verbose=verbose, callbacks=self.callbacks, shuffle=self.hyperparameters['shuffle_data'], initial_epoch=self.step_num)
self.model.save_weights('./weights/%s.hdf5'%(self.model_name))
self.model.load_weights('./weights/%s.hdf5'%(self.model_name))
self.model.fit(x=self.data['X_train'], y=self.data['y_train'], batch_size=self.input_params[-1]['batch_size'], epochs=1, validation_data=(self.data['X_test'], self.data['y_test']), verbose=verbose, callbacks=self.callbacks, shuffle=self.hyperparameters['shuffle_data'], initial_epoch=self.step_num)
self.model.save_weights('./weights/%s.hdf5'%(self.model_name))

Tensorboard 上的结果图看起来像这样,这不是我所希望的:

更新:

当将epochs=10 传递给第一个model.fit() 时,TensorBoard 中会显示 10 个 epoch 结果(见图)。

但是,当重新加载模型并运行它(附加相同的回调)时,回调的 on_epoch_end 方法永远不会被调用。

【问题讨论】:

你运行的是哪个版本的 keras?我正在查看master's branch,而Tensorboard 回调不是start_epoch 参数(而是由调用者传递给Tensorboard#on_epoch_end 我正在运行 Keras 2.0.6,但正如帖子中提到的,initial_epoch 参数没有传递给回调,而是传递给 keras 的 model.fit() 方法。 我知道initial_epoch是fit的参数,但是你的代码sn-p的第一行是self.callbacks = [TensorBoardCallback(... start_epoch=self.step_num)],这很奇怪。关于这种并行训练的另一个问题:这些模型有不同的名称吗? logs里面有多个目录吗? 哦,是的,你说得对,对不起。我尝试使用 TensorBoard 回调本身并尝试用我的纪元编号替换 on_epoch_end() 中的纪元。虽然当我训练重新加载的模型时似乎没有调用该方法。我并不是要在代码中留下这个抱歉。是的,每个模型都有不同的名称,它们都显示在 Tensorboard 图表上,但仅适用于 epoch 0。 别担心。回到问题:我认为模型在恢复之前被重新创建(因此被重命名)。如果您希望它们在图中重新出现为同一条线,它们必须具有相同的名称 => 包含在同一个子文件夹中。尽管如此,从图表上看,您似乎甚至没有在一个时期内训练过任何模型。尝试训练它们超过一个 epoch 并检查图中是否出现一条线(不仅是一个点);将 smoothing 拖到 0 并在“水平轴”处检查 step 而不是 relative。然后将新图表上传到您的问题。 【参考方案1】:

事实证明,当我将集数传递给 model.fit() 以告诉它要训练多长时间时,它必须是指定的 initial_epoch 中的数字。所以如果 initial_epoch=self.step_num 那么,如果我想训练 10 集,epochs=self.step_num+10。

【讨论】:

"请注意,结合initial_epochepochs 应理解为“最终时期”。该模型没有针对时期给定的多次迭代进行训练,而只是直到时期已达到索引时期的数量。” - the docs 所以使用epochs=step + epochsinitial_epoch=step * epochs【参考方案2】:

假设我们刚刚开始拟合我们的模型,我们的第一次 epoch 计数是 30 (请忽略其他参数,只看 epochsinitial_epoch) model.fit(train_dataloader,validation_data = test_dataloader,epochs =30,steps_per_epoch = len(train_dataloader),callbacks = callback_list)

现在说,在 30 个 epoch 之后,我们想通过更改我们的 Adam 优化器(或不优化器)学习率从第 31 个 epoch 重新开始(您可以在 tesnorboard 中看到这一点)

所以我们可以做的是

model.optimizer.learning_rate = 0.0005

model1.fit(train_dataloader,validation_data = test_dataloader,initial_epoch=30,epochs =55,steps_per_epoch = len(train_dataloader),callbacks = callback_list)

=> 所以这里 initial_epoch= 我们上次离开训练的地方; epochs= initial_epoch+num_epoch 我们要为第二次拟合运行

【讨论】:

以上是关于Keras 中的 TensorBoard 回调不尊重适合的初始时期?的主要内容,如果未能解决你的问题,请参考以下文章

在 Keras 上使用回调 Tensorboard 时出现 AttributeError:“模型”对象没有属性“run_eagerly”

使用 keras 在 tensorboard 中显示分类图像

使用 Keras,当我将 Tensorboard 回调添加到我的神经网络时,准确性会降低。我该如何解决?

我可以通过 Keras 将图像添加到 Tensorboard 吗?

将 TensorBoard 与 Keras Tuner 一起使用

Keras - 是不是可以在 Tensorboard 中查看模型的权重和偏差