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'])
短い答え:それはではないです。
これを確認するには、精度を「手動」で計算してみてください。これにより、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_accuracy
とcategorical_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 [〜#〜]:私の投稿の後で、この問題はすでに この回答で特定されていることがわかりました 。
まず、binary_crossentropyは、2つのクラスがある場合ではありません。
「バイナリ」という名前は、バイナリ出力に適合しているためで、softmaxの各番号は0または1を目指しています。ここでは、出力の各番号をチェックします。
Categorical_entropyは分類の問題であるという事実を利用しているため、結果は説明されません。
データを読み取るときに、サンプルごとにクラスが1つだけあることを確信していますか?それは私が与えることができる唯一の説明です。