Keras 中基于输入数据的自定义损失函数

Posted

技术标签:

【中文标题】Keras 中基于输入数据的自定义损失函数【英文标题】:Custom loss function in Keras based on the input data 【发布时间】:2019-08-22 01:32:19 【问题描述】:

我正在尝试使用 Keras 创建自定义损失函数。我想根据输入计算损失函数并预测神经网络的输出。

我尝试在 Keras 中使用 customloss 函数。我认为 y_true 是我们为训练提供的输出,而 y_pred 是神经网络的预测输出。以下损失函数与 Keras 中的“mean_squared_error”损失相同。

def customloss(y_true, y_pred):
    return K.mean(K.square(y_pred - y_true), axis=-1)

除了 mean_squared_error 损失之外,我还想使用神经网络的输入来计算自定义损失函数。有没有办法将输入作为 customloss 函数的参数发送到神经网络。

谢谢。

【问题讨论】:

***.com/a/66966915/10375049 【参考方案1】:

对于您提出的问题,我遇到了 2 个解决方案。

    您可以将输入张量作为参数传递给自定义损失包装函数。
    def custom_loss(i):

        def loss(y_true, y_pred):
            return K.mean(K.square(y_pred - y_true), axis=-1) + something with i...
        return loss

    def baseline_model():
        # create model
        i = Input(shape=(5,))
        x = Dense(5, kernel_initializer='glorot_uniform', activation='linear')(i)
        o = Dense(1, kernel_initializer='normal', activation='linear')(x)
        model = Model(i, o)
        model.compile(loss=custom_loss(i), optimizer=Adam(lr=0.0005))
        return model

the accepted answer here中也提到了这个解决方案

    您可以使用输入中的额外数据列填充标签并编写自定义损失。如果您只需要输入中的一个/几个特征列,这将很有帮助。
    def custom_loss(data, y_pred):

        y_true = data[:, 0]
        i = data[:, 1]
        return K.mean(K.square(y_pred - y_true), axis=-1) + something with i...


    def baseline_model():
        # create model
        i = Input(shape=(5,))
        x = Dense(5, kernel_initializer='glorot_uniform', activation='linear')(i)
        o = Dense(1, kernel_initializer='normal', activation='linear')(x)
        model = Model(i, o)
        model.compile(loss=custom_loss, optimizer=Adam(lr=0.0005))
        return model


    model.fit(X, np.append(Y_true, X[:, 0], axis =1), batch_size = batch_size, epochs=90, shuffle=True, verbose=1)

这个解决方案也可以在这里找到thread。

当我不得不在损失中使用输入特征列时,我只使用了第二种方法。我使用了带有标量参数的第一种方法;但我相信张量输入也可以。

【讨论】:

我参加聚会很晚了,但你的第二个解决方案真是太棒了!非常非常实用,棒棒哒。 这样做我得到:tensorflow.python.eager.core._SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor 'mel_specs:0' shape=(None, None, 512) dtype=float32>]。并不是说我将tf.data.Dataset 传递给fit() 函数。知道这里有什么问题吗? 我在使用第一种方法时遇到了问题。我收到此错误UnboundLocalError: local variable 'input_tensor' referenced before assignment 在第二种方法中,2 列作为 y 传递给 model.fit(x, y)。如果我们使用经过训练的模型进行预测,它预测的是哪一列? @阿纳金 我刚刚实施了您的第二个解决方案,它就像一个魅力!我同意让-皮埃尔的观点——“天才”。谢谢【参考方案2】:

您可以使用另一个将输入张量作为参数的函数来包装您的自定义损失:

def customloss(x):
    def loss(y_true, y_pred):
        # Use x here as you wish
        err = K.mean(K.square(y_pred - y_true), axis=-1)
        return err

    return loss

然后编译你的模型如下:

model.compile('sgd', customloss(x))

x 是您的输入张量。

注意:未经测试。

【讨论】:

什么是 y_true 和 y_pred?它是一个输入的张量还是标量?我想发送一个对应于 y_true 的输入 x。是针对 ytrain 张量的每个元素(Keras 模型的输出)还是针对整个张量单独计算损失?谢谢。 y_true 是标签的张量,而y_pred 是网络预测的张量。至于另一个问题,我不明白问的是什么。 y_pred 将用于模型的某些输入。我想访问那个输入张量。有没有办法将输入张量发送到 customloss 函数?谢谢。 可以通过x的参数customloss传递输入张量

以上是关于Keras 中基于输入数据的自定义损失函数的主要内容,如果未能解决你的问题,请参考以下文章

Keras 中具有样本权重的自定义损失函数

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

需要内部层输出作为标签的自定义损失函数的 Keras 实现

Keras 中的自定义损失函数(IoU 损失函数)和梯度误差?

R Keras 中的自定义损失函数

图像分割 - Keras 中的自定义损失函数