我将如何在 Tensorflow 中随机采样像素?
How would I randomly sample pixels in Tensorflow?
假设我有一个形状为 (b,h,w,d) 的张量
b: batch_size
h: height of image
w: width of image
d: feature dimension
我如何从中抽取一组 100 个随机选择的像素,这样我就有一个形状为 (b, 100, d) 的张量?
还有,不知道h, w
测试时是这样的怎么办?
通用策略是使用 TF 创建所有必要的像素坐标,然后应用 tf.gather_nd
。即使形状未知,这也有效。
import tensorflow as tf
import numpy as np
b, h, w, d = 2, 4, 6, 4
data = np.arange(b * h * w * d).reshape(b, h, w, d)
# forget shape
b, h, w, d = None, None, None, None
# make TF has no idea what the original dimensions were
data_pldhr = tf.placeholder(tf.float32, [None, None, None, None])
data_shape = tf.shape(data)
B_op, H_op, W_op, D_op = [data_shape[i] for i in range(4)]
# add chose same data for each batch (other case is even more trivial)
REPEAT = 10
pixel_h = tf.random_uniform([REPEAT], minval=0, maxval=H_op, dtype=tf.int32)
pixel_w = tf.random_uniform([REPEAT], minval=0, maxval=H_op, dtype=tf.int32)
pixel_h = tf.expand_dims(pixel_h, axis=0)
pixel_w = tf.expand_dims(pixel_w, axis=0)
pixel_h = tf.tile(pixel_h, [B_op, 1])
pixel_w = tf.tile(pixel_w, [B_op, 1])
# add batch-dimension
b_idx = tf.tile(tf.expand_dims(tf.range(0, B_op), axis=-1), [1, REPEAT])
# combine everything
pixel_pos = tf.stack([b_idx, pixel_h, pixel_w], axis=-1)
selected_pixels = tf.gather_nd(data_pldhr, pixel_pos)
with tf.Session() as sess:
ret = sess.run([tf.shape(selected_pixels), selected_pixels, pixel_pos], {data_pldhr: data})
print ret[0] # shape of output: [ 2 10 4]
print ret[1] # content with the previous shape
print ret[2] # selected pixel positions
请注意,您始终可以使用
直接为每个批次条目生成不同的坐标,而不是沿批次维度平铺
count_op = tf.mul(B_op, REPEAT)
tf.random_uniform([count_op], minval=0, maxval=H_op, dtype=tf.int32)
假设我有一个形状为 (b,h,w,d) 的张量
b: batch_size
h: height of image
w: width of image
d: feature dimension
我如何从中抽取一组 100 个随机选择的像素,这样我就有一个形状为 (b, 100, d) 的张量?
还有,不知道h, w
测试时是这样的怎么办?
通用策略是使用 TF 创建所有必要的像素坐标,然后应用 tf.gather_nd
。即使形状未知,这也有效。
import tensorflow as tf
import numpy as np
b, h, w, d = 2, 4, 6, 4
data = np.arange(b * h * w * d).reshape(b, h, w, d)
# forget shape
b, h, w, d = None, None, None, None
# make TF has no idea what the original dimensions were
data_pldhr = tf.placeholder(tf.float32, [None, None, None, None])
data_shape = tf.shape(data)
B_op, H_op, W_op, D_op = [data_shape[i] for i in range(4)]
# add chose same data for each batch (other case is even more trivial)
REPEAT = 10
pixel_h = tf.random_uniform([REPEAT], minval=0, maxval=H_op, dtype=tf.int32)
pixel_w = tf.random_uniform([REPEAT], minval=0, maxval=H_op, dtype=tf.int32)
pixel_h = tf.expand_dims(pixel_h, axis=0)
pixel_w = tf.expand_dims(pixel_w, axis=0)
pixel_h = tf.tile(pixel_h, [B_op, 1])
pixel_w = tf.tile(pixel_w, [B_op, 1])
# add batch-dimension
b_idx = tf.tile(tf.expand_dims(tf.range(0, B_op), axis=-1), [1, REPEAT])
# combine everything
pixel_pos = tf.stack([b_idx, pixel_h, pixel_w], axis=-1)
selected_pixels = tf.gather_nd(data_pldhr, pixel_pos)
with tf.Session() as sess:
ret = sess.run([tf.shape(selected_pixels), selected_pixels, pixel_pos], {data_pldhr: data})
print ret[0] # shape of output: [ 2 10 4]
print ret[1] # content with the previous shape
print ret[2] # selected pixel positions
请注意,您始终可以使用
直接为每个批次条目生成不同的坐标,而不是沿批次维度平铺count_op = tf.mul(B_op, REPEAT)
tf.random_uniform([count_op], minval=0, maxval=H_op, dtype=tf.int32)