J'ai formé mon modèle (classification multiclasse) de CNN en utilisant des keras et maintenant je veux évaluer le modèle sur mon jeu d'images de test.
Quelles sont les options possibles pour évaluer mon modèle en dehors de l'exactitude, de la précision et du rappel? Je sais comment obtenir la précision et le rappel d'un script personnalisé. Mais je ne peux pas trouver un moyen d'obtenir la matrice de confusion pour mes 12 classes d'images . Scikit-learn montre un way , mais pas pour les images. J'utilise model.fit_generator ()
Existe-t-il un moyen de créer une matrice de confusion pour toutes mes classes ou de trouver la confiance de classification sur mes classes? J'utilise Google Colab, mais je peux télécharger le modèle et l'exécuter localement.
Toute aide serait appréciée.
Code:
train_data_path = 'dataset_cfps/train'
validation_data_path = 'dataset_cfps/validation'
#Parametres
img_width, img_height = 224, 224
vggface = VGGFace(model='resnet50', include_top=False, input_shape=(img_width, img_height, 3))
#vgg_model = VGGFace(include_top=False, input_shape=(224, 224, 3))
last_layer = vggface.get_layer('avg_pool').output
x = Flatten(name='flatten')(last_layer)
xx = Dense(256, activation = 'sigmoid')(x)
x1 = BatchNormalization()(xx)
x2 = Dropout(0.3)(x1)
y = Dense(256, activation = 'sigmoid')(x2)
yy = BatchNormalization()(y)
y1 = Dropout(0.6)(yy)
x3 = Dense(12, activation='sigmoid', name='classifier')(y1)
custom_vgg_model = Model(vggface.input, x3)
# Create the model
model = models.Sequential()
# Add the convolutional base model
model.add(custom_vgg_model)
model.summary()
#model = load_model('facenet_resnet_lr3_SGD_sameas1.h5')
def recall(y_true, y_pred):
true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
recall = true_positives / (possible_positives + K.epsilon())
return recall
def precision(y_true, y_pred):
true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
precision = true_positives / (predicted_positives + K.epsilon())
return precision
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
validation_datagen = ImageDataGenerator(rescale=1./255)
# Change the batchsize according to your system RAM
train_batchsize = 32
val_batchsize = 32
train_generator = train_datagen.flow_from_directory(
train_data_path,
target_size=(img_width, img_height),
batch_size=train_batchsize,
class_mode='categorical')
validation_generator = validation_datagen.flow_from_directory(
validation_data_path,
target_size=(img_width, img_height),
batch_size=val_batchsize,
class_mode='categorical',
shuffle=True)
# Compile the model
model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-3),
metrics=['acc', recall, precision])
# Train the model
history = model.fit_generator(
train_generator,
steps_per_Epoch=train_generator.samples/train_generator.batch_size ,
epochs=100,
validation_data=validation_generator,
validation_steps=validation_generator.samples/validation_generator.batch_size,
verbose=1)
# Save the model
model.save('facenet_resnet_lr3_SGD_new_FC.h5')
Voici comment obtenir la matrice de confusion (ou peut-être des statistiques à l'aide de scikit-learn) pour toutes les classes:
1. Classes prédictives
test_generator = ImageDataGenerator()
test_data_generator = test_generator.flow_from_directory(
test_data_path, # Put your path here
target_size=(img_width, img_height),
batch_size=32,
shuffle=False)
test_steps_per_Epoch = numpy.math.ceil(test_data_generator.samples / test_data_generator.batch_size)
predictions = model.predict_generator(test_data_generator, steps=test_steps_per_Epoch)
# Get most likely class
predicted_classes = numpy.argmax(predictions, axis=1)
2.Obtenez des classes et des étiquettes de classe
true_classes = test_data_generator.classes
class_labels = list(test_data_generator.class_indices.keys())
3. Utilisez scikit-learn pour obtenir des statistiques
report = metrics.classification_report(true_classes, predicted_classes, target_names=class_labels)
print(report)
Vous pouvez lire plus ici
EDIT: Si ce qui précède ne fonctionne pas, regardez cette vidéo Créez une matrice de confusion pour les prédictions à partir du modèle Keras . Consultez probablement les commentaires si vous avez un problème. Ou Faites des prédictions avec un classificateur d'images Keras CNN
Pourquoi la fonction scikit-learn ne ferait pas le travail? Vous transmettez tous vos échantillons (images) dans l'ensemble train/test, convertissez un codage à chaud en codage d'étiquette (voir lien ) et passez-le dans sklearn.metrics.confusion_matrix
comme y_pred
. Vous procédez de la même manière avec y_true
(un chaud pour étiqueter).
Exemple de code:
import sklearn.metrics as metrics
y_pred_ohe = KerasClassifier.predict(X) # shape=(n_samples, 12)
y_pred_labels = np.argmax(y_pred_ohe, axis=1) # only necessary if output has one-hot-encoding, shape=(n_samples)
confusion_matrix = metrics.confusion_matrix(y_true=y_true_labels, y_pred=y_pred_labels) # shape=(12, 12)
Ici, les chats et les chiens sont les étiquettes de classe:
#Confusion Matrix and Classification Report
from sklearn.metrics import classification_report
Y_pred = model.predict_generator(validation_generator, nb_validation_samples //
batch_size+1)
y_pred = np.argmax(Y_pred, axis=1)
print('Confusion Matrix')
print(confusion_matrix(validation_generator.classes, y_pred))
print('Classification Report')
target_names = ['Cats', 'Dogs']
print(classification_report(validation_generator.classes, y_pred,
target_names=target_names))