【问题标题】:Confusion regarding data generator in python for use in Keras fit_generator关于在 Keras fit_generator 中使用 python 中的数据生成器的困惑
【发布时间】:2019-12-04 23:38:02
【问题描述】:

在下面的一些问题和教程中:

  1. Why is an iterable object not an iterator?
  2. Generator "TypeError: 'generator' object is not an iterator"

建议 keras 的数据生成器应该是一个包含 __iter____next__ 方法的类。

而其他一些教程如:

  1. https://keunwoochoi.wordpress.com/2017/08/24/tip-fit_generator-in-keras-how-to-parallelise-correctly/
  2. https://www.altumintelligence.com/articles/a/Time-Series-Prediction-Using-LSTM-Deep-Neural-Networks

使用带有 yield 语句的普通 python 函数来提供数据。虽然我按照上面的第二个教程在 LSTM 网络中成功使用了 yield,但我无法在卷积网络中使用正常的 yield 函数并在 fit_generator 中得到以下错误:

'method'对象不是迭代器

我没有尝试使用 __next__ 方法,但建议遇到上述错误的人使用 __next__ 方法(编辑:在 Daniel Möller 建议的修复后工作)。有人可以帮我澄清一下何时使用哪种技术,以及“yields”下一个示例的函数与具有 __iter____next__ 的类之间有什么区别

我使用 yield 的工作代码: https://github.com/KashyapCKotak/Multidimensional-Stock-Price-Prediction/blob/master/StockTF1_4Sequential.ipynb

我当前使用 yield 的数据生成器函数(编辑:在 Daniel Möller 建议的修复后工作):

def train_images_generator(self):
    for epoch in range(0, self.epochs):
      print("Current Epoch:",epoch)
      cnt = 0
      if epoch > 2000:
        learning_rate = 1e-5

      for ind in np.random.permutation(len(self.train_ids)):
        print("provided image with id:",ind)
        #get the input image and target/ground truth image based on ind
        raw = rawpy.imread(in_path)
        input_images = np.expand_dims(pack_raw(raw), axis=0) * ratio # pack the bayer image in 4 channels of RGBG

        gt_raw = rawpy.imread(gt_path)
        im = gt_raw.postprocess(use_camera_wb=True,
                      half_size=False,
                      no_auto_bright=True, output_bps=16)
        gt_images = np.expand_dims(np.float32(im / 65535.0),axis=0) # divide by 65535 to normalise (scale between 0 and 1)

        # crop

        H = input_images.shape[1] # get the image height (number of rows)
        W = input_images.shape[2] # get the image width (number of columns)

        xx = np.random.randint(0, W - ps) # get a random number in W-ps (W-512)
        yy = np.random.randint(0, H - ps) # get a random number in H-ps (H-512)
        input_patch = input_images[:, yy:yy + ps, xx:xx + ps, :]
        gt_patch = gt_images[:, yy * 2:yy * 2 + ps * 2, xx * 2:xx * 2 + ps * 2, :]

        if np.random.randint(2) == 1:  # random flip for rows
          input_patch = np.flip(input_patch, axis=1)
          gt_patch = np.flip(gt_patch, axis=1)
        if np.random.randint(2) == 1:  # random flip for columns
          input_patch = np.flip(input_patch, axis=2)
          gt_patch = np.flip(gt_patch, axis=2)
        if np.random.randint(2) == 1:  # random transpose
          input_patch = np.transpose(input_patch, (0, 2, 1, 3))
          gt_patch = np.transpose(gt_patch, (0, 2, 1, 3))\

        input_patch = np.minimum(input_patch, 1.0)

        yield (input_patch,gt_patch)

我如何使用它:

model.fit_generator(
  generator=data.train_images_generator(),
  steps_per_epoch=steps_per_epoch,
  epochs=epochs,
  callbacks=callbacks,
  max_queue_size=50
  #workers=0

)

【问题讨论】:

  • 奇怪的是,随着架构的变化,您无法生成数据。这几乎是两个不同的东西。您能否通过提供一些代码来说明您的具体操作方式来澄清您的观点?
  • 实际上,我并没有提供我的做法,而是提供了一些讨论的链接以及代码示例。我正在做的方式与链接中的示例相同。 (我已经参考了这些链接来制作生成器)
  • 将在尝试“next”方法后更新代码。但是只是好奇地问为什么当某些给定的示例与产量一起使用时,为什么甚至首先需要它。
  • @today 已添加代码。请你看看。

标签: python keras


【解决方案1】:

仔细观察'method'这个词,我发现你没有“调用”你的生成器(你没有创建它)。

您传递的只是函数/方法。

假设你有:

def generator(...):
    ...
    yield x, y

而不是类似的东西:

model.fit_generator(generator)

你应该这样做:

model.fit_generator(generator(...))

生成器或序列

使用生成器(带有yield 的函数)和keras.utils.Sequence 有什么区别?

使用生成器时,训练将遵循确切的循环顺序,并且不知道何时结束。所以。

使用生成器:

  • 无法打乱批次,因为它将始终遵循循环的顺序
  • 必须通知steps_per_epoch,因为Keras 无法知道生成器何时完成(Keras 的生成器必须是无限的)
  • 如果使用多处理,系统可能无法正确处理批次,因为无法知道哪个进程将在其他进程之前启动或完成。

Sequence:

  • 您可以控制生成器的长度。 Keras 自动知道批次的数量
  • 您可以控制批次的索引,因此 Keras 可以对批次进行洗牌。
  • 你可以拿任意批次你想要多少次(你不必按顺序拿批次)
  • 多处理可以使用索引来确保最终不会混合批次。

【讨论】:

  • 谢谢!您的回答是正确的,它部分解决了我的问题。部分原因是我还需要知道问题中提到的产量和其他方法的差异。这是否意味着可以使用具有 yield 的方法而不是扩展 keras.util.Sequence 或具有 iter 和 next 函数的类?还是它们之间有什么重要区别?一旦你回答了这个问题,我就会接受。谢谢!
  • @DanielMoller 我有一个类似的问题可以生成序列。我目前正在使用 LSTM 模型。请让我知道你的想法。问题链接:stackoverflow.com/questions/59978301/… 期待您的回音。非常感谢。 :)
猜你喜欢
  • 1970-01-01
  • 2020-07-05
  • 2021-01-11
  • 1970-01-01
  • 2017-11-22
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
  • 2016-01-11
相关资源
最近更新 更多