¿Cómo predecir la imagen de entrada utilizando un modelo entrenado en Keras?
Estoy empezando con keras y el aprendizaje automático en general.
He entrenado un modelo para clasificar imágenes de 2 clases y lo he guardado usando model.save()
. Aquí está el código que he utilizado:
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')
Se entrenó con éxito con 0,98 precisión que es bastante bueno. Para cargar y probar este modelo en nuevas imágenes, he utilizado el siguiente código:
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
Se salidas:
[[0]]
¿Por qué no da el nombre real de la clase y por qué [[0]]
?
Gracias de antemano.
35
3
Si alguien sigue teniendo problemas para hacer predicciones sobre imágenes, aquí tiene el código optimizado para cargar el modelo guardado y hacer predicciones:
keras predict_classes (docs) outputs Un array numpy de predicciones de clase. En el caso de tu modelo, el índice de la neurona de mayor activación de tu última capa (softmax). 0]]
significa que tu modelo predijo que tus datos de prueba son de clase 0. (normalmente pasarás múltiples imágenes, y el resultado se verá como
[[0], 1, 1, [0]]` )Debe convertir su etiqueta real (por ejemplo,
'cáncer', 'no cáncer'
) en codificación binaria (0
para 'cáncer',1
para 'no cáncer') para la clasificación binaria. Entonces interpretará que su secuencia de salida[[0]]
tiene la etiqueta de clase'cáncer'
.Puede utilizar
model.predict()
para predecir la clase de una sola imagen de la siguiente manera [doc]:En este ejemplo, una imagen se carga como una matriz
numpy
con forma(1, altura, anchura, canales)
. A continuación, la cargamos en el modelo y predecimos su clase, devuelta como un valor real en el rango [0, 1] (clasificación binaria en este ejemplo).