gcn 图卷积神经网络_图卷积网络之GCN(Graph Convolutional Network)

a18b0620962f930cc99ffca1a4268292.png

前言

在正文开始之前需要说明,这篇文章以比较简单的视角去理解GCN,不做过多的理论分析,如果需要比较详细的理论分析请链接到:

如何理解 Graph Convolutional Network(GCN)?​www.zhihu.com
6dbf33387730c0e8a566679811230114.png

或者参考文章:

https://arxiv.org/abs/1905.10224​arxiv.org

接下来的主要内容也是参照这篇文章而来的。

原理

首先需要明确的是我们为什么需要GCN,原因很简单,就是个体自身的特征已经无法完全代表个体的所有信息,这有可能是在数据采集过程中丢失错误或者一些个体的伪装,造成了一些特征的偏差。那么我们就需要它邻居节点的信息作为当前节点的信息补充。这样我们就可以得到比单一个体特征,更完整的信息。

那么如何将邻居的特征与当前节点的特征结合在一起,那当然是优秀的图神经网络。已经有足够多的方法来做这个过程,这里我们就选择其中一种比较经典的方法来解释。

这里我们按照文章中给的式子进行解释:

35465acf8df7c62835ac53acf7710d36.png

可以看到这是一个二层网络,我们只需要理解了第一层就很容易理解第二层了。也就是理解:

。激活函数我们先放在一边,接下来就是三个矩阵相乘。我们以一个简单的图作为说明:

cdcdc1e2426a5a9039aa556a2eb8b73d.png

可见做为一个无向无权图来说,它的邻接矩阵

为:
,加上自己就得到
;为什么要加上自己呢,因为自己的信息肯定是需要被用上的(邻居的信息很重要,但是自己的信息也是不能被遗忘的)。

接下来就是

,它表示的是每个节点的特征,也是就是带的信息。这里假设它是一个二维的向量。
,这也是好理解的,每个节点都有自己的信息。

最后就是

,它的作用是要是对特征进一步的抽象,因为每个特征之间是可能是有联系的,通过这种全连的神经网络可以很容易的将这些特征的联系结合在一起。

我们来看矩阵乘法。首先是

,我们可以得到:

可见经过这个乘法之后,描述节点的特征由它自身的特征加上邻居特征组成。例如:节点1,它的邻居包括节点2,3,和4,那么它的信息就有1,2,3,4的所有信息;再如节点4,因为它的邻居只有节点1,因此它的信息只有它自己加上节点1的信息。

前面说过

是对特征的进一步抽象,这里是属于深度学习中最简单的神经网络就是一个全连层加上一个激活函数,我们就不展开了。我们来看经过一次如卷积的传播,现在每个节点的情况:

284a39b39e8ba66b91ca1c54b93675f8.png

还是上面的网络,我们发现现在每个节点多有它邻居的信息,那么如果我们再进行一次卷积会发生什么情况呢,我们这个时候节点4的信息就会传播到节点2,3中,为什么呢?因为第一次卷积节点4将它的信息传播给了节点1,接下来再进行一次卷积的话,节点1就会把它直到的节点4的信息传播给节点2和3。当然同样的道理他也会将节点2,3的信息传播给4。这样的话就可以得到下面的信息图

3667aba6886f402cd1652a2291b8fe13.png

因此,我们可以直到每一次卷积都会多知道它高一阶邻居的信息。

总结

优点:总的来说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是输入的特征大小为:

,adj当然就是邻接矩阵,self.weight表示的是前面的W。具体的代码可以参考:
tkipf/pygcn​github.com
a5f6942ece47f189848c71e3f39fc84f.png

下面是我们整理的代码,主要参考原作者的形式。

MrLeeeee/GCN-GAT-and-Graphsage​github.com
4ac466c6a8145b894e1a8b95dea743b6.png

GAT请参考这篇文章:

Mr-Lee:理解Graph Attention Networks​zhuanlan.zhihu.com
cdcd61e1d97b837fc0495c7f9bd1d989.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值