在 Keras 中加入两个 DirectoryIterator

Ric*_*ard 1 python machine-learning generator keras

假设我有以下内容:

image_data_generator = ImageDataGenerator(rescale=1./255)

train_generator = image_data_generator.flow_from_directory(
  'my_directory',
  target_size=(28, 28),
  batch_size=32,
  class_mode='categorical'
)
Run Code Online (Sandbox Code Playgroud)

然后 mytrain_generator填充来自 的数据my_directory,其中包含两个子文件夹,将数据分为类01.

假设我还有另一个目录that_directory,也将数据拆分为类01. 我想train_generator用这个额外的数据来增强我的。

运行train_generator = image_data_generator.flow_from_directory('that_directory', ...)会从 中删除先前的数据my_directory

有没有办法在DirectoryIterator不改变文件夹结构本身的情况下将两组数据增加或附加到一个生成器或一个像 a 一样操作的对象中?

tod*_*day 5

只需将生成器组合到另一个生成器中,可选择使用不同的增强配置:

idg1 = ImageDataGenerator(**idg1_configs)
idg2 = ImageDataGenerator(**idg2_configs)

g1 = idg1.flow_from_directory('idg1_dir',...)
g2 = idg2.flow_from_directory('idg2_dir',...)

def combine_gen(*gens):
    while True:
        for g in gens:
            yield next(g)

# ...
model.fit_generator(combine_gen(g1, g2), steps_per_epoch=len(g1)+len(g2), ...)
Run Code Online (Sandbox Code Playgroud)

这将从g1和交替生成批次g2

请注意,有人可能会建议使用itertools.chain,但是您不能在这里使用它,因为ImageDataGenerators生成器是永无止境的并且不断地生成批量数据。这是您传递给fit_generator方法的生成器所期望的。来自Keras 文档

...预计生成器将无限期地循环其数据。当steps_per_epoch模型看到批次时,时代结束。

steps_per_epoch如果未设置将默认为len(generator)那里generator是你传递给发电机fit_generator的方法。该ImageDataGenerator发电机可以给它们的长度,所以你不需要手动设置你steps_per_epoch的说法。如果您想使用上面的组合生成器进行相同的操作,则可以改用此解决方案:

class CombinedGen():
    def __init__(self, *gens):
        self.gens = gens

    def generate(self):
        while True:
            for g in self.gens:
                yield next(g)

    def __len__(self):
        return sum([len(g) for g in self.gens])

# usage:
cg = CombinedGen(g1, g2)
model.fit_generator(cg.generate(), ...) # no need to set `steps_per_epoch`
Run Code Online (Sandbox Code Playgroud)

如果您有兴趣直接迭代此类的对象(而不是迭代),您还可以向类添加__next__和/或__iter__方法。CombinedGencg.generate()