vlambda博客
学习文章列表

图度学习入门教程(十一)——图同构网络模型(GIN)深


本教程是一个系列免费教程,如果喜欢请帮忙转发。


主要是基于图深度学习的入门内容。讲述最基本的基础知识,其中包括深度学习、数学、图神经网络等相关内容。该教程由代码医生工作室出版的全部书籍混编节选而成。偏重完整的知识体系和学习指南。


本教程主要针对的人群:


  • 已经掌握TensorFlow基础应用,并想系统学习的学者。

  • PyTorch学习者

  • 正在从TensorFlow转型到PyTroch的学习者

  • 已经掌握Python,并开始学习人工智能的学者。

 

本篇主要介绍图同构网络(Graph Isomorphism Network GIN)模型,同时也介绍了多重集与单射的概念,以及在DGL中的具体实现。

 

1 了解图同构网络模型(GIN)

图同构网络(Graph Isomorphism Network GIN)模型源于一篇原理性论文《How Powerful are Graph Neural Networks?》(arXiv:1810.00826,2018)。该论文分析了图神经网络中一些主流做法的原理。并在此原理基础之上,推出了一个可以更好的表达图特征的结构——GIN


DGL库中,无论是图卷积模型还是图注意力模型,都是使用递归迭代的方式,对图中的节点特征按照边的结构进行聚合来进行计算的。图同构网络(GIN)模型在此基础之上,对图神经网络提出了一个更高的合理性要求——同构性。即对同构图处理后的图特征应该相同,对非同构图处理后的图特征应该不同。


2 了解多重集与单射

在深入了解图神经网络对图的表征能力之前,需要先介绍两个概念,多重集与单射。


2.1.什么是多重集(MultiSet

多重集(MultiSet)是一个广义的集合概念,它允许有重复的元素。即,从总的集合中划分多个含有不同元素的子集。在图神经网络中表示节点邻居的特征向量集。


2.2.什么是单射(injective

单射是指每一个不同的输入只对应一个不同的输出。如果两个经过单射函数的输出相等,则它们的输入必定相等。


2.3.图神经网络的评判标准

在图神经网络工作时,会对图中的节点特征按照边的结构进行聚合。如果将节点邻居的特征向量集可以看作是一个MultiSet,则整个图神经网络可以理解为是MultiSet的聚合函数。


好的图神经网络应当具有单射函数的特性。即图神经网络必须能够将不同的MultiSet聚合到不同的表示中。


3 GIN模型的原理与实现

图同构网络(GIN)模型是从图神经网络的单射函数特性设计出来的。


3.1GIN模型的原理

GIN模型在图节点邻居特征的每一跳聚合操作之后,又与自身的原始特征混合起来。并在最后使用可以拟合任意规则的全连接网络进行处理,使其具有单射特性。


在特征混合的过程中,引入了一个可学习参数对自身特征进行调节,并将调节后的特征与聚合后的邻居特征进行相加。


3.2GIN模型的实现

DGL库中, GIN模型是通过GINConv类来实现的。该类将GIN模型中的全连接网络换成了参数调用形式,在使用时可以向该参数传入任意神经网络,具有更加灵活的扩展性。


具体代码在DGL安装库路径下的\nn\pytorch\conv\ginconv.py中。例如作者的本机路径为:

D:\ProgramData\Anaconda3\envs\pt15\Lib\site-packages\dgl\nn\pytorch\conv\ginconv.py


GINConv类的具体实现如下:

代码文件:ginconv.py(片段)


 1class GINConv(nn.Module):            #定义GINConv类
2    def __init__(self, apply_func,    #自定义模型参数
3                 aggregator_type,        #聚合类型
4                 init_eps=0,            #可学习变量的初始值
5                 learn_eps=False)
:
        #是否使用可学习变量
6        super(GINConv, self).__init__()
7        self.apply_func = apply_func
8        if aggregator_type == 'sum':
9            self._reducer = fn.sum
10        elif aggregator_type == 'max':
11            self._reducer = fn.max
12        elif aggregator_type == 'mean':
13            self._reducer = fn.mean
14        else:
15            raise KeyError(
16            'Aggregator type {} not recognized.'.format(aggregator_type))
17
18        if learn_eps:                    #是否使用可学习变量
19            self.eps = th.nn.Parameter(th.FloatTensor([init_eps]))
20        else:
21            self.register_buffer('eps', th.FloatTensor([init_eps]))
22
23    def forward(self, graph, feat):        #正向传播
24        graph = graph.local_var()
25        graph.ndata['h'] = feat
26        #聚合邻居节点特征
27        graph.update_all(fn.copy_u('h''m'), self._reducer('m''neigh'))
28        rst = (1 + self.eps) * feat + graph.ndata['neigh']#将自身特征混合
29        if self.apply_func is not None:    #使用神经网络进行单射拟合处理
30            rst = self.apply_func(rst)
31        return rst


代码第28行在聚合邻居节点特征之后,又使用了自身特征进行混合。这种操作是GIN模型有别于其它模型的主要步骤。由于模型中的图节点带有自身特征的加和操作,这使得在聚合邻居节点特征步骤中,聚合函数有更多的选择(可以使用summaxmean)。


提示:

代码第28行的特征混合过程是至关重要的。它为节点特征中默认加入了一个自身的特征信息。如果去掉了特征混合过程,并且在聚合特征中使用了maxmean函数,则无法捕获到图的不同结构。因为在maxmean函数计算时,会损失掉单个节点特征。


推荐阅读













点击“阅读原文”图书配套资源