web-dev-qa-db-fra.com

Matrice de confusion sur les images en keras CNN

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')
8
Abhishek Singh

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

9
Abhishek Singh

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)
6
Jan K

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))
0
Meghana Rao