【问题标题】:shuffling two tensors in the same order以相同的顺序改组两个张量
【发布时间】:2019-10-27 18:36:21
【问题描述】:

如上。我尝试了这些都无济于事:

tf.random.shuffle( (a,b) )
tf.random.shuffle( zip(a,b) )

我曾经连接它们并进行洗牌,然后取消连接/解包。但是现在我处于(a)是 4D 秩张量而(b)是 1D 的情况,所以,没有办法连接。

我还尝试将种子参数提供给 shuffle 方法,以便它重现相同的 shuffle 并且我使用它两次 => 失败。还尝试用随机打乱的数字范围自己进行改组,但是 TF 在花哨的索引和东西方面不如 numpy 灵活 ==> 失败。

我现在正在做的是,将所有内容转换回 numpy,然后使用 sklearn 中的 shuffle,然后通过重铸回到张量。这纯粹是愚蠢的方式。这应该发生在图表内。

【问题讨论】:

  • 您能否提供一个更清晰的示例来说明您正在尝试做什么?什么是确切的形状张量?据我了解,您需要连接两个不同形状的张量(4D 和 1D),并应用可重现的 shuffle op(每次运行的顺序相同)。对吗?
  • 没有。我想要的是洗牌 4D 张量的元素(元素沿着第一个维度,即批处理轴)。我希望一维张量的元素以完全相同的方式洗牌。我没有做到这一点,而 concat 技巧只是达到我想要的东西的一种手段。谢谢。哦,同样,可重现的 shuffle 只是一个单独的 shuffle 的技巧(运行命令两次)。谢谢。

标签: tensorflow tensorflow2.0 tensorflow2.x


【解决方案1】:

您可以只打乱索引,然后使用tf.gather() 提取对应于这些打乱索引的值:

TF2.x(更新)

import tensorflow as tf
import numpy as np

x = tf.convert_to_tensor(np.arange(5))
y = tf.convert_to_tensor(['a', 'b', 'c', 'd', 'e'])

indices = tf.range(start=0, limit=tf.shape(x)[0], dtype=tf.int32)
shuffled_indices = tf.random.shuffle(indices)

shuffled_x = tf.gather(x, shuffled_indices)
shuffled_y = tf.gather(y, shuffled_indices)

print('before')
print('x', x.numpy())
print('y', y.numpy())

print('after')
print('x', shuffled_x.numpy())
print('y', shuffled_y.numpy())
# before
# x [0 1 2 3 4]
# y [b'a' b'b' b'c' b'd' b'e']
# after
# x [4 0 1 2 3]
# y [b'e' b'a' b'b' b'c' b'd']

TF1.x

import tensorflow as tf
import numpy as np

x = tf.placeholder(tf.float32, (None, 1, 1, 1))
y = tf.placeholder(tf.int32, (None))

indices = tf.range(start=0, limit=tf.shape(x)[0], dtype=tf.int32)
shuffled_indices = tf.random.shuffle(indices)

shuffled_x = tf.gather(x, shuffled_indices)
shuffled_y = tf.gather(y, shuffled_indices)

确保在同一会话运行中计算 shuffled_xshuffled_y。否则他们可能会得到不同的索引排序。

# Testing
x_data = np.concatenate([np.zeros((1, 1, 1, 1)),
                         np.ones((1, 1, 1, 1)),
                         2*np.ones((1, 1, 1, 1))]).astype('float32')
y_data = np.arange(4, 7, 1)

print('Before shuffling:')
print('x:')
print(x_data.squeeze())
print('y:')
print(y_data)

with tf.Session() as sess:
  x_res, y_res = sess.run([shuffled_x, shuffled_y],
                          feed_dict={x: x_data, y: y_data})
  print('After shuffling:')
  print('x:')
  print(x_res.squeeze())
  print('y:')
  print(y_res)
Before shuffling:
x:
[0. 1. 2.]
y:
[4 5 6]
After shuffling:
x:
[1. 2. 0.]
y:
[5 6 4]

【讨论】:

  • 你是个天才。或者,可能只有我从未听说过 tf.gather :D 多么奇怪的命令名称。我必须学会自己命名一切的方式。与 Pytorch 相比,这是 TF 的一大缺点。谢谢你的时间。一个完美的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-04
  • 2012-04-09
  • 2012-11-12
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
相关资源
最近更新 更多