【问题标题】:how does tensorflow indexing work张量流索引如何工作
【发布时间】:2016-05-05 23:18:44
【问题描述】:

我无法理解 tensorflow 的基本概念。索引如何对张量读/写操作起作用?为了明确这一点,如何将以下 numpy 示例转换为 tensorflow(使用张量来分配数组、索引和值):

x = np.zeros((3, 4))
row_indices = np.array([1, 1, 2])
col_indices = np.array([0, 2, 3])
x[row_indices, col_indices] = 2
x

带输出:

array([[ 0.,  0.,  0.,  0.],
       [ 2.,  0.,  2.,  0.],
       [ 0.,  0.,  0.,  2.]])

...和...

x[row_indices, col_indices] = np.array([5, 4, 3])
x

带输出:

array([[ 0.,  0.,  0.,  0.],
       [ 5.,  0.,  4.,  0.],
       [ 0.,  0.,  0.,  3.]])

...最后...

y = x[row_indices, col_indices]
y

带输出:

array([ 5.,  4.,  3.])

【问题讨论】:

  • 许多你可以用 numpy 做的事情在 tensorflow 中不受支持。看到这个问题stackoverflow.com/questions/33736795/…也许你可以通过更新这些矩阵值来解释更多你想要完成的事情,有人可以回答如何在tensorflow中实现这个结果。
  • 感谢您的链接。我想尝试几种图像增强(在 tensorflow 库中尚不可用),以期提高学习到的图像分类网络的通用性。我不需要梯度流过这些操作,我可以在 CPU 上轻松完成,但这成为一个巨大的性能瓶颈。我想我应该能够用雅罗斯拉夫的回答做我需要做的事情。

标签: tensorflow


【解决方案1】:

github issue #206 可以很好地支持这一点,同时你必须求助于冗长的解决方法

第一个示例可以使用 tf.select 完成,它通过从一个或另一个中选择每个元素来组合两个相同形状的张量

tf.reset_default_graph()
row_indices = tf.constant([1, 1, 2])
col_indices = tf.constant([0, 2, 3])
x = tf.zeros((3, 4))
sess = tf.InteractiveSession()

# get list of ((row1, col1), (row2, col2), ..)
coords = tf.transpose(tf.pack([row_indices, col_indices]))

# get tensor with 1's at positions (row1, col1),...
binary_mask = tf.sparse_to_dense(coords, x.get_shape(), 1)

# convert 1/0 to True/False
binary_mask = tf.cast(binary_mask, tf.bool)

twos = 2*tf.ones(x.get_shape())

# make new x out of old values or 2, depending on mask 
x = tf.select(binary_mask, twos, x)

print x.eval()

给予

[[ 0.  0.  0.  0.]
 [ 2.  0.  2.  0.]
 [ 0.  0.  0.  2.]]

第二个可以用scatter_update 完成,除了scatter_update 只支持线性索引和变量。因此,您可以创建一个临时变量并像这样使用整形。 (为了避免变量,你可以使用dynamic_stitch,见最后)

# get linear indices
linear_indices = row_indices*x.get_shape()[1]+col_indices

# turn 'x' into 1d variable since "scatter_update" supports linear indexing only
x_flat = tf.Variable(tf.reshape(x, [-1]))

# no automatic promotion, so make updates float32 to match x
updates = tf.constant([5, 4, 3], dtype=tf.float32)

sess.run(tf.initialize_all_variables())
sess.run(tf.scatter_update(x_flat, linear_indices,  updates))

# convert back into original shape
x = tf.reshape(x_flat, x.get_shape())

print x.eval()

给予

[[ 0.  0.  0.  0.]
 [ 5.  0.  4.  0.]
 [ 0.  0.  0.  3.]]

最后第三个例子已经支持gather_nd,你写

print tf.gather_nd(x, coords).eval()

得到

[ 5.  4.  3.]

编辑,5 月 6 日

更新x[cols,rows]=newvals 可以在不使用变量(会话运行调用之间占用内存)的情况下完成,通过使用select 和采用稀疏值向量的sparse_to_dense,或依赖dynamic_stitch

sess = tf.InteractiveSession()
x = tf.zeros((3, 4))
row_indices = tf.constant([1, 1, 2])
col_indices = tf.constant([0, 2, 3])

# no automatic promotion, so specify float type
replacement_vals = tf.constant([5, 4, 3], dtype=tf.float32)

# convert to linear indexing in row-major form
linear_indices = row_indices*x.get_shape()[1]+col_indices
x_flat = tf.reshape(x, [-1])

# use dynamic stitch, it merges the array by taking value either
# from array1[index1] or array2[index2], if indices conflict,
# the later one is used 
unchanged_indices = tf.range(tf.size(x_flat))
changed_indices = linear_indices
x_flat = tf.dynamic_stitch([unchanged_indices, changed_indices],
                           [x_flat, replacement_vals])
x = tf.reshape(x_flat, x.get_shape())
print x.eval()

【讨论】:

  • 这些例子很有帮助。谢谢!
  • 同事建议使用dynamic_stitch 代替变量,更新食谱
  • 这仍然是最好的方法吗?
猜你喜欢
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 2018-01-17
  • 2018-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-31
相关资源
最近更新 更多