如何制作一个遮罩以在Tensorflow中选择一些特殊索引?

这是示例代码。我想使用tf.scatter_nd将值分配给新的张量。就像,updated_values = tf.scatter_nd(tf.expand_dims(indices_tf,-1),values_tf,tf.shape(values_tf))。索引张量中有一些重复的索引,这会导致在update_values张量中增加麻烦。我只想给总是与索引张量具有相同形状的信息张量分配一个权重。该代码描述了细节。

import numpy as np
import tensorflow as tf

info =    np.array([0,3,4,5,6,2,1])

indices = np.array([0,1,2])
values = np.array([7,9,10])

delta_tf = tf.convert_to_tensor(info,tf.int32)
indices_tf = tf.convert_to_tensor(indices,tf.int32)
values_tf = tf.convert_to_tensor(values,tf.float32)

updated_values = tf.scatter_nd(tf.expand_dims(indices_tf,-1),values_tf,tf.shape(values_tf))

sess = tf.Session()

updated_values_ = sess.run(updated_values)
print(updated_values_)

# The updated_values_ is [7. 18. 14.  0.  0.  0.  0.].
# I would like tf.scatter_nd to assign only one value to updated_values 
# at repetitive indices not adding them.
# 
# So I want to make a mask from indices according to info,# the rule is that when meeting repetitive index in indices,# the mask will compare the values in info,then reset the maximum value to 1,the others to 0.
#    info: [0,1]
# indices: [0,2]
#    mask: [1,0]
# 
# In this example,the mask will reset the position at 0,6 in info to 1,the others to 0.
# So the mask is [1,0].

mask = np.array([1,0]) # the desired mask
mask_tf = tf.convert_to_tensor(mask,tf.float32)
updated_valuess = tf.scatter_nd(tf.expand_dims(indices_tf,values_tf * mask_tf,tf.shape(values_tf))

updated_valuess_ = sess.run(updated_valuess)
print(updated_valuess_) # This output [7. 2. 4. 0. 0. 0. 0.] is what I want.

如何生成此蒙版?

cb46124994 回答:如何制作一个遮罩以在Tensorflow中选择一些特殊索引?

方法1

这应该有效,

vals = tf.constant([0,3,4,5,6,2,1],dtype=tf.int64)
ind = tf.constant([0,1,2],dtype=tf.int64)

un,_  = tf.unique(ind)
res = tf.reduce_sum(
    tf.map_fn(lambda x: tf.one_hot(tf.argmax(vals * tf.cast(tf.equal(ind,x),tf.int64)),depth=ind.shape[0],dtype=tf.int64),un),axis=0)

修改

方法2

map_fn是一个缓慢的操作。因此,如果使用该选项,则还应该期望速度较慢。除非您设置parallel_iteration参数并以non-eager模式执行,否则它将按顺序运行。因此,以下解决方案将更快。

在这里,我正在使用RaggedTensor并查找属于给定段的每个元素的最大值。但是,要使用RaggedTensors,您必须对段ID进行排序,因此涉及排序和取消排序。

vals = tf.constant([0,dtype=tf.int64)

sort_args = tf.argsort(ind)
sort_vals = tf.gather(vals,sort_args)
sort_inds = tf.gather(ind,sort_args)

ragged = tf.RaggedTensor.from_value_rowids(
    values=sort_vals,value_rowids=sort_inds)
max_vals = tf.reshape(tf.reduce_max(ragged,axis=1),[-1,1])

res = tf.cast(tf.equal(ragged,max_vals).values,tf.int32)
res_unsort = tf.gather(res,sort_args)

结果(在Colab GPU上)

  • 方法1(无并行执行):10个循环,最好为3:每个循环2.4毫秒
  • 方法2:10个循环,每个循环最好3:490 µs

您可以看到方法2更快。

本文链接:https://www.f2er.com/2937104.html

大家都在问