waltwhite
waltwhite

Reputation: 53

Receiving the same (not random) augmentations of image dataset

dataset = tf.data.Dataset.range(1, 6) 

def aug(y):
    x = np.random.uniform(0,1)
    if x > 0.5:
         y = 100
    return y

dataset = dataset.map(aug)
print(list(dataset))

Run this code, then all the elements in the dataset are as they were, or all equal to 100. How do I make it so each element is individually transformed? My more specific question below is basically asking this

I create my segmentation training set by:

dataset = tf.data.Dataset.from_tensor_slices((image_paths, mask_paths))

I then apply my augmentation function to the dataset:

def augment(image_path, mask_path)):
    //use tf.io.read_file and tf.io.decode_jpeg to convert paths to tensors
    
    x = np.random.choice([0,1])
    if x == 1:
        image = tf.image.flip_up_down(image) 
        mask = tf.image.flip_up_down(mask)

    return image, mask

training_dataset = dataset.map(augment)
BATCH_SIZE=2
training_dataset = training_dataset.shuffle(100, reshuffle_each_iteration=True)
training_dataset = training_dataset.batch(BATCH_SIZE)
training_dataset = training_dataset.repeat()
training_dataset = training_dataset.prefetch(-1)

However when I visualise my training dataset, all the images have same flip applied- the are all either flipped upside down or not flipped. Where as I'm expecting them to have different flips- some upside down and some not.

Why is this happening?

Upvotes: 1

Views: 395

Answers (2)

jkr
jkr

Reputation: 19280

You need to use tensorflow operations (not numpy or normal python) because tf.data.Dataset.map() executes the mapped function as a graph. When converting a function to a graph, numpy and base python are converted to constants. The augmentation function is only running np.random.uniform(0,1) once and storing it as a constant.

Note that irrespective of the context in which map_func is defined (eager vs. graph), tf.data traces the function and executes it as a graph.

The source for the above is here.

One solution is to use tensorflow operations. I have included an example below. Note that the y value in the if has to be cast to the same dtype as the input.

dataset = tf.data.Dataset.range(1, 6) 

def aug(y):
    x = tf.random.uniform([], 0, 1)
    if x > 0.5:
        y = tf.cast(100, y.dtype)
    return y

dataset = dataset.map(aug)
print(list(dataset))

Upvotes: 1

Armin Azhdehnia
Armin Azhdehnia

Reputation: 145

You can use a uniform random function or other probability distribution

tf.random.uniform(
shape, minval=0, maxval=None, dtype=tf.dtypes.float32, seed=None, name=None
)

even you can use prebuild method in TensorFlow or Keras for fliping

tf.keras.layers.experimental.preprocessing.RandomFlip(
mode=HORIZONTAL_AND_VERTICAL, seed=None, name=None, **kwargs
)

Upvotes: 0

Related Questions