为什么binary_crossentropy比分类_crossentropy更准确用于Keras中的多类分类?

Leo*_*ang 15 machine-learning neural-network deep-learning conv-neural-network keras

我正在学习如何使用Keras创建卷积神经网络.我正试图获得MNIST数据集的高精度.

显然categorical_crossentropy是2个以上的课程,binary_crossentropy2个课程.由于有10个数字,我应该使用categorical_crossentropy.然而,经过数十种模型的培训和测试,binary_crossentropy始终表现出色categorical_crossentropy.

在Kaggle,我使用了99 +%的精确度binary_crossentropy和10个时代.同时,categorical_crossentropy即使使用30个时代,我也无法使用97%以上(这不是很多,但我没有GPU,所以训练需要永远).

这就是我的模型现在的样子:

model = Sequential()
model.add(Convolution2D(100, 5, 5, border_mode='valid', input_shape=(28, 28, 1), init='glorot_uniform', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(100, 3, 3, init='glorot_uniform', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.3))
model.add(Flatten())
model.add(Dense(100, init='glorot_uniform', activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(100, init='glorot_uniform', activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(10, init='glorot_uniform', activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='adamax', metrics=['accuracy'])
Run Code Online (Sandbox Code Playgroud)

des*_*aut 13

简短回答:事实并非如此.

要看到这一点,只需尝试"手动"计算准确度,您将看到它与Keras报告的model.evaluate方法不同:

# Keras reported accuracy:
score = model.evaluate(x_test, y_test, verbose=0) 
score[1]
# 0.99794011611938471

# Actual accuracy calculated manually:
import numpy as np
y_pred = model.predict(x_test)
acc = sum([np.argmax(y_test[i])==np.argmax(y_pred[i]) for i in range(10000)])/10000
acc
# 0.98999999999999999
Run Code Online (Sandbox Code Playgroud)

它的原因似乎是一个相当微妙的问题,当Keras实际猜测使用哪种精度时,取决于您选择的损失函数,当您简单地包含metrics=['accuracy']在模型编译中时.

如果您检查源代码,Keras没有定义一个准确的度量,但有几个不同的,其中binary_accuracycategorical_accuracy.会发生什么引擎盖下的是,既然你选择了二进制交叉熵作为损失函数,并没有规定特定的准确性度量,Keras(错误...)推断出你感兴趣的binary_accuracy,而这也正是它返回.

为了避免这种情况,即使用确实二进制交叉熵作为损失函数(没有错,原则上),同时还获得了绝对的由手(即MNIST分类)的问题,要求的精度,你应该问明确为categorical_accuracy模型汇编如下:

from keras.metrics import categorical_accuracy
model.compile(loss='binary_crossentropy', optimizer='adamax', metrics=[categorical_accuracy])
Run Code Online (Sandbox Code Playgroud)

在我上面展示的训练,评分和预测测试集之后,现在两个指标是相同的,因为它们应该是:

sum([np.argmax(y_test[i])==np.argmax(y_pred[i]) for i in range(10000)])/10000 == score[1]
# True
Run Code Online (Sandbox Code Playgroud)

(HT对这个类似问题的答案很有帮助,这有助于我理解这个问题...)

更新:在我的帖子之后,我发现这个问题已经在这个答案中被识别出来了.


Lab*_*abo 5

首先,当有两个类时,binary_crossentropy 不是。

“二进制”名称是因为它适用于二进制输出,并且 softmax 的每个数字的目标是 0 或 1。这里,它检查输出的每个数字。

它不能解释您的结果,因为 categorical_entropy 利用了它是一个分类问题的事实。

您确定当您读取数据时,每个样本只有一个类别吗?这是我能给出的唯一解释。


归档时间:

查看次数:

9968 次

最近记录:

7 年,2 月 前