liuxiyang641 / RAGAT

RAGAT: Relation Aware Graph Attention Network for Knowledge Graph Completion
56 stars 16 forks source link

关于spmm模块的疑惑 #15

Closed Infinempty closed 11 months ago

Infinempty commented 11 months ago

阅读代码时我发现在ragat_conv中的spmm模块都设置了dim=1

spmm = SpecialSpmmFinal() edge = torch.tensor([[0,1],[0,2],[0,3],[0,0]]).t() edge_w = torch.tensor([[1,1,1],[2,2,2],[3,3,3],[4,4,4]]) print(edge) x = spmm.forward(edge,edge_w,4,4,3,dim=1) print(x)

但是我在利用如上代码进行测试时,我发现x的输出是 tensor([[10, 10, 10], [ 0, 0, 0], [ 0, 0, 0], [ 0, 0, 0]]) 按我的理解,这个输入数据的意义应该是 0->1,msg:[1,1,1] 0->2,msg:[2,2,2] 0->3,msg:[3,3,3] 0->0,msg:[4,4,4] 最终得到的结果应该是 tensor([[4, 4, 4], [1, 1, 1], [2, 2, 2], [3, 3, 3]]) 和dim=0的测试结果一致,请问这里是不是我理解有误呢

liuxiyang641 commented 11 months ago

你好,非常抱歉。由于这个工作是我之前做的,已经过去比较久了,所以代码的细节我现在一下子也回想不起来。 这个SpecialSpmmFinal()函数只是用来做稀疏矩阵相乘的,原始的代码是来自KBGAT的代码。 不过要做图卷积有很多实现思路,比如可以用DGL这种库,或者是用scatter聚合邻居embedding(代码)。

Infinempty commented 11 months ago

我认为这里改成dim=0更符合逻辑,load_data函数里面读入三元组是(sub,obj)的形式,但是改成dim=0之后反而导致在valid上的MRR下降了0.01左右,训练到1200轮我看不下去就断了,所以我也很疑惑这里到底为什么dim=1和实际边方向相反,但反而能获得更好的效果orz

Infinempty commented 11 months ago

我尝试过用dgl的库复现过RAGAT,如果要用他们的update_all流程的话,个人感觉是不如原代码好使,感觉他们的库更适合小图和稠密图

liuxiyang641 commented 11 months ago

如果你是因为方向感觉到疑惑的话,消息传递的方向和关系的方向并不一定是一致的。 它可以是头实体向尾实体传递消息,也可以是尾实体向头实体传递消息。 由于添加了逆关系,所以这两种传递方向本质上是一样的,每个实体最终都获得了周围所有实体(无论是中心实体的头实体还是尾实体)的embedding。 而在验证集上的变化,0.01的波动我认为并不能说明什么问题。

liuxiyang641 commented 11 months ago

另外,我也推荐可以参考用torch_scatter去聚合邻居信息,用起来也很方便,可以参考这个代码

Infinempty commented 11 months ago

不是早期的0.01波动,是在基本收敛的时候的0.01的差距,相同batch,MRR从0.373降到了0.363左右,我个人认为这种差距算是很大的波动了,而且早期的收敛速度也有一定的差距,在100轮时的MRR差距大概也在0.01左右。关于正负边这个我也有思考过,他们本质上理应是一样的,我只是单纯很好奇是什么样的原因造成了这种差异,还是说就是单纯的玄学。。

Infinempty commented 11 months ago

另外,我也推荐可以参考用torch_scatter去聚合邻居信息,用起来也很方便,可以参考这个代码

好的我试试