如何在 Keras 中创建一个依赖于纪元数的损失函数参数?

Posted

技术标签:

【中文标题】如何在 Keras 中创建一个依赖于纪元数的损失函数参数?【英文标题】:How to create a loss function parameter that is dependent on epoch number in Keras? 【发布时间】:2019-03-13 17:53:16 【问题描述】:

我有一个带有超参数 alpha 的自定义损失函数,我想在训练中每 20 轮更改一次。损失函数类似于:

def custom_loss(x, x_pred): 
    loss1 = binary_crossentropy(x, x_pred)
    loss2 = (x, x_pred)
    return (alpha)* loss1 + (1-alpha)*loss2

根据我的研究,创建自定义回调是可行的方法。我已经查看了类似问题here 和here 的解决方案,但是这些解决方案没有实现我想要完成的回调解决方案。

我试图通过更改 keras repo 中的 LearningRateScheduler 回调来创建自定义回调

class changeAlpha(Callback):
    def __init__(self, alpha):
        super(changeAlpha, self).__init__()
        self.alpha = alpha 

    def on_epoch_begin(self, epoch, logs=):
        if epoch%20 == 0:   
             K.set_value(self.alpha, K.get_value(self.alpha) * epoch**0.95)
             print("Setting alpha to =", str(alpha))

但是,我不确定 alpha 值实际上是否对应于我的损失函数中的 alpha 值。无论如何,当我将changeAlpha 回调放入model.fit 方法时,我会收到attribute error

有人可以帮我编辑回调,使其在一定数量的时期后改变我的alpha 参数吗?

【问题讨论】:

【参考方案1】:

我理解你的想法。我认为问题在于损失函数中的 alpha 没有引用 changeAlpha 类的成员。你可以这样尝试:

instance = changeAlpha()
def custom_loss(x, x_pred): 
    loss1 = binary_crossentropy(x, x_pred)
    loss2 = (x, x_pred)
    return (instance.alpha*)* loss1 + (1-instance.alpha)*loss2

或者,您可以将 alpha 作为类变量而不是安装变量,然后将损失函数更改如下:

def custom_loss(x, x_pred): 
    loss1 = binary_crossentropy(x, x_pred)
    loss2 = (x, x_pred)
    return (changeAlpha.alpha*)* loss1 + (1-changeAlpha.alpha)*loss2

希望对你有帮助。

【讨论】:

在我看来,这仅在启用急切执行时才有效,这可能会使其非常缓慢。

以上是关于如何在 Keras 中创建一个依赖于纪元数的损失函数参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 keras 中创建自定义损失函数? (自定义加权二元交叉熵)

使用Tensorflow后端的Keras LSTM RNN中令人费解的训练损失与纪元...行为的任何原因

以 y_true 依赖于 y_pred 的方式自定义 Keras 的损失函数

Keras 中的自定义损失函数 - 遍历 TensorFlow

Keras 中带有附加变量输入的自定义损失/目标函数

keras 模型中损失函数的奇怪行为,具有预训练的卷积基础