前言
在正文开始之前需要说明,这篇文章以比较简单的视角去理解GCN,不做过多的理论分析,如果需要比较详细的理论分析请链接到:
如何理解 Graph Convolutional Network(GCN)?www.zhihu.com或者参考文章:
https://arxiv.org/abs/1905.10224arxiv.org接下来的主要内容也是参照这篇文章而来的。
原理
首先需要明确的是我们为什么需要GCN,原因很简单,就是个体自身的特征已经无法完全代表个体的所有信息,这有可能是在数据采集过程中丢失错误或者一些个体的伪装,造成了一些特征的偏差。那么我们就需要它邻居节点的信息作为当前节点的信息补充。这样我们就可以得到比单一个体特征,更完整的信息。
那么如何将邻居的特征与当前节点的特征结合在一起,那当然是优秀的图神经网络。已经有足够多的方法来做这个过程,这里我们就选择其中一种比较经典的方法来解释。
这里我们按照文章中给的式子进行解释:
可以看到这是一个二层网络,我们只需要理解了第一层就很容易理解第二层了。也就是理解:
可见做为一个无向无权图来说,它的邻接矩阵
接下来就是
最后就是
我们来看矩阵乘法。首先是
可见经过这个乘法之后,描述节点的特征由它自身的特征加上邻居特征组成。例如:节点1,它的邻居包括节点2,3,和4,那么它的信息就有1,2,3,4的所有信息;再如节点4,因为它的邻居只有节点1,因此它的信息只有它自己加上节点1的信息。
前面说过
还是上面的网络,我们发现现在每个节点多有它邻居的信息,那么如果我们再进行一次卷积会发生什么情况呢,我们这个时候节点4的信息就会传播到节点2,3中,为什么呢?因为第一次卷积节点4将它的信息传播给了节点1,接下来再进行一次卷积的话,节点1就会把它直到的节点4的信息传播给节点2和3。当然同样的道理他也会将节点2,3的信息传播给4。这样的话就可以得到下面的信息图
因此,我们可以直到每一次卷积都会多知道它高一阶邻居的信息。
总结
优点:总的来说GCN形式简单,也便于理解。
缺点:计算量比较大,对新加入的节点没有很好的处理方法。
代码分析
最后我们通过代码来看模型:
class
这里就是两层的图卷积网络,我们来具体看一下GraphConvolution里面的代码:
class GraphConvolution(nn.Module):
def __init__(self, in_feature, out_feature, bias=True):
super(GraphConvolution, self).__init__()
self.in_features = in_feature
self.out_features = out_feature
self.weight = Parameter(torch.FloatTensor(in_feature, out_feature))
if bias:
self.bias = Parameter(torch.FloatTensor(out_feature))
else:
self.register_parameter('bias', None)
self.reset_parameters()
def reset_parameters(self):
stdv = 1. / math.sqrt(self.weight.size(1))
self.weight.data.uniform_(-stdv, stdv)
if self.bias is not None:
self.bias.data.uniform_(-stdv, stdv)
def forward(self, input, adj):
support = torch.mm(input, self.weight)
output = torch.spmm(adj, support)
if self.bias is not None:
return output + self.bias
else:
return output
我们可以看到这里面的forward就是两次的矩阵乘法。先解释一下参数,input是输入的特征大小为:
下面是我们整理的代码,主要参考原作者的形式。
MrLeeeee/GCN-GAT-and-Graphsagegithub.comGAT请参考这篇文章:
Mr-Lee:理解Graph Attention Networkszhuanlan.zhihu.com