2017-12-19 16 views
1

私は入力データが4096項の周波数逆文書頻度で構成されるテキスト分類モデルを訓練しています。Keras:ビッグワンホットエンコーディング:binary_crossentropyまたはcategorical_crossentropy

私の出力は416種類です。各データは3つのカテゴリを持っているので、3つのものは、413個のゼロ(ワンホット・エンコーディング)

の配列である私のモデルは次のようになります。私はそれを訓練するとき

model = Sequential() 
model.add(Dense(2048, activation="relu", input_dim=X.shape[1])) 
model.add(Dense(512, activation="relu")) 
model.add(Dense(416, activation="sigmoid")) 

binary_crossentropyの損失は、1エポック後に0.185の損失と96%の精度を示します。 5エポック後、損失は0.037であり、精度は99.3%である。私はこれが間違っていると思う。ラベルが正しく分類されているので、ラベルに0がたくさんあるからだ。

私はcategorical_crossentropyの損失で訓練すると、最初の数エポックで15.0の損失と5%以下の精度を示し、5.0の損失で固着し、 50を超える)エポック。

私の状況に適しているのはどれですか(複数の1で大きなワンホットエンコーディング)?これらの得点は何を教えてくれるのですか?

EDIT:要するに

model.compile(loss='categorical_crossentropy', 
       optimizer=keras.optimizers.Adam(), 
       metrics=['accuracy']) 

model.compile(loss='binary_crossentropy', 
       optimizer=keras.optimizers.Adam(), 
       metrics=['accuracy']) 
+0

あなたの正確な 'model.compile()この記事をレビュー誰のために加え、申し訳ありません – desertnaut

+1

で'コマンド含めてください:これは*の符号化であるが*問題持ちますKerasと関係があり、stats/ML理論や実践に関係するものではありません。したがって、その場所はここにあり、クロスバリデーションではありません。 – Tutanchamunon

+0

@desertnaut各ケース – desertnaut

答えて

2

:これらはmodel.compile()声明ているあなたはloss='binary_crossentropy'を使用するときに報告した(高い)精度は、あなたのように、正しいものではありませんすでに推測している。問題の場合、推奨される損失はcategorical_crossentropyです。

ロングで

あなたのこの動作の根本的な理由は、あなたが選択した損失関数に応じて、使用する精度方法Keras実際推測ではなく、微妙な&文書化されていない問題ですモデルのコンパイルにはそのままmetrics=['accuracy']を含めます。言い換えれば、あなたの最初のコンパイルオプション

model.compile(loss='categorical_crossentropy', 
      optimizer=keras.optimizers.Adam(), 
      metrics=['accuracy'] 

は、2番目の1有効な間:

model.compile(loss='binary_crossentropy', 
      optimizer=keras.optimizers.Adam(), 
      metrics=['accuracy']) 

は、あなたが期待するものを生成しませんが、その理由は、バイナリのクロスエントロピーを使用することではありません(少なくとも原則的には、絶対的に有効な損失関数である)。

なぜですか? metrics source codeを確認した場合、Kerasでは精度メトリックは1つではなく、複数の異なるメトリックを定義しています(binary_accuracycategorical_accuracy)。 under the hoodloss='binary_crossentropy'を選択し、の具体的なメトリックを指定していないため、Keras(間違って...)はbinary_accuracyに興味があると推測しています。 に興味があります。

はのは、以下の変更で、Kerasで MNIST CNN exampleを使用して、これが事実であることを確認してみましょう:

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  

おそらく、独自のデータと上記の動作の検証が簡単です。

そして、何らかの理由で、あなたの損失関数としてバイナリクロスエントロピーを使うことを主張しているならば(私が言ったように、少なくとも原理的にはこれは間違っていませんでした)

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

MNISTの例では、トレーニングの後、スコアリング、そして私は上記を示してテストセットを予測:当面の問題で必要とされる精度カテゴリ次のように、あなたがモデルのコンパイルにcategorical_accuracyに対して明示的に依頼する必要があります次の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 
+0

ありがとうございました! 'categorical_crossentropy'は分配を期待しているのに対して、私は常に3つのものを予測しなければならないので、' categorical_crossentropy'は最終的に行く方法ではないことが私に指摘されました。そうですか?もしそうなら、categorical_accuracyで 'binary_crossentropy'を使う価値がありますか? – Tutanchamunon

+0

@Tutanchamunon私が言ったように、あなたが複数のクラスを持っているときの "カノニカル"ロスは 'categorical_crossentropy'です。しかし、(理論的には非常に貧しい)深い学習領域では、実際には、究極の裁判官は実験です!だから、あなたはそれを試してみることができます(私が上で示唆した救済策を用いて)あなたが得たものを見てください(そしてBTW、あなたはまた答えを受け入れることができます - ありがとう)。 – desertnaut

関連する問題