Python tensorflow-r1.2中“tf.scatter\u nd”的正确用法

Python tensorflow-r1.2中“tf.scatter\u nd”的正确用法,python,tensorflow,deep-learning,python-3.4,tensor,Python,Tensorflow,Deep Learning,Python 3.4,Tensor,给定带形状的索引[批次大小,序列长度],更新带形状的[批次大小,序列长度,采样大小],带形状的带形状的[批次大小,序列长度,声音大小],其中声音大小,采样大小,我想使用tf.scatter将更新映射到一个巨大的张量,用映射到_形,这样映射到_形[bs,index[bs,sz]]=更新[bs,sz]。也就是说,我想逐行将更新映射到到_shape。请注意,sequence\u len和sampled\u size是标量张量,而其他张量是固定的。我试着做到以下几点: new_tensor = tf.s

给定带形状的
索引
[批次大小,序列长度],
更新带形状的
[批次大小,序列长度,采样大小]
带形状的
带形状的
[批次大小,序列长度,声音大小]
,其中
声音大小
采样大小
,我想使用
tf.scatter
更新映射到一个巨大的张量,用
映射到_形
,这样
映射到_形[bs,index[bs,sz]]=更新[bs,sz]
。也就是说,我想逐行将
更新映射到
到_shape
。请注意,
sequence\u len
sampled\u size
是标量张量,而其他张量是固定的。我试着做到以下几点:

new_tensor = tf.scatter_nd(tf.expand_dims(indices, axis=2), updates, to_shape)
但我有一个错误:

您能告诉我如何正确使用
scatter\n和
吗?提前谢谢

因此,假设您有:

  • 张量
    使用形状
    [批次大小、序列长度、采样大小]
    更新
  • 张量
    索引
    ,形状
    [批次大小、序列长度、采样大小]
然后你会:

import tensorflow as tf

# Create updates and indices...

# Create additional indices
i1, i2 = tf.meshgrid(tf.range(batch_size),
                     tf.range(sequence_len), indexing="ij")
i1 = tf.tile(i1[:, :, tf.newaxis], [1, 1, sampled_size])
i2 = tf.tile(i2[:, :, tf.newaxis], [1, 1, sampled_size])
# Create final indices
idx = tf.stack([i1, i2, indices], axis=-1)
# Output shape
to_shape = [batch_size, sequence_len, vocab_size]
# Get scattered tensor
output = tf.scatter_nd(idx, updates, to_shape)

采用
索引
张量,
更新
张量和某些形状
更新
是原始张量,形状正好是所需的输出形状,因此
[批大小、序列大小、声音大小]
。现在,
索引
更加复杂。由于您的输出有3个维度(排名3),因此对于
更新中的每个元素,您需要3个索引来确定每个元素在输出中的位置。因此,
索引
参数的形状应与
更新
相同,且附加尺寸为3。在这种情况下,我们希望第一个维度是相同的,但我们仍然必须指定3个索引。因此,我们使用生成我们需要的索引,并沿第三维平铺它们(在
更新的最后一个维度中,每个元素向量的第一个和第二个索引是相同的)。最后,我们将这些索引与之前创建的映射索引进行叠加,我们得到了完整的三维索引。

我想您可能正在寻找这个

def permute_batched_tensor(batched_x, batched_perm_ids):
    indices = tf.tile(tf.expand_dims(batched_perm_ids, 2), [1,1,batched_x.shape[2]])

    # Create additional indices
    i1, i2 = tf.meshgrid(tf.range(batched_x.shape[0]),
                     tf.range(batched_x.shape[2]), indexing="ij")
    i1 = tf.tile(i1[:, tf.newaxis, :], [1, batched_x.shape[1], 1])
    i2 = tf.tile(i2[:, tf.newaxis, :], [1, batched_x.shape[1], 1])
    # Create final indices
    idx = tf.stack([i1, indices, i2], axis=-1)
    temp = tf.scatter_nd(idx, batched_x, batched_x.shape)
    return temp

您必须展示如何定义
到_形
索引
。此外,命名参数
aixs=2
中存在键入错误,应为
axis=2
。这是原代码中的打字错误吗?@E_net4谢谢你的回复。是的,这是一个打字错误,我把它修好了。您可以认为这三个张量是由占位符创建的。除了序列之外,序列是一个标量,即它是动态的,其他的是固定的。请用这些信息更新您的问题,使其易于理解,并且不会留下歧义。目前还不太清楚序列是否是标量张量。有一些不清楚或错误的地方。如果
索引
[batch\u size,sequence\u len]
to\u shape
[batch\u size,sequence\u len,vocab\u size]
,那么
to\u shape[bs,sl,index[bs,sl]
将是一个元素,但
更新[bs,sl]
是一个大小向量
采样的大小
索引
不应该是
[批次大小、序列长度、采样大小]
?或者是
索引的内容
更新内容的初始位置
还是类似的?您的问题是不正确的<代码>到形状[bs,sl,索引[bs,i]]=更新[bs,sl,i]
但是索引的第二维度一直到序列长度
,而更新的第三维度一直到采样大小
谢谢你的回答。但是我的
标记
是形状
[批次大小,序列长度]
。是打字错误吗?@user5779223哦,从你的评论中我想这是问题中的一个错误。。。然后我仍然不明白映射是如何工作的(如果你对问题做了更改,你能指出它们吗?)。我想要的输出是
到_形[bs,sl,index[bs,I]=updates[bs,sl,I]
因此我将
updates
中的值映射到
到_形
标量scalar@user5779223啊,是的,我现在看到你的编辑了。但是,
i
将采用小于或等于
序列长度的值,该值与
更新的第三维大小不匹配,
采样的大小
。我可以理解
索引
是否有大小
[批次大小,采样大小]
(每个批次都有自己的映射,从
采样大小
声音大小
)或
[批次大小,采样大小]
(每个批次中的每个序列都有自己的映射,从
采样大小
声音大小
).我已经试过上面的代码了。它在编译过程中运行良好。但是当它运行列车步骤时,它在计算坡度方面存在一些问题:
ValueError:index.shape[-1]必须是
def permute_batched_tensor(batched_x, batched_perm_ids):
    indices = tf.tile(tf.expand_dims(batched_perm_ids, 2), [1,1,batched_x.shape[2]])

    # Create additional indices
    i1, i2 = tf.meshgrid(tf.range(batched_x.shape[0]),
                     tf.range(batched_x.shape[2]), indexing="ij")
    i1 = tf.tile(i1[:, tf.newaxis, :], [1, batched_x.shape[1], 1])
    i2 = tf.tile(i2[:, tf.newaxis, :], [1, batched_x.shape[1], 1])
    # Create final indices
    idx = tf.stack([i1, indices, i2], axis=-1)
    temp = tf.scatter_nd(idx, batched_x, batched_x.shape)
    return temp