[解決済み】同じ問題で binary_crossentropy と categorical_crossentropy が異なる性能を示すのはなぜか?
質問
私は、テキストをトピックごとに分類するCNNを学習させようとしている。バイナリクロスエントロピーの場合は80%の精度、カテゴリクロスエントロピーの場合は50%の精度が得られます。
これはなぜなのか、理解できません。マルチクラス問題なのだから、カテゴリカルクロスエントロピーを使わなければならず、バイナリクロスエントロピーの結果は意味がないということではないのでしょうか?
model.add(embedding_layer)
model.add(Dropout(0.25))
# convolution layers
model.add(Conv1D(nb_filter=32,
filter_length=4,
border_mode='valid',
activation='relu'))
model.add(MaxPooling1D(pool_length=2))
# dense layers
model.add(Flatten())
model.add(Dense(256))
model.add(Dropout(0.25))
model.add(Activation('relu'))
# output layer
model.add(Dense(len(class_id_index)))
model.add(Activation('softmax'))
そして、次のようにコンパイルします。
categorical_crossentropy
を損失関数とする。
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
または
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
直感的には、なぜカテゴリカルクロスエントロピーを使いたいのか理解できるのですが、なぜバイナリで良い結果が得られ、カテゴリカルで悪い結果が得られるのか理解できません。
どのように解決するのですか?
バイナリクロスエントロピーとカテゴリカルクロスエントロピーの性能差の原因は、ユーザーxtof54がすでに 彼の回答は以下の通りです。 すなわち
Kerasのメソッドで計算された精度
evaluate
は、単に 2つ以上のラベルでbinary_crossentropyを使用した場合、間違っています。
もっと詳しく、実際に根本的な問題を示し、それを説明し、改善策を提示したいと思います。
この動作はバグではありません。根本的な理由は、Kerasの実際の動作にある、かなり微妙な& 文書化されていない問題なのです。
推測
を含む場合、選択した損失関数に応じて、どの精度を使用するかを決定します。
metrics=['accuracy']
をモデルコンパイル時に使用します。言い換えれば、最初のコンパイルオプション
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
が有効なのは、あなたの2番目のものです。
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
は期待通りの結果を得られませんが、その理由はバイナリクロスエントロピーの使用ではありません(少なくとも原理的には、絶対的に有効な損失関数です)。
それはなぜか?を確認すると
メトリクスソースコード
Kerasは単一の精度指標を定義しているわけではなく、いくつかの異なる指標を定義しているのですが、そのうちの一つが
binary_accuracy
と
categorical_accuracy
. 何が起こるか
ボンネットの下
は、損失関数としてバイナリクロスエントロピーを選択し、特定の精度メトリックを指定していないため、Kerasは(誤って...)、あなたが
binary_accuracy
であり、これが返されるものです。
categorical_accuracy
.
ということを検証してみましょう。 MNIST CNNの例 をKerasで実行し、以下のように修正しました。
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # WRONG way
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=2, # only 2 epochs, for demonstration purposes
verbose=1,
validation_data=(x_test, y_test))
# Keras reported accuracy:
score = model.evaluate(x_test, y_test, verbose=0)
score[1]
# 0.9975801164627075
# 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.98780000000000001
score[1]==acc
# False
これを改善するために、つまり、損失関数として実際にバイナリクロスエントロピーを使いながら(私が言ったように、少なくとも原理的には何も問題はありません)、なおかつ
カテゴリカル
の精度が必要な場合は、明示的に
categorical_accuracy
を以下のようにモデルコンパイルする。
from keras.metrics import categorical_accuracy
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=[categorical_accuracy])
MNISTの例では、上に示したように、テストセットの学習、スコアリング、予測を行った後、2つのメトリクスは、あるべき姿として同じになりました。
# Keras reported accuracy:
score = model.evaluate(x_test, y_test, verbose=0)
score[1]
# 0.98580000000000001
# Actual accuracy calculated manually:
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.98580000000000001
score[1]==acc
# True
システムの設定です。
Python version 3.5.3
Tensorflow version 1.2.1
Keras version 2.0.4
アップデイト : 投稿後、この問題がすでに この回答 .
関連
-
[解決済み】Keras - KerasRegressorを使用して予測を実行する方法は?
-
[解決済み] イプシロン貪欲q学習におけるイプシロンと学習率の減衰について
-
[解決済み] エアフローとKubeflowパイプラインの違いは何ですか?
-
[解決済み] コスト関数、線形回帰、シータをハードコーディングしないようにする。オクターブ
-
[解決済み] サポートベクターマシンに対する人工ニューラルネットワークの優位性は何ですか?[終了しました]
-
[解決済み】線形回帰とロジスティック回帰の違いは何ですか?[クローズド]
-
[解決済み】同じ問題で binary_crossentropy と categorical_crossentropy が異なる性能を示すのはなぜか?
-
[解決済み】機械学習モデルの損失と精度の解釈の仕方【終了しました
-
[解決済み] Kerasにおける多対一および多対多のLSTMの例
-
[解決済み] Appleはどのように電子メールの日付、時間、アドレスを見つけるのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] PyTorchのバックワード関数
-
[解決済み] RuntimeError: 次元が範囲外([-1, 0]の範囲にあると期待されたが、1が得られた)
-
[解決済み] コスト関数、線形回帰、シータをハードコーディングしないようにする。オクターブ
-
[解決済み】ニューラルネットワークにおけるバイアスの役割とは?[クローズド]
-
[解決済み】データセットをトレーニングセットとバリデーションセットに分割する方法には法則性があるのでしょうか?[クローズド]
-
[解決済み] なぜ人工ニューラルネットワークの入力を正規化する必要があるのですか?[クローズド]
-
[解決済み] Kerasにおける多対一および多対多のLSTMの例
-
[解決済み] Diablo 2をプレイするための人工ニューラルネットワークを視覚的に学習させる方法とは?
-
[解決済み] 期待値最大化手法の直感的な説明とは?[クローズド]
-
[解決済み] フィーチャーとラベルの違いは何ですか?[クローズド]