Solución:
flow_from_directory(directory)
genera imágenes aumentadas desde el directorio con una colección arbitraria de imágenes. Entonces 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
. Entonces no hay necesidad de target_size
parámetro. En cuanto a cambiar el tamaño, prefiero usar scipy.misc.imresize
sobre PIL.Image resize
, o cv2.resize, ya que puede operar con muchos datos de imagen.
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 un gran conjunto 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:
- Puede usar Lambda Layer para crear una capa y luego alimentarla con datos de entrenamiento originales. La salida es el tamaño 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)
- 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 dice 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 )