【问题标题】:How can a generator (ImageDataGenerator) run out of data?生成器 (ImageDataGenerator) 如何耗尽数据?
【发布时间】:2021-08-08 17:42:28
【问题描述】:

让我们从一个包含 1000 张图片的文件夹开始

现在,如果我们使用 no generatorbatch_size = 10steps_per_epoch = 100,我们将使用每张图片作为 10 * 100 = 1000。所以增加steps_per_epoche 将(正确地)导致错误:

tensorflow:你的输入数据用完了;中断训练。确保您的数据集或生成器至少可以生成 steps_per_epoch * epochs 个批次(在本例中为 10000 个批次)

另一方面,使用生成器会产生无穷无尽的图像:

datagenerator = ImageDataGenerator(
    rescale=1./255,
    shear_range=0.1,
    zoom_range=0.1,
    # ...
)

imageFlow = datagenerator.flow_from_directory(
        image_dir_with_1000_pcs,
        target_size=(150, 150),
        batch_size=10,
        class_mode='binary')

i = 0
for x, y in imageFlow:
  print(x.shape) # batch of images
  
  i += 1
  if i > 3000:
    break # I break, because it ENDLESSLY goes on otherwise

但是,如果我去跑步

history = model.fit(
      imageFlow,
      steps_per_epoch=101, # I increased this above 100!
      epochs=5,
      #...
)

我会得到同样的错误:为什么? model.fit() 获得了一个生成器,因此获得了无穷无尽的批次。无休止的批处理怎么会耗尽数据?

在发布这个问题之前,我阅读了:

【问题讨论】:

  • 还期望数据增强的供应源源不断。我猜实施更改为Dataset。您找到解决方法了吗?我一直在寻找它通过数据增强再次循环。
  • 对不起,我在这里帮不了你,因为我只是在寻找对我没想到的行为的解释。但我认为你不需要解决这个问题,因为每个时代你都会得到不同的增强数据。因此,如果您愿意,无尽的时代 == 无尽的增强数据,或者?否则可以预先准备批次,这是一个简单的解决方法。

标签: python tensorflow keras


【解决方案1】:

生成器(ImageDataGenerator)如何耗尽数据?

据我所知,它会从生成器中创建一个tf.data.Dataset,它不会无限运行,这就是您在拟合时看到这种行为的原因。

如果它是一个无限数据集,那么您必须指定steps_per_epoch

编辑:如果您不指定steps_per_epoch,那么训练将在number_of_batches >= len(dataset) // batch_size 时停止。它在每个时期都完成。

要检查引擎盖下到底发生了什么,您可以查看the source。可以看出,创建了一个tf.data.Dataset,它实际上处理了批处理和历元迭代。

【讨论】:

  • 但是tensorflow.org/api_docs/python/tf/keras/preprocessing/image/… 的文档指出“我们需要手动中断循环,因为 [...] 生成器无限循环”。顺便说一句,获取 tf.data.Dataset 本身就是一项任务 - 请参阅:stackoverflow.com/questions/54606302/…
  • 是的,这就是生成器在 TF 中的工作方式。 model.fit() 实际处理终止过程。如果你想创建一个手动训练过程,那么你必须处理纪元结束等。我的意思是在引擎盖下它返回一个 tf.data.Dataset
  • 好的,对我来说,模型在每个步骤中都要求批量数据。批次可以由发电机无休止地交付。并且模型在时代结束之前仍然耗尽了数据。为什么?没有len(imageFlow)。它一直在继续。 model.fit() 上的文档甚至声明“当传递 无限重复数据集 时,您必须指定 steps_per_epoch 参数。”。
  • 我真的很抱歉,但我无法遵循 生成器的长度 部分。生成器在主动使用 break 之前屈服,怎么会有长度?你能这么好心,可能会尝试不同的措辞吗?我真的很想弄清楚它。
  • 对不起,我删除了它,编辑了答案。现在清楚了吗?
猜你喜欢
  • 1970-01-01
  • 2018-03-05
  • 1970-01-01
  • 1970-01-01
  • 2013-03-01
  • 1970-01-01
  • 2018-06-08
  • 2022-01-03
相关资源
最近更新 更多