神经网络中多类别,多标签分类任务的损失函数是什么?


64

我正在训练一个神经网络,以将一组对象分类为n类。每个对象可以同时属于多个类(多类,多标签)。

我读到,对于多类问题,通常建议使用softmax和分类交叉熵代替mse作为损失函数,并且我或多或少地了解了为什么。

对于我的多标签问题,使用softmax当然是没有意义的,因为每种类别的概率都应该彼此独立。因此,我的最后一层就是S型单元,将其输入压缩到每个类的概率范围为0..1。

现在我不确定应该使用什么损失函数。观察分类交叉熵的定义,我认为它不适用于此问题,因为它将仅考虑应为1的神经元输出,而忽略其他神经元的输出。

二进制交叉熵听起来更合适,但是我只看到它曾经针对单个输出神经元的二进制分类问题提到过。

我正在使用python和keras进行培训,以防万一。


1
我认为softmax “将每个类别的输入压缩到0.1.1的概率范围的S型单位”。
Hong Ooi

您可以将softmax用作损失函数,然后使用概率对数据进行多标签处理。
balboa

Answers:


30

如果您使用的是keras,只需将Sigmoids放在输出层上,将binary_crossentropy放在cost函数上。

如果您使用的是tensorflow,则可以使用sigmoid_cross_entropy_with_logits。但就我而言,这种直接损失函数并未收敛。所以我最终使用了显式的S型交叉熵损失。您可以在此示例中制作自己的(yln(sigmoid(logits))+(1y)ln(1sigmoid(logits)))

与softmax不同,Sigmoid不会给出周围的概率分布作为输出,而是给出独立的概率。nclasses

如果平均而言,为任何行分配的标签较少,则可以使用softmax_cross_entropy_with_logits,因为在类互斥的情况下,由于这种损失,所以不需要这样。所需要的只是标签的每一行都是有效的概率分布。如果不是,则梯度的计算将不正确。


尊敬的Alok,您能否向OP解释他们将如何使用此功能,以及为什么这样做有意义?正如您将在游览中看到的那样,网站上不鼓励仅链接答案。
Antoine Vernet

一个很好的简短解释可以在keras github上找到:github.com/fchollet/keras/issues/741
Dror Hilman

1
使用交叉熵时,不建议编写自己的成本函数- 可能会遇到数值稳定性问题。有关讨论,请参见github.com/tensorflow/tensorflow/issues/2462
kbrose

一件事是多标签,另一件事是多标签多类。Sigmoid将输出压缩在0和1之间,但是OP具有多个类,因此输出应为Eg 0-10。因此,输出应为:[0,5,2,3,1] <---这不是Sigmoid做。
mimoralea

我应该先在成本函数中使用tf.round(logits)还是直接从隐藏层到tf.nn.sigmoid ....使用logits?
和尚(

9

更新(18/04/18):旧的答案仍然被证明对我的模型有用。诀窍是分别对分区函数和分布建模,从而利用softmax的功能。

考虑您的观察向量包含标签。 (如果样本i包含标签m,则为1,否则为0)。因此,目标是以每个样本的方式对矩阵建模。因此,模型评估。考虑扩展以实现两个属性:ymyim=δimF(yi,xi)=logP(yi|xi)yim=ZP(ym)

  1. 分布函数:mP(ym)=1
  2. 分区函数:估计标签数Z

然后是分别对两者建模的问题。最好使用softmax层对分布函数进行建模,而可以使用线性单位对分区函数进行建模(在实践中,我将其裁剪为。更复杂的建模(例如泊松单元)可能会更好地工作)。然后,您可以选择应用分布式损失(在分配上分配KL,在分区上分配MSE),也可以在其产品上尝试以下损失。max(0.01,output)

实际上,优化器的选择也有很大的不同。我使用分解法的经验是,它在Adadelta下效果最佳(Adagrad对我不起作用,尚未尝试RMSprop,SGD的性能受参数影响)。

关于乙状结肠的旁注:我当然已经尝试过乙状结肠+交叉熵,但没有奏效。该模型仅倾向于预测,而无法捕获分布函数的变化。(又名,它在某种程度上对分区建模很有用,其背后可能存在数学原因)Z

更新:(随机的想法)似乎使用Dirichlet程序会允许一些事先合并的标签数目吗?

更新:通过实验,修改后的KL散度仍然倾向于提供多类输出,而不是多标签输出。


(旧答案)

我对S形交叉熵的体验不是很愉快。目前,我正在使用改良的KL散度。它采取的形式

Loss(P,Q)=x|P(x)Q(x)||logP(x)Q(x)|=x|(P(x)Q(x))logP(x)Q(x)|
其中是目标伪分布,是预测的伪分布(但是函数实际上是对称的,因此实际上并不重要)P(x)Q(x)

由于未归一化,它们被称为伪分布。因此,如果您有2个用于特定样本的标签,则可以。xP(x)=2

Keras推动

def abs_KL_div(y_true, y_pred):
    y_true = K.clip(y_true, K.epsilon(), None)
    y_pred = K.clip(y_pred, K.epsilon(), None)
    return K.sum( K.abs( (y_true- y_pred) * (K.log(y_true / y_pred))), axis=-1)

在我的特定数据集上,adam要比rmsprop
shadi '18

如果您将这种损失用于培训,那么在测试阶段该如何做?也将softmax用于预测,但是如何选择阈值来确定多标签类别?
karl_TUM


0

实际上在张量流中您仍然可以将其sigmoid_cross_entropy_mean用作多标签中的损失计算功能,我非常确认


给我们提供文档链接
伊夫林

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.