如何在 Tensorflow 中随机转换或移动批量张量

use*_*700 0 python tensorflow

我想让我的输入图像(张量)在每批中随机向上/向下或向右/向左移动。

例如,我有一批大小为 的灰度图像[10, 48, 64, 1]

如果有一张图片,我知道我可以使用 tf.pad 和 tf.slice(或其他内置函数)

但我想通过一次操作将随机移位应用于 10 个不同的图像。

是否可以?还是应该使用诸如 tf.scan 之类的循环?

bsa*_*ter 5

作为替代方案,您还可以使用tf.contrib.image.transform()并使用参数a2b2来转换图像:

import numpy as np
import tensorflow as tf

image1 = np.array([[[.1], [.1], [.1], [.1]],
                  [[.2], [.2], [.2], [.2]],
                  [[.3], [.3], [.3], [.3]],
                  [[.4], [.4], [.4], [.4]]])
image2 = np.array([[[.1], [.2], [.3], [.4]],
                  [[.1], [.2], [.3], [.4]],
                  [[.1], [.2], [.3], [.4]],
                  [[.1], [.2], [.3], [.4]]])
images = np.stack([image1, image2])
images_ = tf.convert_to_tensor(images, dtype=tf.float32)

shift1_x = 1
shift1_y = 2
shift2_x = -1
shift2_y = 0
transforms_ = tf.convert_to_tensor([[1, 0, -shift1_x, 0, 1, -shift1_y, 0, 0],
                                   [1, 0, -shift2_x, 0, 1, -shift2_y, 0, 0]],
                                   tf.float32)
shifted_ = tf.contrib.image.transform(images=images_,
                                      transforms=transforms_)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    shifted = sess.run([shifted_])
    print(shifted)
Run Code Online (Sandbox Code Playgroud)

变换投影矩阵也可以是大小为N×8的张量,所以有可能将一批每个图像不同地移动。这可以通过tf.random_uniform()轻松扩展,以在每个图像的 x/y 偏移中包含一些随机性。

编辑: 要对批次的每个图像使用随机移位:

...
images_ = tf.convert_to_tensor(images, dtype=tf.float32)

num_imgs = images.shape[0]
base_ = tf.convert_to_tensor(np.tile([1, 0, 0, 0, 1, 0, 0, 0], [num_imgs, 1]), dtype=tf.float32)
mask_ = tf.convert_to_tensor(np.tile([0, 0, 1, 0, 0, 1, 0, 0], [num_imgs, 1]), dtype=tf.float32)
random_shift_ = tf.random_uniform([num_imgs, 8], minval=-2.49, maxval=2.49, dtype=tf.float32)
transforms_ = base_ + random_shift_ * mask_

shifted_ = tf.contrib.image.transform(images=images_,
                                      transforms=transforms_)
...
Run Code Online (Sandbox Code Playgroud)

编辑 2: 为了完成起见,这里只是另一个辅助函数,它对批次的每个单个图像应用随机旋转和移位:

def augment_data(input_data, angle, shift):
    num_images_ = tf.shape(input_data)[0]
    # random rotate
    processed_data = tf.contrib.image.rotate(input_data,
                                             tf.random_uniform([num_images_],
                                                               maxval=math.pi / 180 * angle,
                                                               minval=math.pi / 180 * -angle))
    # random shift
    base_row = tf.constant([1, 0, 0, 0, 1, 0, 0, 0], shape=[1, 8], dtype=tf.float32)
    base_ = tf.tile(base_row, [num_images_, 1])
    mask_row = tf.constant([0, 0, 1, 0, 0, 1, 0, 0], shape=[1, 8], dtype=tf.float32)
    mask_ = tf.tile(mask_row, [num_images_, 1])
    random_shift_ = tf.random_uniform([num_images_, 8], minval=-shift, maxval=shift, dtype=tf.float32)
    transforms_ = base_ + random_shift_ * mask_

    processed_data = tf.contrib.image.transform(images=processed_data,
                                                transforms=transforms_)
    return processed_data
Run Code Online (Sandbox Code Playgroud)