1

我正在尝试了解如何使用 Albumentations 构建数据增强管道以提供 Keras 模型。我正在关注这个示例-> https://albumentations.ai/docs/examples/tensorflow-example/,他们在其中创建了一个数据集对象 PrefetchDataset 并将其传递给 model.fit()。请参见下面的代码:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import tensorflow_datasets as tfds
from functools import partial
from albumentations import (
    Compose, RandomBrightness, JpegCompression, HueSaturationValue, RandomContrast, HorizontalFlip,
    Rotate
)
AUTOTUNE = tf.data.experimental.AUTOTUNE

#load data
data, info= tfds.load(name="tf_flowers", split="train", as_supervised=True, with_info=True)
data

# augmentations
transforms = Compose([
            Rotate(limit=40),
            RandomBrightness(limit=0.1),
            JpegCompression(quality_lower=85, quality_upper=100, p=0.5),
            HueSaturationValue(hue_shift_limit=20, sat_shift_limit=30, val_shift_limit=20, p=0.5),
            RandomContrast(limit=0.2, p=0.5),
            HorizontalFlip(),
        ])


def aug_fn(image, img_size):
    data = {"image":image}
    aug_data = transforms(**data)
    aug_img = aug_data["image"]
    aug_img = tf.cast(aug_img/255.0, tf.float32)
    aug_img = tf.image.resize(aug_img, size=[img_size, img_size])
    return aug_img

def process_data(image, label, img_size):
    aug_img = tf.numpy_function(func=aug_fn, inp=[image, img_size], Tout=tf.float32)
    return aug_img, label

# create dataset
ds_alb = data.map(partial(process_data, img_size=120),
                  num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE)


# ...And then just pass this dataset object to the model

def create_model(input_shape):
    pass
    # define model layers...

model = create_model(input_shape)

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy', run_eagerly=True)
model.fit(ds_alb, epochs=2)

我的问题是:这个对象ds_alb在训练期间是否为每批返回不同的图像(根据随机参数集)?我已经阅读了代码,似乎所有的增强Compose都只执行了一次,在这里:

ds_alb = data.map(partial(process_data, img_size=120), num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE)

但我相信构建这条管道的目的是在每次传递时提供不同的增强图像,而不是只增强一次……有些东西我不明白。如何检查是否正在生成不同的图像?

4

1 回答 1

1

我不确定tf.numpy_function每个批次是否会调用该函数一次或多次。但是有一个简单的方法来测试它。在里面放一张印刷品aug_fn,分两批:

def aug_fn(...):
    print("Called")
    ....

batch = next(ds_alb) #depending on the type of generator, you might need ds_alb[0]   
another_batch = next(ds_alb) #or ds_alb[1]

#also check the shape of the batch to make sure there are many images

如果“Called”多次出现,则表示每张图像都会进行一次转换。如果它只出现两次,则每批进行一次转换。如果它只出现一次,那么代码就有问题。

老实说,我更喜欢“每批次一次转换”,因为这将代表性能的巨大提升,这很重要。有时预处理可能是限制性能的操作。

但这不会超出增强的目的吗?

不!您正在向模型提供许多批次,并且大概,尽管您对整个批次进行了相同的预处理,但您有不同的源图像!当然,您的下一批将有不同的预处理。

由于您将训练多个 epoch,当然,相同的图像将在稍后的 epoch 中再次出现,并进行不同的预处理。最后,pass 的数量会很大,以至于在单个批次中使用相同的预处理对模型来说不会是问题。

于 2022-02-24T12:44:56.930 回答