web-dev-qa-db-ja.com

Kerasのマルチクラス分類で、binary_crossentropyがcategorical_crossentropyよりも正確なのはなぜですか?

Kerasを使用して畳み込みニューラルネットワークを作成する方法を学習しています。 MNISTデータセットの高精度を取得しようとしています。

どうやらcategorical_crossentropyは2つを超えるクラス用であり、binary_crossentropyは2つのクラス用です。 10桁なので、categorical_crossentropyを使用する必要があります。ただし、数十のモデルをトレーニングおよびテストした後、binary_crossentropyは常にcategorical_crossentropyを大幅に上回ります。

Kaggleでは、binary_crossentropyと10エポックを使用して99 +%の精度を得ました。一方、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'])
17
Leo Jiang

短い答え:それはではないです。

これを確認するには、精度を「手動」で計算してみてください。これにより、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

それがそうであるように見えるの理由は、ケラスが実際にどのように正確に推測するかについての微妙な問題であり、損失に応じて選択した関数(モデルのコンパイルに単にmetrics=['accuracy']を含める場合)。

ソースコード をチェックすると、Kerasは単一の精度メトリックを定義するのではなく、binary_accuracycategorical_accuracyなどのいくつかの異なるメトリックを定義します。何が起こるか 内部で は、損失関数としてバイナリクロスエントロピーを選択していて、特定の精度メトリックを指定していないため、Keras(間違って...)は、binary_accuracy、そしてこれはそれが返すものです。

それを回避するには、つまり、必要なcategorical精度を取得しながら、損失関数として実際にバイナリクロスエントロピーを使用します(原則としてこれは問題ありません)。手元の問題(つまり、MNIST分類)では、次のようにモデルのコンパイルでcategorical_accuracyを明示的に要求する必要があります。

from keras.metrics import categorical_accuracy
model.compile(loss='binary_crossentropy', optimizer='adamax', metrics=[categorical_accuracy])

上記で示したように、テストセットのトレーニング、スコアリング、および予測を行った後、2つのメトリックは同じになるはずです。

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

(HTから この素晴らしい答え に似た問題があり、問題の理解に役立ちました...)

[〜#〜] update [〜#〜]:私の投稿の後で、この問題はすでに この回答で特定されていることがわかりました

14
desertnaut

まず、binary_crossentropyは、2つのクラスがある場合ではありません。

「バイナリ」という名前は、バイナリ出力に適合しているためで、softmaxの各番号は0または1を目指しています。ここでは、出力の各番号をチェックします。

Categorical_entropyは分類の問題であるという事実を利用しているため、結果は説明されません。

データを読み取るときに、サンプルごとにクラスが1つだけあることを確信していますか?それは私が与えることができる唯一の説明です。

2
Labo