我目前正在尝试为 TF 制作一个增强类,如下所示:
class Augmentations:
def __init__(self, **kwargs):
# Some Global Kwargs Define Here
self.transforms = tf.eye(3)
self.img_height = kwargs['img_height']
self.img_width = kwargs['img_width']
def _generate_random(self, shape, seed, minval, maxval):
return tf.random_uniform(shape=shape,
minval=minval,
maxval=maxval,
seed=seed,
dtype=tf.float32)
def rotate(self, seed, max_angle):
random_rotation_value = self._generate_random([1], seed, 0., max_angle)
rotation_matrix = tf.contrib.image.angles_to_projective_transforms(
random_rotation_value,
self.img_height,
self.img_width)
rotation_matrix = tf.reshape(tf.concat([rotation_matrix, [[1.]]], axis=1),
[3, 3])
self.transforms = tf.matmul(self.transforms, rotation_matrix)
return self
def apply(self, img):
t = tf.reshape(tf.matmul(self.transforms[0],
self.transforms[1]),
[1, 9])[0, :8]
return tf.contrib.image.transform(img, t)
我已经尝试了dataset.map
和tf.map_fn
,两者都返回一致的转换,即:
augment = Augment(**kwargs).rotate(None, 30).shear(None, 30)
dataset = dataset.map(augment.apply, num_parallel_calls=10)
和
augment = Augment(**kwargs).rotate(None, 30).shear(None, 30)
dataset = tf.map_fn(augment.apply)
这两个调用都返回应用了相同转换的不同图像。
使用随机变换返回图像的唯一方法是调用map()
中的变换:
dataset = dataset.map(Augment(**kwargs).rotate(None, 30).shear(None, 30).apply, num_parallel_calls=10)
或将所有随机数移动到apply()
中。
random_*()
调用的放置在TF中是否重要,我认为放置无关紧要,是否仅对map_fn
重要?
预期行为,因为对 apply
方法的所有调用共享相同的tf.random_uniform
操作。调用session.run
时,此随机操作将计算一次,其结果将用于所有元素。
在 apply 中调用tf.random_uniform
会有所不同,因为您将创建多个随机操作,每个操作都会生成不同的随机序列。它基本上是以下两者之间的区别:
sess = tf.InteractiveSession()
x = tf.random_uniform((1,))
y = tf.stack([x * tf.constant(1.0), x * tf.constant(1.0)])
y.eval()
# Prints
# array([[ 0.67649043],
# [ 0.67649043]], dtype=float32)
# because there is only one random operation in the graph and it is evaluated once.
和
sess = tf.InteractiveSession()
y = tf.stack([tf.random_uniform((1,)) * tf.constant(1.0), tf.random_uniform((1,)) * tf.constant(1.0)])
y.eval()
# Prints
# array([[ 0.08824277],
# [ 0.4801079 ]], dtype=float32)
# because there are two random operations in the graph and each yields a different value when evaluated
非常基本的是,张量流session.run()
每次调用最多评估一次操作(假设它不在while
循环或类似循环中(。