【问题标题】:How to sum based off index vector如何根据索引向量求和
【发布时间】:2019-09-13 02:24:06
【问题描述】:

我有 3 个向量 - 一个和向量、一个贡献向量和一个值向量。我想根据它们的贡献向量对值向量求和,并将它们放在求和向量中的相应索引中。一个例子是:

A = [0;0] (sum vector), B = [0,0,1,1] (contribution vector) C=[20,30,40,10] (value vector)

输出: A = [20+30;40+10]

使得 B 向量与 C 的长度相同,并且它们对应的索引告诉我们要添加到 A 中的哪个位置。

我可以通过这样的 for 循环来实现这一点:

for index,value in enumerate(C):
    A[B[index]]+=value

但是,由于这将是我的 NN 模型前向循环的一部分,因此会导致严重的性能问题。具体来说,我正在寻找一种更有效的向量/矩阵排序方法。在上面的示例中,对我有效的方法是:

A=torch.zeros(2,1)
C=C.reshape(2,2)
sum=torch.sum(C,1).reshape(2,1)
A += sum

但是,我遇到了一些问题,因为 A 的索引并不总是具有相同的贡献。例如 - B = [0,0,0,1,1]C=[20,30,40,10,50] 的情况。对于一般情况,是否有功能或战略方法可以做到这一点?谢谢!

【问题讨论】:

标签: python machine-learning pytorch


【解决方案1】:

执行 for 循环会在一定程度上降低性能。假设贡献向量中唯一类型的数量远小于 B(或 C)的长度,您可以使用以下假设进行 for 循环 O(num_types)


num_types = 3
B_len = 5
C_len = B_len

B = torch.randint(0, num_types, size=[B_len,])
"""
>>> B
tensor([2, 1, 1, 0, 0])
"""

C = torch.randint(0, 10, size=[C_len,])
C = C.float()
"""
>>> C
tensor([1., 5., 7., 6., 2.])
"""

# For loop here
A = [torch.sum(C * (torch.eq(B, type).float()) for type in range(num_types)]
# A = [tensor(8.), tensor(12.), tensor(1.)]

# Convert it to torch.tensor
A = torch.stack(A)
# tensor([ 8., 12.,  1.])

【讨论】:

    【解决方案2】:

    您正在寻找index_add_()

    A.index_add_(0, B, C)
    

    注意B的类型应该是torch.long(它是一个索引向量),C的类型应该是torch.float,和A的类型一样。
    此外,如果AC 是多维张量,您可以使用第一个dim 参数沿不同维度进行求和。

    【讨论】:

    猜你喜欢
    • 2013-11-05
    • 2019-09-01
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    • 2023-03-09
    • 2012-01-15
    相关资源
    最近更新 更多