web-dev-qa-db-fra.com

Comment utiliser .predict_generator () sur de nouvelles images - Keras

J'ai utilisé ImageDataGenerator et flow_from_directory pour la formation et la validation.

Ce sont mes répertoires:

train_dir = Path('D:/Datasets/Trell/images/new_images/training')
test_dir = Path('D:/Datasets/Trell/images/new_images/validation')
pred_dir = Path('D:/Datasets/Trell/images/new_images/testing')

Code ImageGenerator:

img_width, img_height = 28, 28
batch_size=32
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1. / 255)

train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='categorical')

Trouvé 1852 images appartenant à 4 classes

Trouvé 115 images appartenant à 4 classes

Voici mon modèle de code de formation:

history = cnn.fit_generator(
        train_generator,
        steps_per_Epoch=1852 // batch_size,
        epochs=20,
        validation_data=validation_generator,
        validation_steps=115 // batch_size)

Maintenant, j'ai de nouvelles images dans un dossier de test (toutes les images sont dans le même dossier uniquement), sur lesquelles je veux prédire. Mais quand j'utilise .predict_generator Je reçois:

Trouvé 0 images appartenant à 0 classe

J'ai donc essayé ces solutions:

1) Keras: Comment utiliser Predict_Generator avec ImageDataGenerator? Cela n'a pas fonctionné, car sa tentative de validation est définie uniquement.

2) Comment prédire la nouvelle image en utilisant model.predict?module image not found

3) Comment obtenir des prédictions avec Predict_Generator sur les données de test en streaming dans Keras? Cela n'a pas fonctionné non plus.

Mes données de train sont essentiellement stockées dans 4 dossiers distincts, c'est-à-dire 4 classes spécifiques, la validation est également stockée de la même manière et fonctionne assez bien.

Donc, dans mon dossier de test, j'ai environ 300 images, sur lesquelles je veux prédire et créer une trame de données, comme ceci:

image_name    class
gghh.jpg       1
rrtq.png       2
1113.jpg       1
44rf.jpg       4
tyug.png       1
ssgh.jpg       3

J'ai également utilisé ce code suivant:

img = image.load_img(pred_dir, target_size=(28, 28))
img_tensor = image.img_to_array(img)
img_tensor = np.expand_dims(img_tensor, axis=0)
img_tensor /= 255.

cnn.predict(img_tensor)

Mais je reçois cette erreur: [Errno 13] Permission denied: 'D:\\Datasets\\Trell\\images\\new_images\\testing'

Mais je n'ai pas pu predict_generator sur mes images de test. Alors, comment puis-je prédire mes nouvelles images en utilisant Keras. J'ai beaucoup cherché sur Google, cherché sur Kaggle Kernels mais je n'ai pas pu trouver de solution.

8
Debadri Dutta

Donc, tout d'abord, les images de test doivent être placées dans un dossier séparé à l'intérieur du dossier de test. Donc, dans mon cas, j'ai créé un autre dossier dans le dossier test et je l'ai nommé all_classes. Puis a exécuté le code suivant:

test_generator = test_datagen.flow_from_directory(
    directory=pred_dir,
    target_size=(28, 28),
    color_mode="rgb",
    batch_size=32,
    class_mode=None,
    shuffle=False
)

Le code ci-dessus me donne une sortie:

Trouvées 306 images appartenant à 1 classe

Et surtout, vous devez écrire le code suivant:

test_generator.reset()

sinon des sorties étranges viendront. Puis en utilisant la fonction .predict_generator():

pred=cnn.predict_generator(test_generator,verbose=1,steps=306/batch_size)

L'exécution du code ci-dessus donnera une sortie en probabilités, donc au début, je dois les convertir en numéro de classe. Dans mon cas, c'était 4 classes, donc les numéros de classe étaient 0,1,2 et 3.

Code écrit:

predicted_class_indices=np.argmax(pred,axis=1)

La prochaine étape est que je veux le nom des classes:

labels = (train_generator.class_indices)
labels = dict((v,k) for k,v in labels.items())
predictions = [labels[k] for k in predicted_class_indices]

Où par les numéros de classe seront remplacés par les noms de classe. Une dernière étape si vous souhaitez l'enregistrer dans un fichier csv, organisez-le dans une trame de données avec les noms d'image ajoutés à la classe prévue.

filenames=test_generator.filenames
results=pd.DataFrame({"Filename":filenames,
                      "Predictions":predictions})

Affichez votre trame de données. Tout est fait maintenant. Vous obtenez toute la classe prévue pour vos images.

15
Debadri Dutta

