使用不同的损失函数恢复训练

dav*_*ave 8 keras loss-function

我想实施一个两步学习过程,其中:

  1. 使用损失函数预训练几个时期的模型 loss_1
  2. 将损失函数更改为loss_2并继续训练以进行微调

目前,我的做法是:

model.compile(optimizer=opt, loss=loss_1, metrics=['accuracy'])
model.fit_generator(…)
model.compile(optimizer=opt, loss=loss_2, metrics=['accuracy'])
model.fit_generator(…)
Run Code Online (Sandbox Code Playgroud)

请注意,优化器保持不变,只有损失函数发生变化。我想顺利地继续训练,但损失函数不同。根据这篇文章,重新编译模型会失去优化器状态。问题:

a) 即使我使用相同的优化器,例如 Adam,我会丢失优化器状态吗?
b) 如果 a) 的答案是肯定的,关于如何在不重置优化器状态的情况下将损失函数更改为新函数的任何建议?

编辑:
根据 Simon Caby 的建议并基于此线程,我创建了一个自定义损失函数,其中包含两个依赖于纪元数的损失计算。但是,它对我不起作用。我的做法:

model.compile(optimizer=opt, loss=loss_1, metrics=['accuracy'])
model.fit_generator(…)
model.compile(optimizer=opt, loss=loss_2, metrics=['accuracy'])
model.fit_generator(…)
Run Code Online (Sandbox Code Playgroud)

初始化后,我编译如下current_epoch

def loss_wrapper(t_change, current_epoch):
    def custom_loss(y_true, y_pred):
       c_epoch = K.get_value(current_epoch)
       if c_epoch < t_change:
           # compute loss_1
       else:
           # compute loss_2
    return custom_loss
Run Code Online (Sandbox Code Playgroud)

为了更新current_epoch,我创建了以下回调:

current_epoch = K.variable(0.)
model.compile(optimizer=opt, loss=loss_wrapper(5, current_epoch), metrics=...)
Run Code Online (Sandbox Code Playgroud)

回调self.current_epoch正确更新每个时期。但是更新没有达到自定义损失函数。相反,current_epoch永远保持初始化值,并且loss_2永远不会执行。

欢迎任何建议,谢谢!

小智 2

我的回答:\na)是的,你可能应该制作自己的学习率调度程序以保持对它的控制:

\n\n
keras.callbacks.LearningRateScheduler(schedule, verbose=0)\n
Run Code Online (Sandbox Code Playgroud)\n\n

b)是的,您可以创建自己的损失函数,包括在两种不同损失方法之间波动的损失函数。请参阅:“高级 Keras\xe2\x80\x8a\xe2\x80\x94\xe2\x80\x8a构造复杂的自定义损失和指标”\n https://towardsdatascience.com/advanced-keras-constructing-complex-custom-losses -和-指标-c07ca130a618

\n