【问题标题】:kedro: train image classifier with keras ImageDataGeneratorkedro:使用 keras ImageDataGenerator 训练图像分类器
【发布时间】:2021-01-20 12:28:40
【问题描述】:

在处理图像和 keras ImageDataGenerator 时应该使用哪个 kedro 数据集?我知道有ImageDataset,但图像数量太大而无法放入内存。而 keras ImageDataGenerator 真正需要的只是图像数据集的本地文件夹位置,格式为:

data/
    train/
        dogs/
            dog001.jpg
            dog002.jpg
            ...
        cats/
            cat001.jpg
            cat002.jpg
            ...
    validation/
        dogs/
            dog001.jpg
            dog002.jpg
            ...
        cats/
            cat001.jpg
            cat002.jpg
            ...

可以使用指定数据位置的参数,但我认为数据的适当位置应该是数据目录。是否有一种简单的方法可以在数据目录中指定此数据位置?

【问题讨论】:

    标签: python tensorflow keras kedro


    【解决方案1】:

    如何在parameters.yml 中设置路径,然后将其作为 ImageDataGenerator 的输入读取。它可能看起来像:

    train_dogs_location: data/train/dogs/
    

    根据最佳情况修改上述示例。 您还可以考虑为conf/base/globals.yml 文件中的所有数据集设置全局路径。例如,对于您的根数据文件夹。

    【讨论】:

    • 感谢@Shubham Agrawal 的回答。这就是我目前正在做的事情,但我想知道是否有办法指定数据目录中的数据位置(我认为它属于哪里)?
    • 我非常怀疑任何 Kedro 数据集都具有这样的属性。使用参数文件可能会更好。如果您必须使用 DataSet,则将位置和数据集存储在某种形式的字典中,然后 PickleDataSet 可能是另一种选择。
    • 谢谢,我想我会选择/保留参数文件选项,因为在数据目录中组织数据集不是强制性的。但是,我认为 kedro 缺少某种可以在数据目录中使用的 tf.data.Dataset 类型。
    • 我可能会同意你的看法。我认为您可能值得在他们的回购中打开票证/问题并解释为什么这可能是一个有益的功能。可能会从社区中获得更多支持/见解。
    【解决方案2】:

    我认为您的问题有两部分很重要;

    1. 是否可以配置自定义 ImageDataGenerator 数据集? (TLDR;是的)
    2. 是否可以使用与我的用例匹配的文件路径参数来配置上述内容? (TLDR;是的,但您可能不希望您的目录结构成为目录结构的默认视图,因为其他用户可能也无法使用它)。

    是否可以配置自定义 ImageDataGenerator 数据集?

    这里有一些不完整的 Python 代码,可用于构建自定义数据集。如果您想要这样的解决方案,我会留给您使其正常工作。查看 Kedro Github Repo 中的示例数据集以获取灵感,并查看 kedro 阅读文档中的 tutorial on creating custom datasets

    import tensorflow as tf 
    from kedro.io.core import AbstractDataSet
    
    class ImageDataGeneratorDataSet(AbstractDataSet):
    
        def __init__(
            self,
            filepath: str,
            load_args: Dict[str, Any] = None,
            save_args: Dict[str, Any] = None):
            
            self.filepath = filepath
            self.load_args = load_args
            self.save_args = save_args 
    
    
        def load(self):
            generator = tf.keras.preprocessing.image.ImageDataGenerator(**self.load_args)
            return generator.flow_from_directory(self.filepath)
    
        def save(self, data):
            raise Exception("Saving with the ImageDataGeneratorDataSet is not supported")
    

    2:是否可以用符合我用例的文件路径参数来配置以上内容?

    虽然我们可以修改上面的内容以接收一些参数并返回不同的迭代器,但如果目录结构不同,这可能会给我们带来问题。这是因为参数化很大程度上依赖于通用约定。

    如果您的约定是data/{train/validation}/{dog/cat}/images...,那么您提取和应用参数的解决方案可能会与火车/验证和狗/猫的相应顺序相关联,并且可能不适用于可能具有 @ 约定的其他用户987654330@.

    也许更好的模式是实现一个解决方案(就像我在第一部分中概述的那样),在目录中为每个不同的训练/验证数据注册一个数据集,并在运行时将迭代器组合在您的节点来创建训练和验证迭代器。

    例如,您将拥有数据集 train_cats、train_dogs、validation_cats、validation_dogs。在节点中,您可以将这些迭代器 izip 一起压缩(参见 https://stackoverflow.com/a/243902/13341083)。

    如果您最终采用这种方法,请提出 PR 并做出贡献 :) 祝您好运

    【讨论】:

    • 感谢@William Ashford。我也考虑过编写一个自定义数据集。但我主要担心的是tf.keras.preprocessing.image.ImageDataGenerator 返回一个DirectoryIterator,我不知道这是否可以腌制,我认为这是 kedro 要求的,以便在不同节点之间传递输出。
    • 我知道酸洗/深度复制不能直接使用tf.data.Dataset,这是我最终想要的,使用 keras ImageDataGenerator。我在another question 中询问过这个问题。你知道MemoryDatasetcopy_mode = assign 没有深拷贝吗?
    • 无论如何ImageDataGeneratorDataset 是有道理的,如果它有效,我会提出一个 PR。
    • 关于第二部分:我仅部分同意您的观点,因为据我所知,keras ImageDataGenerator 需要以下文件夹层次结构约定:data/{class_0, class_1, ... class_n}。数据可以是训练或验证。请参阅flow_from_directoryclassessubsets 参数了解更多详情。
    • 我添加了一个PR,但它需要一些讨论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 2017-07-15
    • 2019-07-05
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 2019-05-17
    相关资源
    最近更新 更多