Problema: Estoy entrenando un modelo para el reconocimiento de imágenes multietiqueta. Por lo tanto, mis imágenes están asociadas con múltiples etiquetas y. Esto entra en conflicto con el conveniente método de keras "flow_from_directory" de ImageDataGenerator, donde se supone que cada imagen está en la carpeta de la etiqueta correspondiente ( https://keras.io/preprocessing/image/ ).
Solución alternativa: actualmente, estoy leyendo todas las imágenes en una matriz numpy y uso la función de "flujo" desde allí. Pero esto da como resultado grandes cargas de memoria y un lento proceso de lectura.
Pregunta: ¿Hay alguna manera de usar el método "flow_from_directory" y proporcionar manualmente las (múltiples) etiquetas de clase?
Actualización : terminé extendiendo la clase DirectoryIterator para el caso de etiquetas múltiples. Ahora puede establecer el atributo "class_mode" en el valor "multilabel" y proporcionar un diccionario "multilabel_classes" que asigna nombres de archivo a sus etiquetas. Código: https://github.com/tholor/keras/commit/29ceafca3c4792cb480829c5768510e4bdb489c5
Simplemente podría usar flow_from_directory y extenderlo a una multiclase de la siguiente manera:
def multiclass_flow_from_directory(flow_from_directory_gen, multiclasses_getter): for x, y in flow_from_directory_gen: yield x, multiclasses_getter(x, y) Donde multiclasses_getter está asignando un vector multiclase/su representación multiclase a sus imágenes. Tenga en cuenta que x e y no son ejemplos únicos sino lotes de ejemplos, por lo que esto debe incluirse en su diseño de multiclasses_getter .
Podría escribir una clase generadora personalizada que leyera los archivos desde el directorio y aplicara el etiquetado. Ese generador personalizado también podría admitir una instancia de ImageDataGenerator que produciría los lotes usando flow().
Me estoy imaginando algo como esto:
class Generator(): def __init__(self, X, Y, img_data_gen, batch_size): self.X = X self.Y = Y # Maybe a file that has the appropriate label mapping? self.img_data_gen = img_data_gen # The ImageDataGenerator Instance self.batch_size = batch_size def apply_labels(self): # Code to apply labels to each sample based on self.X and self.Y def get_next_batch(self): """Get the next training batch""" self.img_data_gen.flow(self.X, self.Y, self.batch_size)Entonces simplemente:
img_gen = ImageDataGenerator(...) gen = Generator(X, Y, img_gen, 128) model.fit_generator(gen.get_next_batch(), ...)* Descargo de responsabilidad: en realidad no he probado esto, pero debería funcionar en teoría.
# Training the model history = model.fit(train_generator, steps_per_epoch=steps_per_epoch, epochs=3, validation_data=val_generator,validation_steps=validation_steps, verbose=1, callbacks= keras.callbacks.ModelCheckpoint(filepath='/content/results',monitor='val_accuracy', save_best_only=True,save_weights_only=False)) Los validation_steps o los steps_per_epoch pueden exceder los de los parámetros originales.
steps_per_epoch= (int(num_of_training_examples/batch_size) podría ayudar. De manera similar, validation_steps= (int(num_of_val_examples/batch_size) ayudará