J'ai eu quelques problèmes avec predict_generator(). Certains messages ici ont beaucoup aidé. Je poste également ma solution ici et j'espère qu'elle aidera les autres. Ce que je fais:

  • Faites des prédictions sur de nouvelles images en utilisant predict_generator()
  • Obtenez le nom de fichier pour chaque prédiction
  • Stocker les résultats dans une trame de données

Je fais des prédictions binaires à la "chats et chiens" comme documenté ici . Cependant, la logique peut être généralisée aux cas multiclasses. Dans ce cas, le résultat de la prédiction a une colonne par classe.

Tout d'abord, je charge mon modèle stocké et configure le générateur de données:

import numpy as np
import pandas as pd
from keras.preprocessing.image import ImageDataGenerator
from keras.models import load_model

# Load model
model = load_model('my_model_01.hdf5')

test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_directory(
        "C:/kerasimages/pred/",
        target_size=(150, 150),
        batch_size=20,
        class_mode='binary',
        shuffle=False)

Remarque: il est important de spécifier shuffle=False Afin de conserver l'ordre des noms de fichiers et des prédictions.

Les images sont stockées dans C:/kerasimages/pred/images/. Le générateur de données ne recherchera que des images dans les sous-dossiers de C:/kerasimages/pred/ (Comme spécifié dans test_generator). Il est important de respecter la logique du générateur de données, donc le sous-dossier /images/ Est requis. Chaque sous-dossier dans C:/kerasimages/pred/ Est interprété comme une classe par le générateur. Ici, le générateur affichera Found x images belonging to 1 classes (Car il n'y a qu'un seul sous-dossier). Si nous faisons des prédictions, les classes (détectées par le générateur) ne sont pas pertinentes.

Maintenant, je peux faire des prédictions en utilisant le générateur:

# Predict from generator (returns probabilities)
pred=model.predict_generator(test_generator, steps=len(test_generator), verbose=1)

La réinitialisation du générateur n'est pas nécessaire dans ce cas, mais si un générateur a été configuré auparavant, il peut être nécessaire de le reposer à l'aide de test_generator.reset().

Ensuite, j'arrondis les probabilités d'obtenir des classes et je récupère les noms de fichiers:

# Get classes by np.round
cl = np.round(pred)
# Get filenames (set shuffle=false in generator is important)
filenames=test_generator.filenames

Enfin, les résultats peuvent être stockés dans une trame de données:

# Data frame
results=pd.DataFrame({"file":filenames,"pr":pred[:,0], "class":cl[:,0]})
4
Peter

Le plus probablement, vous faites une erreur en utilisant flow_from_directory. Lecture des documents:

flow_from_directory (répertoire, ...)

Où:

répertoire: chemin d'accès au répertoire cible. Il doit contenir un sous-répertoire par classe. Toutes les images PNG, JPG, BMP, PPM ou TIF à l'intérieur de chaque arborescence de répertoires de sous-répertoires seront incluses dans le générateur.

Cela signifie qu'à l'intérieur du répertoire que vous passez à cette fonction, vous devez créer des sous-répertoires et placer vos images à l'intérieur de ces sous-répertoires. Sinon, lorsque les images sont dans le répertoire que vous passez (pas dans les sous-répertoires), en effet il y a 0 images et 0 classes.

MODIFIER

Bon, donc dans le cas de la prédiction que vous souhaitez effectuer, je pense que vous souhaitez utiliser la fonction predict comme suit: (notez que vous devez fournir des données au réseau dans le même format que lors de l'apprentissage processus)

image = img_to_array(load_img(f"{directory}/{foldername}/{filename}"))
# here you prepare the input data, for example here we take the gray image
# gray scale is the 1st channel in the Lab color space
color_me = rgb2lab((1.0 / 255) * color_me)[:, :, 0]
color_me = color_me.reshape(color_me.shape + (1,))
# here data is in the format which is accepted by, in this case, my model
# for your model you have to do the preparation just the same as in the case of learning process
output = model.predict(np.array([color_me]))
# and here you have your predicted output
0
Mariusz Ch.

Je vous recommande fortement de créer un dossier parent dans le dossier de test. Déplacez ensuite le dossier de test vers le dossier parent.

signifie que si vous avez un dossier de test de cette manière:

/root/test/img1.png
/root/test/img2.png
/root/test/img3.png
/root/test/img4.png

cette mauvaise façon d'utiliser predict_generator. Mettez à jour votre dossier de test comme ceci:

/root/test_parent/test/img1.png
/root/test_parent/test/img2.png
/root/test_parent/test/img3.png
/root/test_parent/test/img4.png

Utilisez cette commande pour mettre à jour:

mv /root/test/ ./root/test_parent/test 

Et n'oubliez pas de donner un chemin vers le modèle comme celui-ci

"/root/test_parent/"

Cette méthode fonctionne pour moi.

0
B. Kanani