我正在训练CNN按主题对文本进行分类。当我使用二进制交叉熵时,我得到~80%的准确率,使用分类交叉熵时,我得到~50%的准确率。

我不明白为什么会这样。这是一个多类问题,这是不是意味着我必须使用分类交叉熵而二元交叉熵的结果是没有意义的?

model.add(embedding_layer)
model.add(Dropout(0.25))
# convolution layers
model.add(Conv1D(nb_filter=32,
                    filter_length=4,
                    border_mode='valid',
                    activation='relu'))
model.add(MaxPooling1D(pool_length=2))
# dense layers
model.add(Flatten())
model.add(Dense(256))
model.add(Dropout(0.25))
model.add(Activation('relu'))
# output layer
model.add(Dense(len(class_id_index)))
model.add(Activation('softmax'))

然后我用categorical_crossentropy作为损失函数编译它:

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

or

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

直观地说,我为什么要使用分类交叉熵,我不明白为什么我用二进制得到好的结果,而用分类得到的结果很差。


当前回答

这本书的主要观点得到了出色的侦探作品《沙漠》(desernaut)的圆满回答。然而,在某些情况下,BCE(二元交叉熵)可能会产生与CCE(分类交叉熵)不同的结果,并且可能是首选。虽然上面分享的经验法则(选择哪种损失)适用于99%的情况,但我想在这个讨论中添加一些新的维度。

OP有一个软最大激活,这将抛出一个概率分布作为预测值。这是一个多阶层的问题。首选的损失是分类CE。本质上,这可以归结为-ln(p),其中“p”是样本中唯一正类的预测概率。这意味着负面预测在计算CE时没有作用。这是有意为之。

在极少数情况下,它可能需要让-ve的声音发挥作用。这可以通过将上述样本视为一系列二进制预测来实现。因此,如果预期为[1 0 0 0 0],预测为[0.1 0.5 0.1 0.1 0.2],则进一步分解为:

expected = [1,0], [0,1], [0,1], [0,1], [0,1]
predicted = [0.1, 0.9], [.5, .5], [.1, .9], [.1, .9], [.2, .8]

现在我们继续计算5个不同的交叉熵——分别对应上述5个预期/预测组合,并将它们相加。然后:

CE = -[ ln(.1) + ln(0.5) + ln(0.9) + ln(0.9) + ln(0.8)]

CE有一个不同的尺度,但仍然是预期值和预测值之间差异的衡量标准。唯一的区别是,在这个方案中,-ve值也与+ve值一起受到惩罚/奖励。如果您的问题是要使用输出概率(+ve和-ves)而不是使用max()来预测1 +ve标签,那么您可能需要考虑这个版本的CE。

多标签的情况下,期望= [1 0 0 0 1]?传统的方法是每个输出神经元使用一个sigmoid,而不是一个整体的softmax。这确保了输出概率是相互独立的。所以我们会得到这样的结果:

expected = [1 0 0 0 1]
predicted is = [0.1 0.5 0.1 0.1 0.9]

根据定义,CE度量两个概率分布之间的差值。但上面两个列表不是概率分布。概率分布的总和应该总是1。因此,传统的解决方法是使用与之前相同的损失方法,将期望值和预测值分解为5个单独的概率分布,继续计算5个交叉熵并将它们相加。然后:

CE = -[ ln(.1) + ln(0.5) + ln(0.9) + ln(0.9) + ln(0.9)] = 3.3

当类的数量可能非常多时——比如1000个,而每个样本中可能只有几个类时,就会出现挑战。所以期望是这样的:[1,0,0,0,0,0,0,1,0,0,0.....990 0]。预测结果可能是这样的:[。8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1.....990年0.1的)

在本例中,CE =

- [ ln(.8) + ln(.8) for the 2 +ve classes and 998 * ln(0.9) for the 998 -ve classes]

= 0.44 (for the +ve classes) +  105 (for the negative classes)

