如何从张量中获取随机子张量?
How to get a random sub-tensor from a tensor?
我想从一个张量中得到一个随机的子张量,形状是固定的。例如,
我需要从左张量中获取右张量,并且每一行的索引都是随机的,就像这样:
[[1 4 3] [[3] [[4]
[3 2 1] -----> [2] or [1] (generate randomly)
[0 3 4]] [3]] [0]]
我试过tf.slice和tf.gather,都没有用。我试着写了一个这样的代码测试用例:
import random
import tensorflow as tf
a = tf.convert_to_tensor([[[1, 4, 3]],
[[3, 2, 1]],
[[0, 3, 4]]])
T = a.get_shape().as_list()[0]
result_list = []
for i in range(T):
idx = random.randint(0, 2) # get a random idx
result_list.append(a[i][0][idx])
y_hat = tf.reshape(tf.convert_to_tensor(result_list), shape=(T, 1))
with tf.Session() as sess:
print(sess.run(y_hat))
# y_hat: [[4]
# [1]
# [4]]
在这个测试用例中,它起作用了。但是在真实环境中,'a'.shape=(None, 3), 所以
'T = a.get_shape().as_list()[0]' 不是 int 值,我不能按范围 (T) 迭代 T。
例如:
import random
import tensorflow as tf
a = tf.placeholder(shape=(None, 3), dtype=tf.int32)
result_list = []
T = a.get_shape().as_list()[0]
for i in range(T):
idx = random.randint(0, 2) # get a random idx
result_list.append(a[i][0][idx])
y_hat = tf.reshape(tf.convert_to_tensor(result_list), shape=(T, 1))
with tf.Session() as sess:
a_instance = [[[1, 4, 3]],
[[3, 2, 1]],
[[0, 3, 4]]]
print(sess.run(y_hat, feed_dict={a: a_instance}))
在这种情况下,它不起作用。谁能告诉我该怎么办?
这就是你可以用 tf.gather_nd
做到这一点的方法:
import tensorflow as tf
with tf.Graph().as_default(), tf.Session() as sess:
tf.random.set_random_seed(0)
a = tf.constant([[1, 4, 3],
[3, 2, 1],
[0, 3, 4]])
s = tf.shape(a)
rows, cols = s[0], s[1]
# Row indices
ii = tf.expand_dims(tf.range(rows), 1)
# Column indices
jj = tf.random.uniform((rows, 1), 0, cols, dtype=ii.dtype)
# Gather result
result = tf.gather_nd(a, tf.stack([ii, jj], axis=-1))
# Print some results
print(sess.run(result))
# [[3]
# [2]
# [4]]
print(sess.run(result))
# [[4]
# [1]
# [0]]
print(sess.run(result))
# [[3]
# [2]
# [0]]
我通常使用 numpy 库来执行此操作。
import numpy as np
a_instance = np.array([[1,4,3],[3,2,1],[0,3,4]])
a_instance = a_instance.T # transpose the matrix
np.random.shuffle(a_instance) # it performs the shuffle of the rows
a_instance = a_instance.T
然后你可以用下面的代码得到你想要的一列:
a_column = a_instance[:, 0]
通过这种方式,您可以将想要的随机列作为 numpy 数组,然后您可以将其与 tensorflow 一起使用,如图所示:
...
print(sess.run(y_hat, feed_dict={a: [a_column.tolist()]}))
如果您不想永久修改 "a_instance" 矩阵,请记住将 "a_instance" 的副本与随机播放方法一起使用。
我想从一个张量中得到一个随机的子张量,形状是固定的。例如, 我需要从左张量中获取右张量,并且每一行的索引都是随机的,就像这样:
[[1 4 3] [[3] [[4]
[3 2 1] -----> [2] or [1] (generate randomly)
[0 3 4]] [3]] [0]]
我试过tf.slice和tf.gather,都没有用。我试着写了一个这样的代码测试用例:
import random
import tensorflow as tf
a = tf.convert_to_tensor([[[1, 4, 3]],
[[3, 2, 1]],
[[0, 3, 4]]])
T = a.get_shape().as_list()[0]
result_list = []
for i in range(T):
idx = random.randint(0, 2) # get a random idx
result_list.append(a[i][0][idx])
y_hat = tf.reshape(tf.convert_to_tensor(result_list), shape=(T, 1))
with tf.Session() as sess:
print(sess.run(y_hat))
# y_hat: [[4]
# [1]
# [4]]
在这个测试用例中,它起作用了。但是在真实环境中,'a'.shape=(None, 3), 所以
'T = a.get_shape().as_list()[0]' 不是 int 值,我不能按范围 (T) 迭代 T。
例如:
import random
import tensorflow as tf
a = tf.placeholder(shape=(None, 3), dtype=tf.int32)
result_list = []
T = a.get_shape().as_list()[0]
for i in range(T):
idx = random.randint(0, 2) # get a random idx
result_list.append(a[i][0][idx])
y_hat = tf.reshape(tf.convert_to_tensor(result_list), shape=(T, 1))
with tf.Session() as sess:
a_instance = [[[1, 4, 3]],
[[3, 2, 1]],
[[0, 3, 4]]]
print(sess.run(y_hat, feed_dict={a: a_instance}))
在这种情况下,它不起作用。谁能告诉我该怎么办?
这就是你可以用 tf.gather_nd
做到这一点的方法:
import tensorflow as tf
with tf.Graph().as_default(), tf.Session() as sess:
tf.random.set_random_seed(0)
a = tf.constant([[1, 4, 3],
[3, 2, 1],
[0, 3, 4]])
s = tf.shape(a)
rows, cols = s[0], s[1]
# Row indices
ii = tf.expand_dims(tf.range(rows), 1)
# Column indices
jj = tf.random.uniform((rows, 1), 0, cols, dtype=ii.dtype)
# Gather result
result = tf.gather_nd(a, tf.stack([ii, jj], axis=-1))
# Print some results
print(sess.run(result))
# [[3]
# [2]
# [4]]
print(sess.run(result))
# [[4]
# [1]
# [0]]
print(sess.run(result))
# [[3]
# [2]
# [0]]
我通常使用 numpy 库来执行此操作。
import numpy as np
a_instance = np.array([[1,4,3],[3,2,1],[0,3,4]])
a_instance = a_instance.T # transpose the matrix
np.random.shuffle(a_instance) # it performs the shuffle of the rows
a_instance = a_instance.T
然后你可以用下面的代码得到你想要的一列:
a_column = a_instance[:, 0]
通过这种方式,您可以将想要的随机列作为 numpy 数组,然后您可以将其与 tensorflow 一起使用,如图所示:
...
print(sess.run(y_hat, feed_dict={a: [a_column.tolist()]}))
如果您不想永久修改 "a_instance" 矩阵,请记住将 "a_instance" 的副本与随机播放方法一起使用。