这个问题的两个部分:
(1)更新张量流中张量子集的最佳方法是什么?我看过几个相关的问题:
在Tensor中调整单值 - TensorFlow 以及 如何在Tensorflow中更新2D张量的子集?
我知道可以使用Variable.assign()(和/或scatter_update等)来分配Variable对象,但是对于我来说,tensorflow没有更直观的方式来更新Tensor的一部分似乎很奇怪宾语.我已经搜索了tensorflow api文档和stackoverflow很长一段时间了,似乎找不到比上面链接中提供的更简单的解决方案.这看起来特别奇怪,特别是考虑到Theano与Tensor.set_subtensor()具有相同的版本.我错过了什么,或者目前通过tensorflow api没有简单的方法吗?
(2)如果有更简单的方法,它是否可以区分?
谢谢!
我认为张量的不变性是构建计算图所必需的;你不能让一个张量更新它的一些值而不成为另一个张量,否则在它之前的图中将没有任何内容。Autograd 中也出现了同样的问题。
可以使用布尔掩码来做到这一点(但很难看)(使它们成为变量并使用assign,或者甚至在 numpy 中预先定义它们)。这将是可微分的,但实际上我会避免更新子张量。
如果你真的必须这样做,我真的希望有更好的方法来做到这一点,但这里有一种在一维中使用的方法tf.dynamic_stitch如果你真的必须这样做,我真的希望有更好的方法来做到这一点,但这里有一种在一维中使用和tf.setdiff1d:
def set_subtensor1d(a, b, slice_a, slice_b):
# a[slice_a] = b[slice_b]
a_range = tf.range(a.shape[0])
_, a_from = tf.setdiff1d(a_range, a_range[slice_a])
a_to = a_from
b_from, b_to = tf.range(b.shape[0])[slice_b], a_range[slice_a]
return tf.dynamic_stitch([a_to, b_to],
[tf.gather(a, a_from),tf.gather(b, b_from)])
Run Code Online (Sandbox Code Playgroud)
对于更高的维度,这可以通过滥用来推广reshape (其中nd_slice可以像这样实现,但可能有更好的方法):
def set_subtensornd(a, b, slice_tuple_a, slice_tuple_b):
# a[*slice_tuple_a] = b[*slice_tuple_b]
a_range = tf.range(tf.reduce_prod(tf.shape(a)))
a_idxed = tf.reshape(a_range, tf.shape(a))
a_dropped = tf.reshape(nd_slice(a_idxed, slice_tuple_a), [-1])
_, a_from = tf.setdiff1d(a_range, a_dropped)
a_to = a_from
b_range = tf.range(tf.reduce_prod(tf.shape(b)))
b_idxed = tf.reshape(b_range, tf.shape(b))
b_from = tf.reshape(nd_slice(b_idxed, slice_tuple_b), [-1])
b_to = a_dropped
a_flat, b_flat = tf.reshape(a, [-1]), tf.reshape(b, [-1])
stitched = tf.dynamic_stitch([a_to, b_to],
[tf.gather(a_flat, a_from),tf.gather(b_flat, b_from)])
return tf.reshape(stitched, tf.shape(a))
Run Code Online (Sandbox Code Playgroud)
我不知道这会有多慢。我猜会很慢。而且,除了在几个张量上运行它之外,我还没有对它进行太多测试。
| 归档时间: |
|
| 查看次数: |
4114 次 |
| 最近记录: |