Python TensorFlow:tf.scatter\u更新的替代方案
我有两个像这样的张量:Python TensorFlow:tf.scatter\u更新的替代方案,python,tensorflow,Python,Tensorflow,我有两个像这样的张量: template = tf.convert_to_tensor([[1, 0, 0.5, 0.5, 0.3, 0.3],
template = tf.convert_to_tensor([[1, 0, 0.5, 0.5, 0.3, 0.3],
[1, 0, 0.75, 0.5, 0.3, 0.3],
[1, 0, 0.5, 0.75, 0.3, 0.3],
[1, 0, 0.75, 0.75, 0.3, 0.3]])
patch = tf.convert_to_tensor([[0, 1, 0.43, 0.17, 0.4, 0.4],
[0, 1, 0.18, 0.22, 0.53, 0.6]])
[[1. 0. 0.5 0.5 0.3 0.3 ]
[0. 1. 0.43 0.17 0.4 0.4 ]
[1. 0. 0.5 0.75 0.3 0.3 ]
[0. 1. 0.18 0.22 0.53 0.6 ]]
现在,我想用补丁行更新模板的第二行和最后一行,以获得如下值:
template = tf.convert_to_tensor([[1, 0, 0.5, 0.5, 0.3, 0.3],
[1, 0, 0.75, 0.5, 0.3, 0.3],
[1, 0, 0.5, 0.75, 0.3, 0.3],
[1, 0, 0.75, 0.75, 0.3, 0.3]])
patch = tf.convert_to_tensor([[0, 1, 0.43, 0.17, 0.4, 0.4],
[0, 1, 0.18, 0.22, 0.53, 0.6]])
[[1. 0. 0.5 0.5 0.3 0.3 ]
[0. 1. 0.43 0.17 0.4 0.4 ]
[1. 0. 0.5 0.75 0.3 0.3 ]
[0. 1. 0.18 0.22 0.53 0.6 ]]
有了tf.scatter\u更新,就很容易:
var_template = tf.Variable(template)
var_template = tf.scatter_update(var_template, [1, 3], patch)
但是,它需要创建一个变量。是否有一种仅使用张量运算获得值的方法
我在考虑tf.where,但是我可能必须将每一个补丁行广播到模板大小中,并为每一行调用tf.where 这个应该有用。有点扭曲,但没有使用变量
import tensorflow as tf
template = tf.convert_to_tensor([[1, 1, 0.5, 0.5, 0.3, 0.3],
[2, 2, 0.75, 0.5, 0.3, 0.3],
[3, 3, 0.5, 0.75, 0.3, 0.3],
[4, 4, 0.75, 0.75, 0.3, 0.3]])
patch = tf.convert_to_tensor([[1, 1, 1, 0.17, 0.4, 0.4],
[3, 3, 3, 0.22, 0.53, 0.6]])
ind = tf.constant([1,3])
rn_t = tf.range(0, template.shape[0])
def index1d(t, val):
return tf.reduce_min(tf.where(tf.equal([t], val)))
def index1dd(t,val):
return tf.argmax(tf.cast(tf.equal(t,val), tf.int64), axis=0)
r = tf.map_fn(lambda x: tf.where(tf.equal(index1d(ind, x), 0), patch[index1dd(ind, x)] , template[x]), rn_t, dtype=tf.float32)
with tf.Session() as sess:
print(sess.run([r]))
我将在这里添加我的解决方案。此实用程序函数的工作原理与scatter_update几乎相同,但不使用变量:
def scatter_update_tensor(x, indices, updates):
'''
Utility function similar to `tf.scatter_update`, but performing on Tensor
'''
x_shape = tf.shape(x)
patch = tf.scatter_nd(indices, updates, x_shape)
mask = tf.greater(tf.scatter_nd(indices, tf.ones_like(updates), x_shape), 0)
return tf.where(mask, patch, x)
创建变量有什么问题?这将是我的第二个问题:这段代码是模型预处理链的一部分。我希望它是无国籍的。我认为变量有不同的用途:存储权重、状态等。我认为mrry的回答很好地描述了这种差异。我不怕在预处理中使用tf.Variable。例如,我使用它在Dataset API的映射部分使用tf.scatter\u nd\u更新来增强图像。请记住使用tf.get_变量,而不是tf.variable本身。我有点担心更新期间变量的锁定。我担心这可能会影响多GPU多机设置的性能。对不起,我没有多GPU或多机设置的经验。