我想在TensorFlow 2.x中为我的一个模型中的输入Tensor切片分配一些值(我使用的是2.2,但准备接受2.1的解决方案)。我尝试做的非工作模板是:
import tensorflow as tf
from tensorflow.keras.models import Model
class AddToEven(Model):
def call(self, inputs):
outputs = inputs
outputs[:, ::2] += inputs[:, ::2]
return outputs
当然,在构建这个(AddToEven().build(tf.TensorShape([None, None]))
)时,我得到了以下错误:
TypeError: 'Tensor' object does not support item assignment
我可以通过以下方式实现这个简单的示例:
class AddToEvenScatter(Model):
def call(self, inputs):
batch_size = tf.shape(inputs)[0]
n = tf.shape(inputs)[-1]
update_indices = tf.range(0, n, delta=2)[:, None]
scatter_nd_perm = [1, 0]
inputs_reshaped = tf.transpose(inputs, scatter_nd_perm)
outputs = tf.tensor_scatter_nd_add(
inputs_reshaped,
indices=update_indices,
updates=inputs_reshaped[::2],
)
outputs = tf.transpose(outputs, scatter_nd_perm)
return outputs
(you可以对以下项进行健全性检查:
model = AddToEvenScatter()
model.build(tf.TensorShape([None, None]))
model(tf.ones([1, 10]))
)
但正如你所看到的,写起来非常复杂,而且这只是针对1D(+批量大小)Tensor上的静态更新次数(这里是1)。
我想做的是更投入一点,我认为用tensor_scatter_nd_add
写它将是一场噩梦。
很多关于这个主题的问答都涉及到了变量而不是Tensor的情况(例如this或this)。这里提到pytorch确实支持这个,所以我很惊讶最近没有看到任何tf成员对这个主题的回应。这个答案对我没有什么帮助,因为我需要某种掩码生成,这也会很糟糕。
问题是这样的:在没有tensor_scatter_nd_add
的情况下,我如何高效地进行切片分配(计算方面、内存方面和代码方面)?关键在于我希望它尽可能地动态,这意味着inputs
的形状可以是可变的。
(For如果有人好奇我正在尝试将这段代码翻译成tf)。
此问题最初发布在GitHub问题中。
2条答案
按热度按时间ccgok5k51#
这里是基于二进制掩码的另一种解决方案。
这里是精神检查。
结果(用TF 2.1)是这样的。
--------以下是上一个答案--------
你需要在build()方法中创建tf.Variable。它还允许动态大小通过shape=(None,)。在下面的代码中,我指定了输入shape为(None,None)。
我用TF2.1.0和TF1.15测试了这段代码
结果:
P.S.还有一些其他的方法,比如使用tf.numpy_function(),或者生成掩码函数。
piah890a2#
它似乎没有产生这样的错误: