Yagel
Yagel

Reputation: 1312

How to rotate tensor image randomly

I want to rotate my images in parallel, using 'map', in the preprocessing stage.

The problem is that every image is rotated for the same direction (after one random number generated). But I want that each image will have different degree of rotation.

This is my code:

import tensorflow_addons as tfa
import math
import random
def rotate_tensor(image, label):
    degree = random.random()*360
    image = tfa.image.rotate(image, degree * math.pi / 180, interpolation='BILINEAR')
    return image, label

rotated_test_set = rps_test_raw.map(rotate_tensor).batch(batch_size).prefetch(1)

I tried to change the seed every call for the function:

import tensorflow_addons as tfa
import math
import random
seed_num = 0
def rotate_tensor(image, label):
    seed_num += 1
    random.seed(seed_num)
    degree = random.random()*360
    image = tfa.image.rotate(image, degree * math.pi / 180, interpolation='BILINEAR')
    return image, label

rotated_test_set = rps_test_raw.map(rotate_tensor).batch(batch_size).prefetch(1)

But I get:

UnboundLocalError: local variable 'seed_num' referenced before assignment

I use tf2, but I don't think it matter much (beside the code to rotate the image).


Edit: I tried what @Mehraban suggested, but it seems that rotate_tensor function is being called only once:

import tensorflow_addons as tfa
import math
import random

num_seed = 1
def rotate_tensor(image, label):
    global num_seed
    num_seed += 1
    print(num_seed) #<---- print num_seed
    random.seed(num_seed)
    degree = random.random()*360
    image = tfa.image.rotate(image, degree * math.pi / 180, interpolation='BILINEAR')
    return image, label

rotated_test_set = rps_test_raw.map(rotate_tensor).batch(batch_size).prefetch(1)

But it only prints "2" once. So I think the rotate_tensor is being called once.


Edit 2 - This is the function that show the rotated images:

plt.figure(figsize=(12, 10))

for X_batch, y_batch in rotated_test_set.take(1):
    for index in range(9):
        plt.subplot(3, 3, index + 1)
        plt.imshow(X_batch[index])
        plt.title("Predict: {} | Actual: {}".format(class_names[y_test_proba_max_index[index]], class_names[y_batch[index]]))
        plt.axis("off")

plt.show()

enter image description here

Upvotes: 2

Views: 2200

Answers (1)

Mehraban
Mehraban

Reputation: 3324

The problem is with how you generate random numbers. You rely on random module though you should be using tf.random when dealing with tensorflow.

Here is a demonstration of how things change when you get random numbers from tf:

import tensorflow as tf
import random

def gen():
    for i in range(10):
        yield [1.]

ds = tf.data.Dataset.from_generator(gen, (float))

def m1(d):
    return d*random.random()

def m2(d):
    return d*tf.random.normal([])

[d for d in ds.map(m2)]
[0.17368042,
 1.5629852,
 1.2372143,
 1.8170034,
 1.7040217,
 -0.16738933,
 -0.11567844,
 -0.17949782,
 -0.67811996,
 -0.5391556]

[d for d in ds.map(m1)]
[0.8369798,
 0.8369798,
 0.8369798,
 0.8369798,
 0.8369798,
 0.8369798,
 0.8369798,
 0.8369798,
 0.8369798,
 0.8369798]

Upvotes: 3

Related Questions