【问题标题】:How to optimize multiple loss functions separately in Keras?如何在 Keras 中分别优化多个损失函数?
【发布时间】:2019-10-04 04:48:47
【问题描述】:

我目前正在尝试在 Keras 中构建具有三种不同损失函数的深度学习模型。第一个损失函数是典型的均方误差损失。其他两个损失函数是我自己构建的,它发现了从输入图像和输出图像进行的计算之间的差异(这段代码是我正在做的简化版本)。

def p_autoencoder_loss(yTrue,yPred):

    def loss(yTrue, y_Pred):
       return K.mean(K.square(yTrue - yPred), axis=-1)

    def a(image):
       return K.mean(K.sin(image))

    def b(image):
       return K.sqrt(K.cos(image))


a_pred = a(yPred)
a_true = a(yTrue)

b_pred = b(yPred)
b_true = b(yTrue)

empirical_loss = (loss(yTrue, yPred))
a_loss = K.mean(K.square(a_true - a_pred))
b_loss = K.mean(K.square(b_true - b_pred))
final_loss = K.mean(empirical_loss + a_loss + b_loss)
return final_loss

但是,当我使用此损失函数进行训练时,它根本无法很好地收敛。我想尝试的是分别最小化三个损失函数,而不是通过将它们添加到一个损失函数中。

我基本上想在这里Tensorflow: Multiple loss functions vs Multiple training ops 做第二个选项,但是以 Keras 的形式。我还希望损失函数彼此独立。有没有简单的方法来做到这一点?

【问题讨论】:

    标签: tensorflow keras


    【解决方案1】:

    您的 keras 模型中可以有 3 个输出,每个输出都有您指定的损失,然后 keras 支持对这些损失进行加权。然后它还会在输出中为您生成最终的组合损失,但它将进行优化以减少所有三个损失。不过要小心这一点,因为根据您的数据/问题/损失,您可能会发现它会稍微停顿,或者如果您有损失互相争斗,它会很慢。然而,这需要使用functional API。我不确定这是否真的实现了单独的优化器实例,但是我认为这与我知道的纯 Keras 中的结果一样接近,而无需开始编写更复杂的 TF 训练机制。

    例如:

    loss_out1 = layers.Dense(1, activation='sigmoid', name='loss1')(x)
    loss_out2 = layers.Dense(1, activation='sigmoid', name='loss2')(x)
    loss_out3 = layers.Dense(1, activation='sigmoid', name='loss3')(x)
    
    model = keras.Model(inputs=[input],
                    outputs=[loss1, loss2, loss3])
    model.compile(optimizer=keras.optimizers.RMSprop(1e-3),
              loss=['binary_crossentropy', 'categorical_crossentropy', 'custom_loss1'],
              loss_weights=[1., 1., 1.])
    

    这应该从上面的 (x) 编译一个具有 3 个输出的模型。编译时,您将输出设置为列表,并将损失和损失权重设置为列表。请注意,当您 fit() 时,您也需要将目标输出作为列表提供三次,例如[y, y, y] 因为您的模型现在有三个输出。

    我不是 Keras 专家,但它非常高级,我不知道使用纯 Keras 的另一种方式。希望有人可以提出更好的解决方案来纠正我!

    【讨论】:

    • 我已经用三个输出制作了新模型,但现在我遇到了一个新错误“检查模型目标时出错:您传递给模型的 Numpy 数组列表不是模型预期的大小。预计会看到 3 个数组,但得到了以下 1 个数组的列表:[array([[0., 0., 0., ..., 0., 0., 0 .]" 错误是因为模型期望每个损失函数有三个不同的输入。有没有办法修复它,以便可以用一个输入计算三个损失函数?
    • 很难在没有看到代码的情况下回答这个问题。也许提出一个新问题并从这里链接到它?简而言之,您需要将输出作为我上面所说的列表传递 3 次,每次损失一次。它们都可以像我上面所说的一样。不确定您实际上是否遇到了需要 3 个输入而是损失函数的输入(即目标)的问题,您做错了。
    【解决方案2】:

    由于只有一个输出,所以可以做的事情很少:

    1. 监控各个损失组件以查看它们如何变化。

    def a_loss(y_true, y_pred):
        a_pred = a(yPred)
        a_true = a(yTrue)   
        return K.mean(K.square(a_true - a_pred))
    
    model.compile(....metrics=[...a_loss,b_loss])
    

    2.加权其中 lambda_a 和 lambda_b 为超参数的损失分量。

    final_loss = K.mean(empirical_loss + lambda_a * a_loss + lambda_b * b_loss)
    
    1. 使用不同的损失函数,如 SSIM。

    https://www.tensorflow.org/api_docs/python/tf/image/ssim

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 2021-11-21
      • 1970-01-01
      • 2017-02-24
      • 2021-01-22
      相关资源
      最近更新 更多