首页 > 解决方案 > 如何在 Keras 中分别优化多个损失函数?

问题描述

我目前正在尝试在 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 but in Keras form。我还希望损失函数彼此独立。有没有一种简单的方法可以做到这一点?

标签: tensorflowkeras

解决方案


您的 keras 模型中可以有 3 个输出,每个输出都有您指定的损失,然后 keras 支持对这些损失进行加权。然后它还会在输出中为您生成最终的组合损失,但它将进行优化以减少所有三个损失。不过要小心这一点,因为根据您的数据/问题/损失,您可能会发现它会稍微停顿,或者如果您有损失相互争斗,它会很慢。然而,这需要使用功能 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 的另一种方式。希望有人可以用更好的解决方案来纠正我!


推荐阅读