web-dev-qa-db-ja.com

Keras:マルチクラスNLPタスクのmodel.evaluateとmodel.predictの精度の違い

私は、次のコードを使用して、NLPタスクの簡単なモデルをkerasでトレーニングしています。変数名は、トレイン、テスト、および検証セットの説明です。このデータセットには19のクラスがあるため、ネットワークの最終層には19の出力があります。ラベルもワンホットでエンコードされます。

nb_classes = 19
model1 = Sequential()
model1.add(Embedding(nb_words,
                     EMBEDDING_DIM,
                     weights=[embedding_matrix],
                     input_length=MAX_SEQUENCE_LENGTH,
                     trainable=False))
model1.add(LSTM(num_lstm, dropout=rate_drop_lstm, recurrent_dropout=rate_drop_lstm))
model1.add(Dropout(rate_drop_dense))
model1.add(BatchNormalization())
model1.add(Dense(num_dense, activation=act))
model1.add(Dropout(rate_drop_dense))
model1.add(BatchNormalization())

model1.add(Dense(nb_classes, activation = 'sigmoid'))


model1.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
#One hot encode all labels
ytrain_enc = np_utils.to_categorical(train_labels)
yval_enc = np_utils.to_categorical(val_labels)
ytestenc = np_utils.to_categorical(test_labels)

model1.fit(train_data, ytrain_enc,
             validation_data=(val_data, yval_enc),
             epochs=200,
             batch_size=384,
             shuffle=True,
             verbose=1)

最初のエポックの後、これらの出力が得られます。

Epoch 1/200
216632/216632 [==============================] - 2442s - loss: 0.1427 - acc: 0.9443 - val_loss: 0.0526 - val_acc: 0.9826

次に、テストデータセットでモデルを評価すると、0.98前後の精度も示されます。

model1.evaluate(test_data, y = ytestenc, batch_size=384, verbose=1)

ただし、ラベルはワンホットエンコードされているため、混同行列などを生成できるようにクラスの予測ベクトルが必要です。

PREDICTED_CLASSES = model1.predict_classes(test_data, batch_size=384, verbose=1)
temp = sum(test_labels == PREDICTED_CLASSES)
temp/len(test_labels)
0.83

これは、予測されたクラスの合計が83%正確であったことを示していますが、model1.evaluateは98%の精度を示します!!ここで何が間違っていますか?損失関数は、カテゴリクラスラベルで大丈夫ですか?予測レイヤーのsigmoidアクティベーション関数の選択は大丈夫ですか?またはkerasがモデルを評価する方法に違いがありますか?何が間違っている可能性があるかを提案してください。ディープモデルを作成するのはこれが初めてなので、ここで何が問題なのかよく理解できません。

15
Sal A.

問題が見つかりました。 _metrics=['accuracy']_は、コスト関数から精度を自動的に計算します。したがって、_binary_crossentropy_を使用すると、カテゴリーの精度ではなく、バイナリの精度が示されます。 _categorical_crossentropy_を使用すると、自動的にカテゴリー精度に切り替わり、model1.predict()を使用して手動で計算した場合と同じになります。 Yu-Yangは、マルチクラス問題のコスト関数とアクティベーション関数を指摘するのが正しかった。

追伸:_metrics=['binary_accuracy', 'categorical_accuracy']_を使用することで、カテゴリー精度とバイナリ精度の両方を取得できます

32
Sal A.