TF2 数据增强随机性
TF2 Data Augmentation Randomness
我一直在尝试向模型添加自定义扩充。然而,虽然 tf.image.random_flip_left_right
或 tf.image.random_brightness
等库函数实际上起作用并为每个样本中的每个图像创建随机变化,但我的自定义函数始终对所有批次中的所有图像具有相同的效果。
例如,这些是我的 "random" 高斯和运动模糊函数:
@tf.function
def gaussian(image, n_channels, dtype):
size = np.random.randint(2, 6)
sigma = np.random.uniform(0.5, 4.0)
x = tf.range(-size // 2 + 1, size // 2 + 1, dtype=dtype)
g = tf.math.exp(-(tf.pow(x, 2) / (2 * tf.pow(tf.cast(sigma, dtype), 2))))
g_norm2d = tf.pow(tf.reduce_sum(g), 2)
k = tf.tensordot(g, g, axes=0) / g_norm2d
k = tf.expand_dims(k, axis=-1)
k = tf.expand_dims(tf.tile(k, (1, 1, n_channels)), axis=-1)
return tf.nn.depthwise_conv2d(image[None], k, [1,1,1,1], 'SAME')[0]
@tf.function
def motion(image, n_channels, dtype):
size = np.random.randint(2, 11)
k = np.zeros((size, size))
k[int((size-1)/2), :] = np.ones(size)
k = k / size
k = tf.convert_to_tensor(k, dtype=dtype)
k = tf.expand_dims(k, axis=-1)
k = tf.expand_dims(tf.tile(k, (1, 1, n_channels)), axis=-1)
return tf.nn.depthwise_conv2d(image[None], k, [1,1,1,1], 'SAME')[0]
正如我所说,我的图像具有随机亮度、翻转等。但它们都具有相同的运动和高斯模糊,这不是我想要的。
编辑:为了澄清,我在 augment(image, label)
函数中顺序调用所有扩充函数,该函数通过 dataset.map(augment)
调用。这适用于其他增强。
好的,所以我尝试了很多东西,但让它起作用的是只使用 TF 函数...这迫使我稍微更改代码并使事情变得更复杂,但嘿,这就是 TF 给你的。
代码现在看起来像这样:
@tf.function
def gaussian(image, n_channels):
size = tf.random.uniform([1], 2, 6, dtype=tf.int32)[0]
sigma = tf.random.uniform([1], 0, 4.0, dtype=tf.float32)[0]
x = tf.range(-size // 2 + 1, size // 2 + 1, dtype=tf.float32)
g = tf.math.exp(-(tf.pow(x, 2) / (2 * tf.pow(tf.cast(sigma, dtype=tf.float32), 2))))
g_norm2d = tf.pow(tf.reduce_sum(g), 2)
k = tf.tensordot(g, g, axes=0) / g_norm2d
k = tf.expand_dims(k, axis=-1)
k = tf.expand_dims(tf.tile(k, (1, 1, n_channels)), axis=-1)
return tf.nn.depthwise_conv2d(image[None], k, [1,1,1,1], 'SAME')[0]
@tf.function
def motion(image, n_channels):
size = tf.random.uniform([1], 2, 11, dtype=tf.int32)[0]
a = tf.zeros(((size-1)/2, size))
b = tf.reshape(tf.ones((size)), [1,size])
k = tf.concat([a,b,a], 0)
k = k / tf.cast(size, tf.float32)
k = tf.expand_dims(k, axis=-1)
k = tf.expand_dims(tf.tile(k, (1, 1, n_channels)), axis=-1)
return tf.nn.depthwise_conv2d(image[None], k, [1,1,1,1], 'SAME')[0]
我一直在尝试向模型添加自定义扩充。然而,虽然 tf.image.random_flip_left_right
或 tf.image.random_brightness
等库函数实际上起作用并为每个样本中的每个图像创建随机变化,但我的自定义函数始终对所有批次中的所有图像具有相同的效果。
例如,这些是我的 "random" 高斯和运动模糊函数:
@tf.function
def gaussian(image, n_channels, dtype):
size = np.random.randint(2, 6)
sigma = np.random.uniform(0.5, 4.0)
x = tf.range(-size // 2 + 1, size // 2 + 1, dtype=dtype)
g = tf.math.exp(-(tf.pow(x, 2) / (2 * tf.pow(tf.cast(sigma, dtype), 2))))
g_norm2d = tf.pow(tf.reduce_sum(g), 2)
k = tf.tensordot(g, g, axes=0) / g_norm2d
k = tf.expand_dims(k, axis=-1)
k = tf.expand_dims(tf.tile(k, (1, 1, n_channels)), axis=-1)
return tf.nn.depthwise_conv2d(image[None], k, [1,1,1,1], 'SAME')[0]
@tf.function
def motion(image, n_channels, dtype):
size = np.random.randint(2, 11)
k = np.zeros((size, size))
k[int((size-1)/2), :] = np.ones(size)
k = k / size
k = tf.convert_to_tensor(k, dtype=dtype)
k = tf.expand_dims(k, axis=-1)
k = tf.expand_dims(tf.tile(k, (1, 1, n_channels)), axis=-1)
return tf.nn.depthwise_conv2d(image[None], k, [1,1,1,1], 'SAME')[0]
正如我所说,我的图像具有随机亮度、翻转等。但它们都具有相同的运动和高斯模糊,这不是我想要的。
编辑:为了澄清,我在 augment(image, label)
函数中顺序调用所有扩充函数,该函数通过 dataset.map(augment)
调用。这适用于其他增强。
好的,所以我尝试了很多东西,但让它起作用的是只使用 TF 函数...这迫使我稍微更改代码并使事情变得更复杂,但嘿,这就是 TF 给你的。
代码现在看起来像这样:
@tf.function
def gaussian(image, n_channels):
size = tf.random.uniform([1], 2, 6, dtype=tf.int32)[0]
sigma = tf.random.uniform([1], 0, 4.0, dtype=tf.float32)[0]
x = tf.range(-size // 2 + 1, size // 2 + 1, dtype=tf.float32)
g = tf.math.exp(-(tf.pow(x, 2) / (2 * tf.pow(tf.cast(sigma, dtype=tf.float32), 2))))
g_norm2d = tf.pow(tf.reduce_sum(g), 2)
k = tf.tensordot(g, g, axes=0) / g_norm2d
k = tf.expand_dims(k, axis=-1)
k = tf.expand_dims(tf.tile(k, (1, 1, n_channels)), axis=-1)
return tf.nn.depthwise_conv2d(image[None], k, [1,1,1,1], 'SAME')[0]
@tf.function
def motion(image, n_channels):
size = tf.random.uniform([1], 2, 11, dtype=tf.int32)[0]
a = tf.zeros(((size-1)/2, size))
b = tf.reshape(tf.ones((size)), [1,size])
k = tf.concat([a,b,a], 0)
k = k / tf.cast(size, tf.float32)
k = tf.expand_dims(k, axis=-1)
k = tf.expand_dims(tf.tile(k, (1, 1, n_channels)), axis=-1)
return tf.nn.depthwise_conv2d(image[None], k, [1,1,1,1], 'SAME')[0]