我想实施一个两步学习过程,其中:
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(…)
请注意,优化器保持不变,只有损失函数发生变化。我想顺利地继续训练,但具有不同的损失功能。根据this post的说法,重新编译模型失去了优化器状态。问题:
a)即使我使用相同的优化器,例如Adam,我也会失去优化器状态吗? b)如果a)的答案是肯定的,那么关于如何在不重置优化器状态的情况下将损失函数更改为新函数的任何建议?
编辑: 正如Simon Caby所建议并基于this thread,我创建了一个自定义损失函数,其中两个损失计算取决于时代数。但是,它对我不起作用。我的方法:
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
在初始化current_epoch
之后我编译如下:
current_epoch = K.variable(0.)
model.compile(optimizer=opt, loss=loss_wrapper(5, current_epoch), metrics=...)
要更新current_epoch
,我创建一个回调:
class NewCallback(Callback):
def __init__(self, current_epoch):
self.current_epoch = current_epoch
def on_epoch_end(self, epoch, logs={}):
K.set_value(self.current_epoch, epoch)
model.fit_generator(..., callbacks=[NewCallback(current_epoch)])
回调正确地更新每个时期的self.current_epoch
。但更新未达到自定义丢失功能。相反,current_epoch
永远保持初始化值,并且永远不会执行loss_2
。
欢迎任何建议,谢谢!
我的答案:a)是的,你应该制作自己的学习率调度程序,以便控制它:
keras.callbacks.LearningRateScheduler(schedule, verbose=0)
b)是的,你可以创建自己的损失函数,包括在两种不同的损失方法之间徘徊的函数。请参阅:“高级Keras - 构建复杂的自定义损失和指标”https://towardsdatascience.com/advanced-keras-constructing-complex-custom-losses-and-metrics-c07ca130a618