You can see how the -ve classes are beginning to create a nuisance value when calculating the loss. The voice of the +ve samples (which may be all that we care about) is getting drowned out. What do we do? We can't use categorical CE (the version where only +ve samples are considered in calculation). This is because, we are forced to break up the probability distributions into multiple binary probability distributions because otherwise it would not be a probability distribution in the first place. Once we break it into multiple binary probability distributions, we have no choice but to use binary CE and this of course gives weightage to -ve classes.

一种选择是用一个倍增器淹没-ve类的声音。所以我们将所有-ve损失乘以一个值,其中gamma < 1。在上面的例子中,gamma可以是。0001。现在损失是:

= 0.44 (for the +ve classes) +  0.105 (for the negative classes)

The nuisance value has come down. 2 years back Facebook did that and much more in a paper they came up with where they also multiplied the -ve losses by p to the power of x. 'p' is the probability of the output being a +ve and x is a constant>1. This penalized -ve losses even further especially the ones where the model is pretty confident (where 1-p is close to 1). This combined effect of punishing negative class losses combined with harsher punishment for the easily classified cases (which accounted for majority of the -ve cases) worked beautifully for Facebook and they called it focal loss.

所以在回答OP关于二进制CE在他的情况下是否有任何意义的问题时,答案是——这要看情况。在99%的情况下,传统的拇指规则是有效的,但有时这些规则可能会被弯曲甚至破坏,以适应手头的问题。

要了解更深入的治疗方法,请访问:https://towardsdatascience.com/cross-entropy-classification-losses-no-math-few-stories-lots-of-intuition-d56f8c7f06b0

其他回答

一个简单的例子下一个多类设置来说明

假设您有4个类(其中一个是编码的),下面只有一个预测

True_label = [0,1,0,0] Predicted_label = [0,0,1,0]

当使用categorical_crossentropy时,准确率仅为0,它只关心你是否得到了相关的类。

然而,当使用binary_crossentropy时,对所有类都计算精度,这个预测的准确率为50%。最终结果将是两种情况下个体准确度的平均值。

对于多类(类是互斥的)问题,建议使用categorical_crossentropy;对于多标签问题,建议使用binary_crossentropy。

在评论@Marcin的答案后,我更仔细地检查了我的一个学生的代码,在那里我发现了同样奇怪的行为,即使只有2个纪元!(所以@Marcin的解释在我的情况下不太可能)。

我发现答案其实很简单:当使用超过2个标签的binary_crossentropy时,用Keras方法evaluate计算的准确性完全错误。你可以自己重新计算准确率(首先调用Keras方法“predict”,然后计算由predict返回的正确答案的数量):你得到了真正的准确率,这比Keras的“evaluate”要低得多。

当使用categorical_crossentropy损失时,你的目标应该是分类格式的(例如,如果你有10个类,每个样本的目标应该是一个10维向量,除了对应于样本类别的索引处的1外,它都是零)。

这本书的主要观点得到了出色的侦探作品《沙漠》(desernaut)的圆满回答。然而,在某些情况下,BCE(二元交叉熵)可能会产生与CCE(分类交叉熵)不同的结果,并且可能是首选。虽然上面分享的经验法则(选择哪种损失)适用于99%的情况,但我想在这个讨论中添加一些新的维度。

OP有一个软最大激活,这将抛出一个概率分布作为预测值。这是一个多阶层的问题。首选的损失是分类CE。本质上,这可以归结为-ln(p),其中“p”是样本中唯一正类的预测概率。这意味着负面预测在计算CE时没有作用。这是有意为之。

在极少数情况下,它可能需要让-ve的声音发挥作用。这可以通过将上述样本视为一系列二进制预测来实现。因此,如果预期为[1 0 0 0 0],预测为[0.1 0.5 0.1 0.1 0.2],则进一步分解为:

expected = [1,0], [0,1], [0,1], [0,1], [0,1]
predicted = [0.1, 0.9], [.5, .5], [.1, .9], [.1, .9], [.2, .8]

现在我们继续计算5个不同的交叉熵——分别对应上述5个预期/预测组合,并将它们相加。然后:

