[英]Custom image generator function interpreted as a generator object?
I recently learned that Python interprets functions with return and functions with yield separately.我最近了解到 Python 分别解释带 return 的函数和带 yield 的函数。 I made this custom generator that uses Keras ImageDataGenerator to generates batches of images from a directory into a GAN Deep Learning network:我制作了这个自定义生成器,它使用 Keras ImageDataGenerator 从目录生成批量图像到 GAN 深度学习网络:
def loadRealImages(batch):
for gen in pixGen.flow_from_directory(picturesPath, target_size = (256, 256),
batch_size = batch, class_mode = "binary"):
realImgs = [image for image in gen]
yield realImgs[0]
My program expect what this generator yields (tensor of batch images) to run an analysis through a network and output a prediction:我的程序期望这个生成器产生什么(批量图像的张量)通过网络和 output 进行预测:
real = loadRealImages(1) # get one real image
prediction = discriminator([real, fake]) # check similarity
My problem is that because of the call to the custom generator, real is considered a generator object loadRealImages when the program is expecting an image in tensor form and I get this error:我的问题是,由于调用了自定义生成器,当程序期望张量形式的图像时, real被认为是生成器 object loadRealImages并且我收到此错误:
AttributeError: 'generator' object has no attribute '_keras_mask_'
From what I found looking into the problem, it seems generators don't get executed during interpretation.从我发现的问题来看,似乎生成器在解释期间没有被执行。 Then how should I bypass this check during interpretation?那么在解释过程中我应该如何绕过这个检查呢?
PS: in this particular line, I only need one image so I could load it in a different way but I have others of these generator calls throughout the code and I can't really delete them. PS:在这个特定的行中,我只需要一个图像,因此我可以以不同的方式加载它,但我在整个代码中还有其他这些生成器调用,我无法真正删除它们。
I don't know about the keras library, but generators are a bit different from functions in that calling them returns a generator, not the first yield
object.我不知道 keras 库,但是生成器与函数有点不同,因为调用它们会返回一个生成器,而不是第一个yield
object。 You have to call next
on the returned generator to get the image您必须在返回的生成器上调用next
才能获取图像
def img_generator(num_imgs):
for ii in range(num_imgs):
yield np.random.random((256, 256)) > 0
one_img_generator = img_generator(1)
img = next(one_img_generator)
next(one_img_generator) # will raise StopIteration
Does that make sense?那有意义吗?
Your generator could also be made more 'natural', ie the pythonic way of writing it would be:您的生成器也可以变得更“自然”,即 Pythonic 的编写方式是:
def loadRealImages(batch):
for gen in pixGen.flow_from_directory(picturesPath, target_size = (256, 256),
batch_size = batch, class_mode = "binary"):
yield next(gen)
This way, the whole list isn't placed into memory at the same time (if gen
is a generator).这样,整个列表不会同时放入 memory 中(如果gen
是生成器)。 Instead, only the requested element is in memory.相反,只有请求的元素在 memory 中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.