web-dev-qa-db-fra.com

Keras: différence de précision model.evaluate vs model.predict dans une tâche PNL multi-classe

Je forme un modèle simple en keras pour la tâche PNL avec le code suivant. Les noms de variables sont explicites pour le train, le test et l'ensemble de validation. Cet ensemble de données a 19 classes, donc la couche finale du réseau a 19 sorties. Les étiquettes sont également codées à chaud.

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)

Après la première Epoch, cela me donne ces sorties.

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

Ensuite, j'évalue mon modèle sur un ensemble de données de test et cela me montre également une précision d'environ 0,98.

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

Cependant, les étiquettes sont codées à chaud, j'ai donc besoin d'un vecteur de prédiction de classes pour pouvoir générer une matrice de confusion, etc.

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

Cela montre que le total des classes prévues était précis à 83%, cependant model1.evaluate montre une précision de 98% !! Qu'est-ce que je fais mal ici? Ma fonction de perte est-elle compatible avec les étiquettes de classe catégorielles? Mon choix de fonction d'activation sigmoid pour la couche de prédiction est-il correct? ou il y a une différence dans la façon dont les kéros évaluent un modèle? Veuillez suggérer ce qui ne va pas. C'est mon premier essai pour créer un modèle profond, donc je n'ai pas beaucoup de compréhension de ce qui ne va pas ici.

15
Sal A.

J'ai trouvé le problème. metrics=['accuracy'] Calcule automatiquement la précision à partir de la fonction de coût. Ainsi, l'utilisation de binary_crossentropy Indique une précision binaire et non une précision catégorique. L'utilisation de categorical_crossentropy Bascule automatiquement en précision catégorielle et est maintenant identique à celle calculée manuellement à l'aide de model1.predict(). Yu-Yang a eu raison de souligner la fonction de coût et la fonction d'activation pour un problème multi-classes.

P.S: On peut obtenir une précision à la fois catégorique et binaire en utilisant metrics=['binary_accuracy', 'categorical_accuracy']

32
Sal A.