Comment prédire l'image d'entrée en utilisant le modèle formé dans Keras?
je commence seulement avec keras et l'apprentissage automatique en général.
j'ai formé un modèle pour classer des images de 2 classes et je l'ai enregistré en utilisant model.save(). Voici le code que j'ai utilisé:
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
# dimensions of our images.
img_width, img_height = 320, 240
train_data_dir = 'data/train'
validation_data_dir = 'data/validation'
nb_train_samples = 200 #total
nb_validation_samples = 10 # total
epochs = 6
batch_size = 10
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=5)
model.save('model.h5')
il s'est entraîné avec succès avec une précision de 0,98, ce qui est assez bon. Pour charger et tester ce modèle sur de nouvelles images, j'ai utilisé le code suivant:
from keras.models import load_model
import cv2
import numpy as np
model = load_model('model.h5')
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
img = cv2.imread('test.jpg')
img = cv2.resize(img,(320,240))
img = np.reshape(img,[1,320,240,3])
classes = model.predict_classes(img)
print classes
Il affiche:
[[0]]
pourquoi n'aurait-il pas donné le nom réel de la classe et pourquoi [[0]]?
Merci d'avance.
5 réponses
keras predict_classes ( docs) produit un tableau numpy de prédictions de classe. Qui dans votre cas Modèle, l'index du neurone de la plus haute activation de votre dernière couche (softmax). [[0]] signifie que votre modèle prédit que vos données d'essai sont de classe 0. (habituellement, vous passerez plusieurs images, et le résultat ressemblera à [[0], [1], [1], [0]])
Vous devez convertir votre étiquette (par exemple,'cancer', 'not cancer') en encodage binaire (0 pour "cancer", 1 pour "pas de cancer") pour la classification binaire. Alors vous interpréterez votre séquence de sortie de [[0]] comme ayant l'étiquette de classe 'cancer'
si quelqu'un a encore du mal à faire des prédictions sur des images, voici le code optimisé pour charger le modèle enregistré et faire des prédictions:
# Modify 'test1.jpg' and 'test2.jpg' to the images you want to predict on
from keras.models import load_model
from keras.preprocessing import image
import numpy as np
# dimensions of our images
img_width, img_height = 320, 240
# load the model we saved
model = load_model('model.h5')
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
# predicting images
img = image.load_img('test1.jpg', target_size=(img_width, img_height))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])
classes = model.predict_classes(images, batch_size=10)
print classes
# predicting multiple images at once
img = image.load_img('test2.jpg', target_size=(img_width, img_height))
y = image.img_to_array(img)
y = np.expand_dims(y, axis=0)
# pass the list of multiple images np.vstack()
images = np.vstack([x, y])
classes = model.predict_classes(images, batch_size=10)
# print the classes, the images belong to
print classes
print classes[0]
print classes[0][0]
Vous pouvez utiliser model.predict() pour prédire la classe d'une seule image comme suit [doc]:
# load_model_sample.py
from keras.models import load_model
from keras.preprocessing import image
import matplotlib.pyplot as plt
import numpy as np
import os
def load_image(img_path, show=False):
img = image.load_img(img_path, target_size=(150, 150))
img_tensor = image.img_to_array(img) # (height, width, channels)
img_tensor = np.expand_dims(img_tensor, axis=0) # (1, height, width, channels), add a dimension because the model expects this shape: (batch_size, height, width, channels)
img_tensor /= 255. # imshow expects values in the range [0, 1]
if show:
plt.imshow(img_tensor[0])
plt.axis('off')
plt.show()
return img_tensor
if __name__ == "__main__":
# load model
model = load_model("model_aug.h5")
# image path
img_path = '/media/data/dogscats/test1/3867.jpg' # dog
#img_path = '/media/data/dogscats/test1/19.jpg' # cat
# load a single image
new_image = load_image(img_path)
# check prediction
pred = model.predict(new_image)
dans cet exemple, une image est chargée comme un numpy array avec la forme (1, height, width, channels). Ensuite, nous le chargeons dans le modèle et prédisons sa classe, retournée comme valeur réelle dans la gamme [0, 1] (classification binaire dans cet exemple).
c'est parce que vous obtenez la valeur numérique associée à la classe. Par exemple, si vous avez deux classes de chats et de chiens, Keras les associera aux valeurs numériques 0 et 1. Pour obtenir la correspondance entre les classes et leur valeur numérique associée, vous pouvez utiliser
>>> classes = train_generator.class_indices
>>> print(classes)
{'cats': 0, 'dogs': 1}
Maintenant vous connaissez le mappage entre vos classes et vos indices. Alors maintenant ce que vous pouvez faire est
if classes[0][0] == 1:
prediction = 'dog'
else:
prediction = 'cat'
transmettre l'exemple par @ritiek, je suis aussi un débutant en ML, peut-être que ce type de formatage aidera à voir le nom au lieu du numéro de classe.
images = np.vstack([x, y])
prediction = model.predict(images)
print(prediction)
i = 1
for things in prediction:
if(things == 0):
print('%d.It is cancer'%(i))
else:
print('%d.Not cancer'%(i))
i = i + 1