合并稀疏张量中的重复索引

时间:2016-07-06 21:10:38

标签: tensorflow

假设我有一个带有重复索引的稀疏张量,并且它们是重复的,我想合并值(总结它们) 这样做的最佳方式是什么?

示例:

indicies = [[1, 1], [1, 2], [1, 2], [1, 3]]
values = [1, 2, 3, 4]

object = tf.SparseTensor(indicies, values, shape=[10, 10])

result = tf.MAGIC(object)

结果应该是具有以下值的备用张量(或具体!):

indicies = [[1, 1], [1, 2], [1, 3]]
values = [1, 5, 4]

我唯一能做的就是将标记连接在一起以创建索引哈希,将其应用于第三维,然后减少第三维上的总和。

indicies = [[1, 1, 11], [1, 2, 12], [1, 2, 12], [1, 3, 13]]
sparse_result = tf.sparse_reduce_sum(sparseTensor, reduction_axes=2, keep_dims=true)

但这感觉非常难看

4 个答案:

答案 0 :(得分:4)

以下是使用tf.segment_sum的解决方案。我们的想法是将索引线性化为一维空间,使用tf.unique获取唯一索引,运行tf.segment_sum,并将索引转换回N-D空间。

indices = tf.constant([[1, 1], [1, 2], [1, 2], [1, 3]])
values = tf.constant([1, 2, 3, 4])

# Linearize the indices. If the dimensions of original array are
# [N_{k}, N_{k-1}, ... N_0], then simply matrix multiply the indices
# by [..., N_1 * N_0, N_0, 1]^T. For example, if the sparse tensor
# has dimensions [10, 6, 4, 5], then multiply by [120, 20, 5, 1]^T
# In your case, the dimensions are [10, 10], so multiply by [10, 1]^T

linearized = tf.matmul(indices, [[10], [1]])

# Get the unique indices, and their positions in the array
y, idx = tf.unique(tf.squeeze(linearized))

# Use the positions of the unique values as the segment ids to
# get the unique values
values = tf.segment_sum(values, idx)

# Go back to N-D indices
y = tf.expand_dims(y, 1)
indices = tf.concat([y//10, y%10], axis=1)

tf.InteractiveSession()
print(indices.eval())
print(values.eval())

答案 1 :(得分:1)

也许您可以尝试:

indicies = [[1, 1], [1, 2], [1, 2], [1, 3]]
values = [1, 2, 3, 4]

object = tf.SparseTensor(indicies, values, shape=[10, 10])
tf.sparse.to_dense(object, validate_indices=False)

答案 2 :(得分:0)

所以。按照上述解决方案。

另一个例子。

对于形状[12,5]:

要在代码中更改的行:

getString(R.string.number_of_results, NumberFormat.getInstance().format(1000));

答案 3 :(得分:0)

使用unsorted_segment_sum可能更简单:

def deduplicate(tensor):
    if not isinstance(tensor, tf.IndexedSlices):
        return tensor
    unique_indices, new_index_positions = tf.unique(tensor.indices)
    summed_values = tf.unsorted_segment_sum(tensor.values, new_index_positions, tf.shape(unique_indices)[0])
    return tf.IndexedSlices(indices=unique_indices, values=summed_values, dense_shape=tensor.dense_shape)