CE = -[ ln(.1) + ln(0.5) + ln(0.9) + ln(0.9) + ln(0.8)]

CE有一个不同的尺度,但仍然是预期值和预测值之间差异的衡量标准。唯一的区别是,在这个方案中,-ve值也与+ve值一起受到惩罚/奖励。如果您的问题是要使用输出概率(+ve和-ves)而不是使用max()来预测1 +ve标签,那么您可能需要考虑这个版本的CE。

多标签的情况下,期望= [1 0 0 0 1]?传统的方法是每个输出神经元使用一个sigmoid,而不是一个整体的softmax。这确保了输出概率是相互独立的。所以我们会得到这样的结果:

expected = [1 0 0 0 1]
predicted is = [0.1 0.5 0.1 0.1 0.9]

根据定义,CE度量两个概率分布之间的差值。但上面两个列表不是概率分布。概率分布的总和应该总是1。因此,传统的解决方法是使用与之前相同的损失方法,将期望值和预测值分解为5个单独的概率分布,继续计算5个交叉熵并将它们相加。然后:

CE = -[ ln(.1) + ln(0.5) + ln(0.9) + ln(0.9) + ln(0.9)] = 3.3

当类的数量可能非常多时——比如1000个,而每个样本中可能只有几个类时,就会出现挑战。所以期望是这样的:[1,0,0,0,0,0,0,1,0,0,0.....990 0]。预测结果可能是这样的:[。8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1.....990年0.1的)

在本例中,CE =

- [ ln(.8) + ln(.8) for the 2 +ve classes and 998 * ln(0.9) for the 998 -ve classes]

= 0.44 (for the +ve classes) +  105 (for the negative classes)

You can see how the -ve classes are beginning to create a nuisance value when calculating the loss. The voice of the +ve samples (which may be all that we care about) is getting drowned out. What do we do? We can't use categorical CE (the version where only +ve samples are considered in calculation). This is because, we are forced to break up the probability distributions into multiple binary probability distributions because otherwise it would not be a probability distribution in the first place. Once we break it into multiple binary probability distributions, we have no choice but to use binary CE and this of course gives weightage to -ve classes.

一种选择是用一个倍增器淹没-ve类的声音。所以我们将所有-ve损失乘以一个值,其中gamma < 1。在上面的例子中,gamma可以是。0001。现在损失是:

= 0.44 (for the +ve classes) +  0.105 (for the negative classes)

The nuisance value has come down. 2 years back Facebook did that and much more in a paper they came up with where they also multiplied the -ve losses by p to the power of x. 'p' is the probability of the output being a +ve and x is a constant>1. This penalized -ve losses even further especially the ones where the model is pretty confident (where 1-p is close to 1). This combined effect of punishing negative class losses combined with harsher punishment for the easily classified cases (which accounted for majority of the -ve cases) worked beautifully for Facebook and they called it focal loss.

所以在回答OP关于二进制CE在他的情况下是否有任何意义的问题时,答案是——这要看情况。在99%的情况下,传统的拇指规则是有效的,但有时这些规则可能会被弯曲甚至破坏,以适应手头的问题。

要了解更深入的治疗方法,请访问:https://towardsdatascience.com/cross-entropy-classification-losses-no-math-few-stories-lots-of-intuition-d56f8c7f06b0

这完全取决于你要处理的分类问题的类型。主要有三个类别

二元分类(两个目标类), 多类分类(两个以上专属目标), 多标签分类(两个以上的非排他目标),其中多个目标类别可以同时打开。

在第一种情况下,应该使用二进制交叉熵,目标应该被编码为单热向量。

在第二种情况下,应使用分类交叉熵,并将目标编码为单热向量。

在最后一种情况下,应该使用二进制交叉熵和目标应该编码为一个热向量。每个输出神经元(或单元)被视为一个单独的随机二进制变量,整个输出向量的损失是单个二进制变量损失的乘积。因此,它是每个单个输出单元的二进制交叉熵的乘积。

二元交叉熵定义为

分类交叉熵定义为

其中c是运行在c类数量上的索引。