Tensor.scatter_add_(dim, index, src) → Tensor
out.scatter_add_(dim, index, src)
1.scatter_add / scatter_sum参数:
注意:scatter_add会直接调用scatter_sum,scatter_sum得到参数index后, 还要进行index = broadcast(index, src, dim)的操作,然后调用scatter_add_函数。
2.scatter_add_官方的解释的操作如下:
3.例子
- 关于scatter_add函数的用法-优快云博客
- 这个是自己写的俩个例子;左右个一个;最后的结果:每一行放的是与该目标节点相连的源节点的特征向量的和,并没有目标节点自身的信息,就是只聚合了邻居的消息放在这儿;
- src表示 源节点 的特征向量的集合;index表示的是 edge_index 第2行,也就是目标节点的索引,然后经过广播得到现在看到的inde;out初始值:是[ |V|,节点特征维度值]大小,初始值均为0的tensor;
- 再看一个PYG中GCNConv用到的例子:
- 将每个target node的邻接节点的边的权重以及自环的权重求和;有自环是因为 index是包含自环的边的索引的第二行,也就是目标节点,src是包含自环的边的权重;
- out.scatter_add_(dim, index, src),dim,=0 ,index, src都是一维的Tensor
-
import torch # 创建一个目标张量 out,初始化为0 out = torch.zeros(5) # 创建一个索引张量 index,指定要在哪些位置累加 src 中的值 index = torch.tensor([1, 3, 4, 1, 2]) # 创建一个源张量 src,包含要累加的值 src = torch.tensor([10, 20, 30, 40, 50]) # 将 src 中的值根据 index 添加到 out 中 out.scatter_add_(dim=0, index=index, src=src) print(out)
在这个示例中,
index
中的每个元素表示了要在out
中的哪个位置累加src
中的值。最终,out
的值将被更新为[0, 50, 50, 20, 30],其中每个位置上的值是根据index
和src
累加得到的。
再看一个特别的例子:
import torch_scatter
import torch
# 初始化一个7x7的零张量
x = torch.zeros((7, 7))
# 将每一行的第一个元素设置为1
x[:, 0] = 1
# 打印张量
print(x)
edge_index = torch.tensor([[0, 2, 3],
[0, 2, 3]])
need_x = x.index_select(dim=0, index=edge_index[0])
nei_X = torch_scatter.scatter(src=need_x, index = edge_index[1], dim=0, reduce="sum")
print("...........")
print(nei_X)
实验结果: