I have only recently started working with Tensorflow2. I'm trying to re-program a script that randomly cuts squares out of images. The original code comes from this github repository: Link. I fail due to the tf.while_for() loop in Tensorflow2. But here is the code I wrote so far:
def random_erasing(img, probability = 0.5, sl = 0.02, sh = 0.4, r1 = 0.3):
'''
img is a 3-D variable (ex: tf.Variable(image, validate_shape=False) ) and HWC order
probability: The probability that the operation will be performed.
sl: min erasing area
sh: max erasing area
r1: min aspect ratio
mean: erasing value
'''
i = tf.constant(0)
N = tf.constant(100)
while_condition = lambda i: tf.less(i, N)
def body(i):
def calculate_valid_boxes(h, w):
h_tmp = tf.Variable(tf.shape(img)[1]-h, dtype=tf.dtypes.int32)
w_tmp = tf.Variable(tf.shape(img)[2]-w, dtype=tf.dtypes.int32)
# x1 = random.randint(0, img.size()[1] - h)
# y1 = random.randint(0, img.size()[2] - w)
x1 = tf.map_fn(lambda x: tf.random.uniform([], minval=0, maxval=x, dtype=tf.dtypes.int32), h_tmp)
y1 = tf.map_fn(lambda x: tf.random.uniform([], minval=0, maxval=x, dtype=tf.dtypes.int32), w_tmp)
return x1, y1
area = tf.shape(img)[1] * tf.shape(img)[2]
target_area = tf.random.uniform([3], minval=sl, maxval=sh, dtype=tf.dtypes.float64) * tf.cast(area, tf.dtypes.float64)
aspect_ratio = tf.cast(tf.random.uniform([3], minval=r1, maxval=1/r1), tf.dtypes.float64)
h = tf.cast(tf.math.round(tf.sqrt(target_area * aspect_ratio)), tf.dtypes.int32)
w = tf.cast(tf.math.round(tf.sqrt(target_area / aspect_ratio)), tf.dtypes.int32)
# if condition: w < img.size()[2] and h < img.size()[1]:
cond_1 = tf.less(w, tf.shape(img)[2])
cond_2 = tf.less(h,tf.shape(img)[1])
x1 = tf.cond(tf.cast(tf.logical_and(cond_1, cond_2), tf.int32) == 3, lambda: calculate_valid_boxes(h, w))
return h, w, x1, y1
# mask_size= area of cutout, offset= place of cutout, constant_value=pixel value to fill in at cutout
image = tfa.image.cutout(img, mask_size=(h, w), offset=(x1, y1), constant_values=255)
return image
My problem lies in the following line:
x1 = tf.cond(tf.cast(tf.logical_and(cond_1, cond_2), tf.int32) == 3, calculate_valid_boxes(h, w))
I always get "Exception has occurred: TypeError cond(): false_fn argument required" messages. I want to call the function "calculate_valid_boxes()" in this line if the statement is true or if the statement is false I want to jump to a new iteration.
In plain Python you could solve this either with "break" or "continue" statement (depending on the implementation) but with Tensorflow2 I'm not able to find a solution.
If the information is relevant, the function works with a batch of images.