在 tf.data.Datasets.from_generator 中将多个参数传递给生成器

Passing Multiple Arguments to Generator in tf.data.Datasets.from_generator

我有一个包含各种尺寸图像的文件夹。我需要将它们全部调整为 (160,120) 并创建一个 tf.data.Dataset。为此,我使用了 tf.data.Dataset.from_generator。但我似乎无法弄清楚如何将其他参数发送给生成器,如 target_size、class_mode 等,而不是目录本身。 [注意:我使用的是 Tensorflow 2.0 Beta1]

args 参数采用 tf.Tensor 个对象并将它们用作生成器的参数。我尝试将所有参数作为列表传递。

# gen is the ImageDataGenerator

real_imgs_dataset = tf.data.Dataset.from_generator(gen.flow_from_directory,
                                      args = 
                                            (data_path,    # DIRECTORY
                                            (160, 128),    # TARGET SIZE
                                            'rgb',         # COLOR MODE
                                             None,         # CLASSES
                                             None,         # CLASS MODE
                                             32,           # BATCH SIZE
                                             True),        # SHUFFLE
                                        output_types = tf.float32, 
                                        output_shapes = ([None,160,128,3])
                                       )

我想做的是通过生成器传递图像,生成器会逐批吐出图像并创建一个 tf.data.Dataset。但是,当我尝试 运行 上面的代码片段时,我收到一条错误消息:-

"ValueError: Attempt to convert a value (None) with an unsupported type () to a Tensor"

我在那里报告了一个类似的问题:https://github.com/tensorflow/tensorflow/issues/33133

建议的适合您情况的解决方案是:

gen_mod = gen.flow_from_directory(directory=data_path, target_size=(
    160, 128), class_mode=None, batch_size=32, shuffle=True)

real_imgs_dataset = tf.data.Dataset.from_generator(
    lambda: gen_mod,
    output_types=tf.float32,
    output_shapes=([None, 160, 128, 3])
)

希望对您有所帮助!

使用 lambda 的解决方案部分有效。 但是在我目前的环境中(TensorFlow2.6.0),我观察到lambda生成的值不会在epochs之间重置。

作为解决方法,可以使生成器具有双层,如下所示。

def new_gen():
    gen_mod = gen.flow_from_directory(directory=data_path, target_size=(
        160, 128), class_mode=None, batch_size=32, shuffle=True)

    for x in gen_mod:
        yield x

real_imgs_dataset = tf.data.Dataset.from_generator(
    new_gen,
    output_types=tf.float32,
    output_shapes=([None, 160, 128, 3])
)