我正在学习如何使用Keras创建卷积神经网络。我试图获得MNIST数据集的高精度。
显然categorical_crossentropy
适用于2个以上的课程,binary_crossentropy
适用于2个课程。由于有10位数,我应该使用categorical_crossentropy
。但是,经过数十个模型的培训和测试后,binary_crossentropy
始终优于categorical_crossentropy
。
在Kaggle上,我使用binary_crossentropy
和10个时期获得了99 +%的准确率。同时,即使使用30个时代,我也无法使用categorical_crossentropy
获得97%以上(这不是很多,但我没有GPU,所以培训需要永远)。< / p>
这是我的模特现在的样子:
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'])
答案 0 :(得分:13)
简短回答:不。
要看到这一点,只需尝试计算准确度&#34;手动&#34;,您将看到它与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
它似乎的原因是一个相当微妙的问题,因为Keras实际上猜测使用哪种准确度,取决于你选择的损失函数,当你在模型编译中只包含metrics=['accuracy']
。
如果您选中source code,则Keras不会定义单个精确度指标,而是定义几个不同的精度指标,其中包括binary_accuracy
和categorical_accuracy
。 under the hood会发生什么,因为您选择了二进制交叉熵作为损失函数并且没有指定特定的准确度度量,Keras(错误地......)推断您对binary_accuracy
感兴趣,这就是它的回报。
为了避免这种情况,即确实使用二元交叉熵作为您的损失函数(原则上没有错误),同时仍然获得手头问题所需的分类精度(即MNIST分类) ),您应该在模型编译中明确询问categorical_accuracy
,如下所示:
from keras.metrics import categorical_accuracy
model.compile(loss='binary_crossentropy', optimizer='adamax', metrics=[categorical_accuracy])
在我上面展示的训练,评分和预测测试集之后,现在两个指标是相同的,应该是:
sum([np.argmax(y_test[i])==np.argmax(y_pred[i]) for i in range(10000)])/10000 == score[1]
# True
(HT到this great answer类似的问题,这有助于我理解这个问题......)
更新:在我的帖子之后,我发现此问题已在this answer中确定。
答案 1 :(得分:2)
首先,当有两个类时,binary_crossentropy不是。
&#34;二进制&#34; name是因为它适用于二进制输出,softmax的每个数目都是0或1。 在这里,它检查输出的每个数字。
它没有解释你的结果,因为categorical_entropy利用了这是一个分类问题的事实。
您确定在阅读数据时,每个样本只有一个课程吗?这是我能给出的唯一解释。