Объединить повторяющиеся индексы в разреженном Тензоре
Допустим, у меня есть разреженный тензор с повторяющимися индексами, и там, где они дублируются, я хочу объединить значения (суммировать их)
Как лучше всего это сделать?
Пример:
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)
Но это чувство очень, очень некрасиво
2 ответов:
Вот решение, использующее
tf.segment_sum. Идея состоит в том, чтобы линеаризовать индексы в 1-D пространстве, получить уникальные индексы с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())
Итак. В соответствии с решением, упомянутым выше.
Еще один пример.
Для формы [12, 5]:
Строки, подлежащие изменению в коде:
linearized = tf.matmul(indices, [[5], [1]]) indices = tf.concat([y//5, y%5], axis=1)
Comments