我已经读过tf.scatter_nd documentation并为1D和3D张量运行示例代码...现在我正在尝试为2D张量进行此操作。我想“交织”两个张量的列。对于一维张量,可以通过
'''
We want to interleave elements of 1D tensors arr1 and arr2, where
arr1 = [10, 11, 12]
arr2 = [1, 2, 3, 4, 5, 6]
such that
desired result = [1, 2, 10, 3, 4, 11, 5, 6, 12]
'''
import tensorflow as tf
with tf.Session() as sess:
updates1 = tf.constant([1,2,3,4,5,6])
indices1 = tf.constant([[0], [1], [3], [4], [6], [7]])
shape = tf.constant([9])
scatter1 = tf.scatter_nd(indices1, updates1, shape)
updates2 = tf.constant([10,11,12])
indices2 = tf.constant([[2], [5], [8]])
scatter2 = tf.scatter_nd(indices2, updates2, shape)
result = scatter1 + scatter2
print(sess.run(result))
(除了:有没有一种更好的方法来做到这一点?我都很高兴。)
这给出了输出
[ 1 2 10 3 4 11 5 6 12]
是的!起作用了!
现在让我们尝试将其扩展到2D。
'''
We want to interleave the *columns* (not rows; rows would be easy!) of
arr1 = [[1,2,3,4,5,6],[1,2,3,4,5,6],[1,2,3,4,5,6]]
arr2 = [[10 11 12], [10 11 12], [10 11 12]]
such that
desired result = [[1,2,10,3,4,11,5,6,12],[1,2,10,3,4,11,5,6,12],[1,2,10,3,4,11,5,6,12]]
'''
updates1 = tf.constant([[1,2,3,4,5,6],[1,2,3,4,5,6],[1,2,3,4,5,6]])
indices1 = tf.constant([[0], [1], [3], [4], [6], [7]])
shape = tf.constant([3, 9])
scatter1 = tf.scatter_nd(indices1, updates1, shape)
这给出了错误
ValueError: The outer 1 dimensions of indices.shape=[6,1] must match the outer 1
dimensions of updates.shape=[3,6]: Dimension 0 in both shapes must be equal, but
are 6 and 3. Shapes are [6] and [3]. for 'ScatterNd_2' (op: 'ScatterNd') with
input shapes: [6,1], [3,6], [2].
好像我的indices
是在指定行索引而不是列索引,并给出以numpy和tensorflow(即行优先顺序)“连接”数组的方式,这是否意味着
我需要为updates1
中的每个元素明确地指定每对索引吗?
还是我可以为行使用某种“通配符”规范? (注意indices1 = tf.constant([[:,0], [:,1], [:,3], [:,4], [:,6], [:,7]])
可能会出现语法错误。)
只进行转置,对行进行交织然后再转回会更容易吗? 因为我尝试过...
scatter1 = tf.scatter_nd(indices1, tf.transpose(updates1), tf.transpose(shape))
print(sess.run(tf.transpose(scatter1)))
...并且收到了很多更长的错误消息,除非有人要求,否则我不希望发布。
PS-我进行了搜索,以确保这不是重复的内容-我很难想象别人之前没有问过这个问题-但没有发现任何问题。
答案 0 :(得分:1)
这是纯粹的切片,但我不知道像{b, ...c}:
这样的语法是否有效。似乎可以,但是不确定是否更好。
这可能是您正在寻找的通配符切片机制。
arr1[0:,:][:,:2]
输出为
arr1 = tf.constant([[1,2,3,4,5,6],[1,2,3,4,5,7],[1,2,3,4,5,8]])
arr2 = tf.constant([[10, 11, 12], [10, 11, 12], [10, 11, 12]])
with tf.Session() as sess :
sess.run( tf.global_variables_initializer() )
print(sess.run(tf.concat([arr1[0:,:][:,:2], arr2[0:,:] [:,:1],
arr1[0:,:][:,2:4],arr2[0:, :][:, 1:2],
arr1[0:,:][:,4:6],arr2[0:, :][:, 2:3]],axis=1)))
例如,
[[ 1 2 10 3 4 11 5 6 12]
[ 1 2 10 3 4 11 5 7 12]
[ 1 2 10 3 4 11 5 8 12]]
返回
arr1[0:,:]
和[[1 2 3 4 5 6]
[1 2 3 4 5 7]
[1 2 3 4 5 8]]
返回前两列
arr1[0:,:][:,:2]
轴为1。
答案 1 :(得分:1)
一些主持人可能将我的问题视为this one的重复,不是因为问题相同,而是因为答案包含可以用来回答此问题的部分-即通过指定每个索引组合手。
完全不同的方法是乘以the last answer to this question中所示的置换矩阵。由于我最初的问题是关于scatter_nd的,所以我将发布此解决方案,但请等一下其他答案……(或者,我或某人可以编辑该问题以重新排序不特定于scatter_nd < strong>-编辑:我刚刚编辑了问题标题以体现这一点)。
在这里,我们将两个不同的数组/张量连接起来...
import numpy as np
import tensorflow as tf
sess = tf.Session()
# the ultimate application is for merging variables which should be in groups,
# e.g. in this example, [1,2,10] is a group of 3, and there are 3 groups of 3
n_groups = 3
vars_per_group = 3 # once the single value from arr2 (below) is included
arr1 = 10+tf.range(n_groups, dtype=float)
arr1 = tf.stack((arr1,arr1,arr1),0)
arr2 = 1+tf.range(n_groups * (vars_per_group-1), dtype=float)
arr2 = tf.stack((arr2,arr2,arr2),0)
catted = tf.concat((arr1,arr2),1) # concatenate the two arrays together
print("arr1 = \n",sess.run(arr1))
print("arr2 = \n",sess.run(arr2))
print("catted = \n",sess.run(catted))
哪个提供输出
arr1 =
[[10. 11. 12.]
[10. 11. 12.]
[10. 11. 12.]]
arr2 =
[[1. 2. 3. 4. 5. 6.]
[1. 2. 3. 4. 5. 6.]
[1. 2. 3. 4. 5. 6.]]
catted =
[[10. 11. 12. 1. 2. 3. 4. 5. 6.]
[10. 11. 12. 1. 2. 3. 4. 5. 6.]
[10. 11. 12. 1. 2. 3. 4. 5. 6.]]
现在我们建立置换矩阵并乘以...
start_index = 2 # location of where the interleaving begins
# cml = "column map list" is the list of where each column will get mapped to
cml = [start_index + x*(vars_per_group) for x in range(n_groups)] # first array
for i in range(n_groups): # second array
cml += [x + i*(vars_per_group) for x in range(start_index)] # vars before start_index
cml += [1 + x + i*(vars_per_group) + start_index \
for x in range(vars_per_group-start_index-1)] # vars after start_index
print("\n cml = ",cml,"\n")
# Create a permutation matrix using p
np_perm_mat = np.zeros((len(cml), len(cml)))
for idx, i in enumerate(cml):
np_perm_mat[idx, i] = 1
perm_mat = tf.constant(np_perm_mat,dtype=float)
result = tf.matmul(catted, perm_mat)
print("result = \n",sess.run(result))
哪个提供输出
cml = [2, 5, 8, 0, 1, 3, 4, 6, 7]
result =
[[ 1. 2. 10. 3. 4. 11. 5. 6. 12.]
[ 1. 2. 10. 3. 4. 11. 5. 6. 12.]
[ 1. 2. 10. 3. 4. 11. 5. 6. 12.]]
即使这并不像最初的问题那样使用scatter_nd,但我喜欢的一件事是,您可以通过某种perm_mat
方法分配__init__()
一次,然后继续使用它,在最初的开销之后,它只是矩阵-矩阵乘以一个稀疏,恒定的矩阵,应该很快。 (?)
仍然很高兴等待,看看还有什么其他答案。