关于在Keras fit_generator中使用的python中的数据生成器的困惑

时间:2019-07-26 15:39:06

标签: python keras

在某些问题和类似以下的教程中:

  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中遇到以下错误:

  

“方法”对象不是迭代器

我没有尝试使用 __ next __ 方法,但是建议遇到上述错误的人使用 __ next __ 方法(编辑:根据DanielMöller建议的修复方法进行工作)。有人可以帮我澄清一下什么时候使用哪种技术,下一个示例“ 产生”的函数与带有 __ iter __ __ next__的类之间的区别是什么。

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

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

public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
List<MyEntity> findByMyListEmpty(); //My problem is here
}

我如何使用它:

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)

1 个答案:

答案 0 :(得分: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可以随机播放批次。
  • 您可以根据需要进行任意批次的批处理(不必强制按顺序进行批处理)
  • 多重处理可以使用索引来确保批次最终不会混合。