我目前正在尝试在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形式。我还希望损失函数彼此独立。有没有简单的方法可以做到这一点?
答案 0 :(得分:0)
由于只有一个输出,因此可以完成的工作很少:
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 :(得分:0)
您的keras模型中可能有3个输出,每个输出都有您指定的损失,然后keras支持加权这些损失。然后,它还会在输出中为您生成最终的组合损耗,但是它将进行优化以减少所有三个损耗。请对此保持警惕,尽管根据您的数据/问题/损失,您可能会发现它停滞不前,或者如果您在互相抗衡中有损失,则可能会变慢。但是,这需要使用functional API。我不确定这是否真正实现了单独的优化器实例,但是我认为您将尽我所能而不必开始编写更复杂的TF训练机制,就可以得到纯净的Keras。
例如:
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的另一种方法。希望有人可以通过更好的解决方案来纠正我!