Sorting 如何在tensorflow中对一批2D张量进行排序?
我有一个张量Sorting 如何在tensorflow中对一批2D张量进行排序?,sorting,multidimensional-array,tensorflow,Sorting,Multidimensional Array,Tensorflow,我有一个张量a,形状为[#batch,#MaxSequence,#Features],其中第二维度的实际长度(可能小于#MaxSequence)存储在一个张量L中。我想在每个批次的序列上按第三维中的第二个特征对A进行排序。我使用tf.gather和tf.nn.top_k对二维张量进行排序,但我不知道如何将其应用于三维情况。我需要使用loop来完成吗?我有一些工作,但可能存在更好的解决方案。我想对于这个简单的问题,我的代码可能过于复杂了 其思想是,我们必须将tf.nn.top_k(a[:,:,1)
a
,形状为[#batch,#MaxSequence,#Features]
,其中第二维度的实际长度(可能小于#MaxSequence
)存储在一个张量L
中。我想在每个批次的序列上按第三维中的第二个特征对A
进行排序。我使用tf.gather
和tf.nn.top_k
对二维张量进行排序,但我不知道如何将其应用于三维情况。我需要使用loop来完成吗?我有一些工作,但可能存在更好的解决方案。我想对于这个简单的问题,我的代码可能过于复杂了
其思想是,我们必须将tf.nn.top_k(a[:,:,1)]的返回索引(按第三维度中第二个特征的顺序)转换为可以使用的东西。特别是对于我下面的示例,我们需要将
[[3, 2, 1, 0],
[0, 1, 2, 3],
[2, 0, 3, 1]]
到
我发现:
- 首先展平目标索引,从而得到
[3 2 1 0 1 2 3 2 0 3 1]
- 有意地构造一对向量
[0 0 0 0 1 1 2 2 2]
tf.stack
将上述两个向量叠加,然后我们将结果重塑为期望的结果
完整的tf代码如下(get\u shape
方法已定义):
将tensorflow导入为tf
a=tf.变量([[0.51,0.52,0.53,0.94,0.35],
[0.32, 0.72, 0.83, 0.74, 0.55],
[0.23, 0.73, 0.63, 0.64, 0.35],
[0.01, 0.74, 0.73, 0.04, 0.75]],
[[0.32, 0.76, 0.83, 0.74, 0.55],
[0.23, 0.72, 0.63, 0.64, 0.35],
[0.11, 0.02, 0.03, 0.14, 0.15],
[0.01, 0.00, 0.73, 0.04, 0.75]],
[[0.51, 0.52, 0.53, 0.94, 0.35],
[0.32, 0.00, 0.83, 0.74, 0.55],
[0.23, 0.92, 0.63, 0.64, 0.35],
[0.11,0.02,0.03,0.14,0.15]],tf.32)
批次大小、序列长度、数量特征=获取形状(a)
idx=tf.重塑(范围(批次大小),[-1,1])
idx_flat=tf.重塑(tf.平铺(idx,[1,序列长度],[-1])
top_k_flat=tf.重塑(tf.nn.top_k(a[:,:,1],
k=序列长度)。指数,[-1])
最终idx=tf.重塑(tf.堆叠([idx_平面,顶部k_平面],1),
[批次大小,序列长度,2])
重新排序=tf.gather\u nd(a,final\u idx)
sess=tf.InteractiveSession()
sess.run(tf.global\u variables\u initializer())
打印sess.run(重新排序)
#有序的
#由此
#列(每个示例中)
[[[ 0.01 , 0.74000001, 0.73000002, 0.04 , 0.75 ],
[ 0.23 , 0.73000002, 0.63 , 0.63999999, 0.34999999],
[ 0.31999999, 0.72000003, 0.82999998, 0.74000001, 0.55000001],
[ 0.50999999, 0.51999998, 0.52999997, 0.94 , 0.34999999]],
[[ 0.31999999, 0.75999999, 0.82999998, 0.74000001, 0.55000001],
[ 0.23 , 0.72000003, 0.63 , 0.63999999, 0.34999999],
[ 0.11 , 0.02 , 0.03 , 0.14 , 0.15000001],
[ 0.01 , 0. , 0.73000002, 0.04 , 0.75 ]],
[[ 0.23 , 0.92000002, 0.63 , 0.63999999, 0.34999999],
[ 0.50999999, 0.51999998, 0.52999997, 0.94 , 0.34999999],
[ 0.11 , 0.02 , 0.03 , 0.14 , 0.15000001],
[ 0.31999999, 0. , 0.82999998, 0.74000001, 0.55000001]]
请注意,在输出中,我们有三个示例。在每个示例中,序列按第二个特征向下排序。谢谢!这一点并不复杂(与循环相比)。我们可以将其应用于长度可变但填充为seq_length
?例如,a[0][3][:]如果填充值为0.0,则序列[0]的实际长度为3,而a[1]和a[2]的实际长度仍然为4。我认为get_shape
将解决这一问题,只要使用全零向量填充(所有特征均为零。因此,在对这些填充序列进行排序后,它们将成为示例中的最后几个序列。由于我在将每个特征读入此三维张量之前对其进行了规格化,其中一些特征将为负值。也许我应该用非常负值(例如-9998)填充它们?是的,这是有意义的,至少对于第二个特征而言是如此。)(您排序的那个)您应该进行更改。更新:为了在第一个维度上使用None
大小,我稍微更改了idx=tf.reformate(range(batch\u size),[-1,1])
到idx=tf.reformate(tf.range(batch\u size),[-1,1])
。
[[[0 3], [0 2], [0 1], [0 0]]
[[1 0], [1 1], [1 2], [1 3]]
[[2 2], [2 0], [2 3], [2 1]]]