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.
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.
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:
predict_generator()
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]})
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
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.