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.

17
demandé sur Løiten 2017-04-18 13:09:20

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'

6
répondu DNK 2017-04-18 11:05:06

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]
12
répondu ritiek 2017-04-21 16:42:23

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).

4
répondu auraham 2017-11-17 00:48:47

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'

1
répondu Javapocalypse 2018-08-08 17:22:20

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
0
répondu Vineeth Sai 2018-01-13 08:58:37