如何在 keras flow_from_directory 中手动指定类标签?

Posted

技术标签:

【中文标题】如何在 keras flow_from_directory 中手动指定类标签?【英文标题】:How to manually specify class labels in keras flow_from_directory? 【发布时间】:2017-08-22 12:43:23 【问题描述】:

问题:我正在训练一个用于多标签图像识别的模型。因此,我的图像与多个 y 标签相关联。这与 ImageDataGenerator 的便捷 keras 方法“flow_from_directory”相冲突,其中每个图像都应该位于相应标签的文件夹中(https://keras.io/preprocessing/image/)。

解决方法:目前,我正在将所有图像读入一个 numpy 数组并从那里使用“流”功能。但这会导致内存负载过重和读入过程缓慢。

问题:有没有办法使用“flow_from_directory”方法并手动提供(多个)类标签?


更新:我最终为多标签案例扩展了 DirectoryIterator 类。您现在可以将属性“class_mode”设置为值“multilabel”并提供一个字典“multlabel_classes”,它将文件名映射到它们的标签。代码:https://github.com/tholor/keras/commit/29ceafca3c4792cb480829c5768510e4bdb489c5

【问题讨论】:

flow_from_directory 假定图像在目录之间进行拆分,并且每个目录的名称都是目标。 Keras 的总体思路是简化使用(相对于 TF 和 Theano),但它伴随着缺乏定制的成本。您不应该将所有图像加载到内存中,而是创建代表各种类的目录并将相应的图像存储在其中。看看非常漂亮的 F. Chollet 教程:blog.keras.io/… 在多标签情况下将图像存储在代表各种类别的目录中并不可行。每个图像有 100 个类和 1-6 个类,可能的组合已经很庞大了。如果没有其他解决方法,我可能会在 keras/preprocessing/image.py 中扩展 DirectoryIterator 类 很好的修复。您是否为此创建了拉取请求?我认为这是维护者可能/应该考虑添加的内容。 我刚刚创建了一个拉取请求:github.com/fchollet/keras/pull/6128 【参考方案1】:

您可以简单地使用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 将多类向量/您的多类表示分配给您的图像。请注意,xy 不是单个示例,而是批量示例,因此应将其包含在您的 multiclasses_getter 设计中。

【讨论】:

你不是说 multilabel_flow_from_directory 和 multilabeles_getter 吗?【参考方案2】:

您可以编写一个自定义生成器类,该类将从目录中读取文件并应用标签。该自定义生成器还可以接收一个 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(), ...)

*免责声明:我还没有实际测试过,但理论上它应该可以工作。

【讨论】:

您可能还需要在 get_next_batch() 方法下使用 while True:...,因为生成器应该在无限循环中提供数据。【参考方案3】:
# 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))

validation_stepssteps_per_epoch 可能超出原始参数的值。

steps_per_epoch= (int(num_of_training_examples/batch_size) 可能会有所帮助。 同样validation_steps= (int(num_of_val_examples/batch_size) 会有所帮助

【讨论】:

欢迎来到 Stack Overflow。请参考How do I write a good answer?。特别要注意正确格式化代码部分并解释包含的代码如何回答/解决 OP 的问题。

以上是关于如何在 keras flow_from_directory 中手动指定类标签?的主要内容,如果未能解决你的问题,请参考以下文章

keras如何快速入门

如何使用 tensorflow 在 keras 中禁用 GPU?

Keras 如何读取输入数据?

如何在多核上运行 Keras?

如何在训练 tensorflow.keras 期间替换损失函数

如何在 keras 中获得可重现的结果