Comment spécifier manuellement les étiquettes de classe dans keras flux de répertoire?

Problème: je forme un modèle de reconnaissance d'image multicâble. Mes images sont donc associées à des labels y multiples. Ceci est en contradiction avec la méthode commode de keras "flow_from_directory" du ImageDataGenerator, où chaque image est supposée être dans le dossier de l'étiquette correspondante (https://keras.io/preprocessing/image/).

palliatif: actuellement, je lis toutes les images dans un tableau numpy et utilise le "flux" de la fonction à partir de là. Mais il en résulte de lourdes charges de mémoire et un lent processus de lecture.

Question: Est-il possible d'utiliser le "flow_from_directory" méthode et de fournir manuellement (plusieurs) classe d'étiquettes?


mise à Jour: j'ai fini par étendre la classe DirectoryIterator pour l'affaire multilabel. Vous pouvez maintenant définir l'attribut "class_mode" à la valeur "multilabel" et de fournir un dictionnaire "multlabel_classes" qui cartes des noms de fichiers pour leurs étiquettes. Code: https://github.com/tholor/keras/commit/29ceafca3c4792cb480829c5768510e4bdb489c5

17
demandé sur Malte 2017-03-29 10:02:58

2 réponses

vous pouvez écrire une classe génératrice personnalisée qui lirait les fichiers du répertoire et appliquerait l'étiquetage. Ce générateur personnalisé pourrait également prendre une instance ImageDataGenerator qui produirait les lots en utilisant flow ().

j'imagine quelque chose comme ceci:

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)

Alors tout simplement:

img_gen = ImageDataGenerator(...)
gen = Generator(X, Y, img_gen, 128)

model.fit_generator(gen.get_next_batch(), ...)
2
répondu gaw89 2017-03-30 15:07:51

Vous pouvez simplement utiliser le flow_from_directory et de les étendre à un multiclass dans un façon suivante:

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)

multiclasses_getter affecte un vecteur multiclasse / votre représentation multiclasse à vos images. Notez que x et y ne sont pas des exemples mais des lots d'exemples, donc cela devrait être inclus dans votre