web-dev-qa-db-fra.com

Comment obtenir une matrice de confusion lors de l'utilisation de model.fit_generator

J'utilise model.fit_generator pour m'entraîner et obtenir des résultats pour mon modèle binaire (deux classes) car je donne des images d'entrée directement à partir de mon dossier. Comment obtenir la matrice de confusion dans ce cas (TP, TN, FP, FN) également parce que généralement j'utilise la commande confusion_matrix De sklearn.metrics Pour l'obtenir, ce qui nécessite predicted, et actual labels. Mais ici, je n'ai pas les deux. Peut-être que je peux calculer les étiquettes prédites à partir de la commande predict=model.predict_generator(validation_generator). Mais je ne sais pas comment mon modèle prend les étiquettes d'entrée de mes images. La structure générale de mon dossier d'entrée est:

train/
 class1/
     img1.jpg
     img2.jpg
     ........
 class2/
     IMG1.jpg
     IMG2.jpg
test/
 class1/
     img1.jpg
     img2.jpg
     ........
 class2/
     IMG1.jpg
     IMG2.jpg
     ........

et certains blocs de mon code sont:

train_generator = train_datagen.flow_from_directory('train',  
        target_size=(50, 50),  batch_size=batch_size,
        class_mode='binary',color_mode='grayscale')  


validation_generator = test_datagen.flow_from_directory('test',
        target_size=(50, 50),batch_size=batch_size,
        class_mode='binary',color_mode='grayscale')

model.fit_generator(
        train_generator,steps_per_Epoch=250 ,epochs=40,
        validation_data=validation_generator,
        validation_steps=21 )

Donc, le code ci-dessus prend automatiquement deux entrées de classe, mais je ne sais pas pour qui il considère la classe 0 et pour quelle classe 1.

10
Hitesh

Je l'ai géré de la manière suivante, en utilisant keras.utils.Sequence.

from sklearn.metrics import confusion_matrix
from keras.utils import Sequence


class MySequence(Sequence):
    def __init__(self, *args, **kwargs):
        # initialize
        # see manual on implementing methods

    def __len__(self):
        return self.length

    def __getitem__(self, index):
        # return index-th complete batch


# create data generator
data_gen = MySequence(evaluation_set, batch_size=10) 

n_batches = len(data_gen)

confusion_matrix(
    np.concatenate([np.argmax(data_gen[i][1], axis=1) for i in range(n_batches)]),    
    np.argmax(m.predict_generator(data_gen, steps=n_batches), axis=1) 
)

La classe implémentée renvoie des lots de données en tuples, ce qui permet de ne pas les conserver tous en RAM. Veuillez noter qu'il doit être implémenté dans __getitem__, et cette méthode doit renvoyer le même lot pour le même argument.

Malheureusement, ce code itère deux fois les données: la première fois, il crée un tableau de vraies réponses à partir des lots renvoyés, la deuxième fois qu'il appelle la méthode predict du modèle.

4
wl2776
probabilities = model.predict_generator(generator=test_generator)

nous donnera un ensemble de probabilités.

y_true = test_generator.classes

nous donnera de vraies étiquettes.

Comme il s'agit d'un problème de classification binaire, vous devez trouver des étiquettes prédites. Pour ce faire, vous pouvez utiliser

y_pred = probabilities > 0.5

Ensuite, nous avons de véritables étiquettes et des étiquettes prédites sur l'ensemble de données de test. Ainsi, la matrice de confusion est donnée par

font = {
'family': 'Times New Roman',
'size': 12
}
matplotlib.rc('font', **font)
mat = confusion_matrix(y_true, y_pred)
plot_confusion_matrix(conf_mat=mat, figsize=(8, 8), show_normed=False)
1
Shirantha Madusanka