使用布尔张量进行Tensorflow索引

时间:2015-11-17 23:27:40

标签: python indexing tensorflow

在numpy中,有两个形状相同的数组xy,可以像y[x > 1]一样进行切片。你如何在张量流中获得相同的结果? y[tf.greater(x, 1)]不起作用,tf.slice也不支持此类内容。有没有办法立即使用布尔张量进行索引或当前是否支持?

5 个答案:

答案 0 :(得分:15)

尝试:

ones = tf.ones_like(x) # create a tensor all ones
mask = tf.greater(x, ones) # boolean tensor, mask[i] = True iff x[i] > 1
slice_y_greater_than_one = tf.boolean_mask(y, mask)

请参阅tf.boolean_mask

编辑:另一种(更好?)方式:

import tensorflow as tf

x = tf.constant([1, 2, 0, 4])
y = tf.Variable([1, 2, 0, 4])
mask = x > 1
slice_y_greater_than_one = tf.boolean_mask(y, mask)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print (sess.run(slice_y_greater_than_one)) # [2 4]

答案 1 :(得分:6)

我不会说它完全没有实现。对于双重否定而言,这是怎样的?

Tensorflow实际上支持相当多的切片和切块,尽管语法可能稍微不那么漂亮。例如,如果要在y时创建一个等于x>1的新数组,否则等于0,那么你肯定可以这样做。查看comparison operators例如

masked = tf.greater(x,1)
zeros = tf.zeros_like(x)
new_tensor = tf.where(masked, y, zeros)

另一方面,如果要创建一个新数组,其中只包含x>1的人,可以将wheregather函数合并。有关gather的详细信息,请访问

https://www.tensorflow.org/versions/master/api_docs/python/array_ops/slicing_and_joining

PS。当然,x>1x方面是不可区分的... ... tf可能很好,但它并不起作用魔法:)。

答案 2 :(得分:3)

目前尚未实施,此处是跟踪进度的GitHub问题 - https://github.com/tensorflow/tensorflow/issues/206

答案 3 :(得分:1)

tf.boolean_mask完成这项工作,但在某些平台上,例如Raspberry Pi或OSX,Tensorflow轮分发中不支持该操作(请检查tf.boolean_mask not supported on OSX。所以另一种方法是使用where和@Jackson Loper建议的gather。例如:

x = tf.Variable([1, 2, 0, 4])
ix = tf.where(x > 1)
y = tf.gather(x, ix)

with tf.Session() as sess:
 sess.run(tf.global_variables_initializer())
 print(sess.run(y))

答案 4 :(得分:1)

正在寻找类似的功能来按定义的标准减少TensorFlow.js张量,但TensorFlow.js没有boolean_mask函数。经过大量的拔发和咬牙切齿的工作后,烹饪了以下内容,该步骤实质上汇总了真实条件的总数,然后简单地选择topk值来创建子集张量。

const a = tf.tensor1d([1, 2, 0, 4]);
const b = a.greater(1).sum().get();
const {values, indices} = tf.topk(a, b);
values.print();   # 4,2
indices.print();  # 3,1

要创建一个值小于或等于1的子集张量,就可以在张量上使用tf.neg,因为没有bottomk函数,然后通过topk获得子集张量后,应用tf.neg再次恢复原始值。