Как вручную указать метки классов в keras flow_from_directory?

Проблема: Я тренирую модель для распознавания многозначных изображений. Поэтому мои изображения связаны с несколькими ярлыками y. Это противоречит удобному методу keras "flow_from_directory" в ImageDataGenerator, где каждое изображение должно находиться в папке соответствующей метки (https://keras.io/preprocessing/image/).

Обходной путь: В настоящее время я читаю все изображения в массив numpy и использую функцию "поток" оттуда. Но это приводит к большим нагрузкам на память и медленному процессу считывания.

Вопрос: Есть ли способ использования метода flow_from_directory и для подачи вручную (нескольких) меток класса?


Обновление. Я закончил тем, что расширил класс DirectoryIterator для многозначного случая. Теперь вы можете установить атрибут "class_mode" на значение "multilabel" и предоставить словарь "multlabel_classes", который отображает имена файлов на свои метки. Код: https://github.com/tholor/keras/commit/29ceafca3c4792cb480829c5768510e4bdb489c5

Ответ 1

Вы можете написать собственный класс генератора, который будет считывать файлы из каталога и применять этикетировки. Этот пользовательский генератор может также принимать экземпляр ImageDataGenerator, который будет производить партии с помощью flow().

Я представляю что-то вроде этого:

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)

Тогда просто:

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

model.fit_generator(gen.get_next_batch(), ...)

* Отказ от ответственности: я на самом деле не проверял это, но он должен работать теоретически.

Ответ 2

Вы можете просто использовать flow_from_directory и расширить его до многоклассов следующим образом:

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 присваивает вашим изображениям многоклассовый вектор/ваше многоклассовое представление. Обратите внимание, что x и y не являются примерами, а примерами примеров, поэтому это должно быть включено в ваш проект multiclasses_getter.