同时针对不同输出使用不同的损失函数,如何在Keras中实现?

13

我正在尝试制作一个网络,它可以分别输出深度图和语义分割数据。

为了训练这个网络,我想在语义分割分支上使用分类交叉熵损失函数,在输出深度图的分支上使用均方误差损失函数。

在Keras函数式API的文档中,我找不到有关如何实现两个分支的这两个损失函数的任何信息。

我是否可以同时在训练过程中使用这些损失函数,或者更好的方法是分别训练这些分支?

1个回答

19

Model.compile文档中可知:

loss:字符串(目标函数的名称)或目标函数。请参见losses。如果模型具有多个输出,您可以通过传递字典或损失列表来在每个输出上使用不同的损失。然后,该模型将最小化所有单独损失的总和。

如果您的输出有名称,则可以使用字典将名称映射到相应的损失函数:

x = Input((10,))
out1 = Dense(10, activation='softmax', name='segmentation')(x)
out2 = Dense(10, name='depth')(x)
model = Model(x, [out1, out2])
model.compile(loss={'segmentation': 'categorical_crossentropy', 'depth': 'mse'},
              optimizer='adam')
否则,使用一列损失函数(与相应的模型输出顺序相同)。
x = Input((10,))
out1 = Dense(10, activation='softmax')(x)
out2 = Dense(10)(x)
model = Model(x, [out1, out2])
model.compile(loss=['categorical_crossentropy', 'mse'], optimizer='adam')

那么对于验证集使用不同的损失函数怎么样呢?我的意思是,我正在为训练集使用权重损失函数,该训练集每个类别的示例数量不同(它是不平衡的)。但是对于验证集,我不想使用加权损失,因为它每个类别有相同数量的示例。所以我可以为验证集传递不同的损失函数吗? - W. Sam
1
如果您没有使用class_weight参数或样本权重,那么是的,您的验证损失将由与训练损失相同的函数计算。也许您可以在自定义损失中使用K.in_train_phase()函数。 - Yu-Yang
非常感谢您,Yu-Yang。那正是我在寻找的。谢谢。 - W. Sam
当然。我将发布一个带有基本示例的答案。 - Yu-Yang
基本上我所做的是:loss= K.in_train_phase(train_loss, val_loss)。我不确定这是否正确,但我会尝试实现并查看结果。 - W. Sam
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接