【问题标题】:Keras: Custom loss function with training data not directly related to modelKeras:具有与模型不直接相关的训练数据的自定义损失函数
【发布时间】:2020-02-12 21:14:47
【问题描述】:

我正在尝试将我用 tensorflow 层编写的 CNN 转换为在 tensorflow 中使用 keras api(我正在使用 TF 1.x 提供的 keras api),并且在编写自定义损失函数来训练模型时遇到问题.

根据本指南,在定义损失函数时,它需要参数 (y_true, y_pred) https://www.tensorflow.org/guide/keras/train_and_evaluate#custom_losses

def basic_loss_function(y_true, y_pred):
    return ...

但是,在我看到的每个示例中,y_true 都与模型直接相关(在简单的情况下,它是网络的输出)。在我的问题中,情况并非如此。如果我的损失函数依赖于一些与模型张量无关的训练数据,如何实现?

具体来说,这是我的问题:

我正在尝试学习在成对图像上训练的图像嵌入。我的训练数据包括图像对和图像对之间匹配点的注释(图像坐标)。输入特征只是图像对,网络是在孪生配置中训练的。

我能够使用 tensorflow 层成功实现这一点,并使用 tensorflow 估计器成功地对其进行训练。 我当前的实现从一个大型的 tf 记录数据库构建一个 tf 数据集,其中的特征是一个包含图像和匹配点数组的字典。在我可以轻松地将这些图像坐标数组输入到损失函数之前,但目前尚不清楚如何执行此操作。

【问题讨论】:

  • keras.io/examples/variational_autoencoder 也许这个例子可以提供一些关于如何在 (y_true, y_pred) 模式崩溃时写入损失的见解。看起来我应该尝试使用自定义损失函数 model.add_loss,但我仍然不清楚如何提供数据,特别是考虑到我的数据不适合内存。
  • 如果你展示你如何训练你的模型,你使用了什么损失等等,它会容易得多。文字看不懂。
  • 主要我们需要知道你的模型输出什么,你的损失函数是什么,它的输入是什么,以及你如何使用点数组。
  • 我想我现在明白了,并更新了下面的 hack 以包含不是“样本到样本”的外部数据。

标签: tensorflow keras tf.keras


【解决方案1】:

我经常使用一种技巧,即通过Lambda 层计算模型中的损失。 (例如,当损失与真实数据无关,并且模型实际上没有要比较的输出时)

在函数式 API 模型中:

def loss_calc(x):
    loss_input_1, loss_input_2 = x #arbirtray inputs, you choose
                                   #according to what you gave to the Lambda layer

    #here you use some external data that doesn't relate to the samples
    externalData = K.constant(external_numpy_data)


    #calculate the loss
    return the loss

使用模型本身的输出(损失中使用的张量)

loss = Lambda(loss_calc)([model_output_1, model_output_2])

创建输出损失而不是输出的模型:

model = Model(inputs, loss)

创建一个用于编译的虚拟 keras 损失函数:

def dummy_loss(y_true, y_pred):
    return y_pred #where y_pred is the loss itself, the output of the model above

model.compile(loss = dummy_loss, ....)

使用根据样本数量正确调整大小的任何虚拟数组进行训练,它将被忽略:

model.fit(your_inputs, np.zeros((number_of_samples,)), ...)

另一种方法是使用自定义训练循环。

不过,这还有很多工作要做。

虽然您使用的是TF1,但您仍然可以在代码的最开头打开eager execution,并执行与TF2 类似的操作。 (tf.enable_eager_execution())

按照教程进行自定义训练循环:https://www.tensorflow.org/tutorials/customization/custom_training_walkthrough

在这里,您可以自己计算任何关于您想要的任何结果的梯度。这意味着您无需遵循 Keras 的培训标准。


最后,您可以使用model.add_loss 建议的方法。 在这种情况下,您计算损失的方法与我在第一个答案中所做的相同。并将这个损失张量传递给add_loss

您可能可以使用loss=None 编译模型(不确定),因为您将使用其他损失,而不是标准损失。

在这种情况下,您的模型的输出也可能是None,您应该适合y=None

【讨论】:

  • 你也可以给this similar question一些建议吗?我无法从您的回答中得出结论,我应该如何解决我的问题。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2022-01-18
  • 2020-11-25
  • 2021-02-21
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多