Machine learning 在Keras中,为什么二元交叉熵比分类交叉熵更准确?

Machine learning 在Keras中,为什么二元交叉熵比分类交叉熵更准确?,machine-learning,keras,neural-network,deep-learning,conv-neural-network,Machine Learning,Keras,Neural Network,Deep Learning,Conv Neural Network,我正在学习如何使用Keras创建卷积神经网络。我试图获得MNIST数据集的高精度 显然,category\u crossentropy用于2个以上的类,而binary\u crossentropy用于2个类。因为有10个数字,所以我应该使用分类\u交叉熵。然而,在训练和测试了几十个模型之后,binary\u crossentropy始终显著优于category\u crossentropy 在Kaggle上,我使用二进制交叉熵和10个历元获得了99%以上的准确率。同时,即使使用30个纪元(虽然不

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

显然,
category\u crossentropy
用于2个以上的类,而
binary\u crossentropy
用于2个类。因为有10个数字,所以我应该使用
分类\u交叉熵
。然而,在训练和测试了几十个模型之后,
binary\u crossentropy
始终显著优于
category\u crossentropy

在Kaggle上,我使用
二进制交叉熵和10个历元获得了99%以上的准确率。同时,即使使用30个纪元(虽然不算多,但我没有GPU,所以培训需要很长时间),我也无法使用
categorical\u crossentropy
获得97%以上的成绩

下面是我的模型现在的样子:

model=Sequential()
添加(卷积2D(100,5,5,border_mode='valid',input_shape=(28,28,1),init='glorot_uniform',activation='relu'))
add(MaxPooling2D(池大小=(2,2)))
添加(卷积2D(100,3,3,init='glorot_uniform',activation='relu'))
add(MaxPooling2D(池大小=(2,2)))
模型。添加(辍学(0.3))
model.add(展平())
添加(密集(100,init='glorot_uniform',activation='relu'))
模型。添加(辍学(0.3))
添加(密集(100,init='glorot_uniform',activation='relu'))
模型。添加(辍学(0.3))
添加(密集(10,init='glorot_uniform',activation='softmax'))
compile(loss='binary\u crossentropy',optimizer='adamax',metrics=['accurity'])

首先,当有两个类时,二进制交叉熵是不存在的

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

它不能解释你的结果,因为分类熵利用了这是一个分类问题的事实


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

简短回答:它是而不是

要了解这一点,只需尝试“手动”计算精度,您就会发现它与Keras使用
模型报告的精度不同。评估
方法:

#Keras报告的准确性:
分数=模型。评估(x_检验,y_检验,详细度=0)
分数[1]
# 0.99794011611938471
#手动计算的实际精度:
将numpy作为np导入
y_pred=模型预测(x_检验)
acc=sum([np.argmax(y_test[i])==np.argmax(y_pred[i]),适用于范围(10000)内的i)/10000
行政协调会
# 0.98999999999999999
这样做的原因似乎是一个相当微妙的问题,即当您在模型编译中简单地包含
metrics=['accurity']
时,Keras如何根据您选择的损失函数猜测使用哪种精度

如果选中,Keras不会定义单个精度度量,而是定义几个不同的度量,其中包括
二进制精度
分类精度
。发生的情况是,由于您选择了二进制交叉熵作为损失函数,并且没有指定特定的精度度量,Keras(错误地…)推断您对
二进制\u精度感兴趣,这就是它返回的结果

为了避免这种情况,即使用二进制交叉熵作为损失函数(原则上没有问题),同时仍然获得手头问题所需的分类精度(即MNIST分类),您应该在模型编译中明确要求
分类精度
,如下所示:

来自keras.metrics导入分类精度
compile(loss='binary\u crossentropy',optimizer='adamax',metrics=[分类精度])
在对测试集进行培训、评分和预测之后,如我上面所示,这两个指标现在应该是相同的:

sum([np.argmax(y_test[i])==np.argmax(y_pred[i]),用于范围(10000)内的i)/10000==score[1]
#真的
(HT解决了一个类似的问题,这帮助我理解了这个问题…)

更新:在我的帖子发布后,我发现这个问题已经在中被发现