Saltar al contenido

Cambiar el tamaño de las imágenes en los métodos de flujo Keras ImageDataGenerator

Luego de mucho trabajar ya encontramos el resultado de este rompecabezas que tantos usuarios de nuestro sitio web han presentado. Si tienes algo que compartir no dudes en dejar tu conocimiento.

Solución:

flow_from_directory(directory) genera imágenes aumentadas desde el directorio con una colección arbitraria de imágenes. Así que hay necesidad de parámetro target_size para hacer todas las imágenes de la misma forma.

Tiempo flow(X, y) aumenta las imágenes que ya están almacenadas en una secuencia en X que no es más que una matriz numpy y se puede preprocesar/redimensionar fácilmente antes de pasar a flow. Así que no hay necesidad de target_size parámetro. En cuanto al cambio de tamaño, prefiero usar scipy.misc.imresize sobre PIL.Image resizeo cv2.resize ya que puede operar en datos de imagen numpy.

import scipy
new_shape = (28,28,3)
X_train_new = np.empty(shape=(X_train.shape[0],)+new_shape)
for idx in xrange(X_train.shape[0]):
    X_train_new[idx] = scipy.misc.imresize(X_train[idx], new_shape)

Para grandes conjuntos de datos de entrenamiento, realizar transformaciones como cambiar el tamaño de todos los datos de entrenamiento consume mucha memoria. Como hizo Keras en ImageDataGenerator, es mejor hacerlo lote por lote. Hasta donde yo sé, hay 2 formas de lograr esto además de operar todo el conjunto de datos:

  1. Puede usar Lambda Layer para crear una capa y luego alimentarla con datos de entrenamiento originales. La salida es el tamaño redimensionado que necesita.

Aquí está el código de muestra si usa TensorFlow como backend de Keras:

original_dim = (32, 32, 3)
target_size = (64, 64)
input = keras.layers.Input(original_dim)
x = tf.keras.layers.Lambda(lambda image: tf.image.resize(image, target_size))(input)
  1. Como mencionó @Retardust, tal vez pueda personalizar su propio ImageDataGenerator, así como la función de preprocesamiento.

Para cualquier otra persona que quiera hacer esto, el método .flow de ImageDataGenerator no tiene un parámetro target_shape y no podemos cambiar el tamaño de una imagen usando el parámetro preprocessing_function como lo indica la documentación The function will run after the image is resized and augmented. The function should take one argument: one image (Numpy tensor with rank 3), and should output a Numpy tensor with the same shape.

Entonces, para usar .flow, tendrá que pasar imágenes redimensionadas solo; de lo contrario, use un generador personalizado que las redimensione sobre la marcha.

Aquí hay una muestra de generador personalizado en keras (también se puede hacer usando el generador de python o cualquier otro método)

class Custom_Generator(keras.utils.Sequence) :
    def __init__(self,...,datapath, batch_size, ..) :

    def __len__(self) :
        #calculate data len, something like len(train_labels)


    def load_and_preprocess_function(self, label_names, ...):
        #do something...
        #load data for the batch using label names with whatever library

    def __getitem__(self, idx) :
        batch_y = train_labels[idx:idx+batch_size]
        batch_x = self.load_and_preprocess_function()
        return ( batch_x, batch_y )

Reseñas y puntuaciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *