Graph-GraphSage

MPNN很好地归纳了空域卷积的过程,但定义在这个框架下的全部模型都有一个共同的缺陷:html

1. 卷积操做针对的对象是整张图,也就意味着要将全部结点放入内存/显存中,才能进行卷积操做。但对实际场景中的大规模图而言,整个图上的卷积操做并不现实。GraphSage[2]提出的动机之一就是解决这个问题。从该方法的名字咱们也能看出,区别于传统的全图卷积,GraphSage利用采样(Sample)部分结点的方式进行学习。固然,即便不须要整张图同时卷积,GraphSage仍然须要聚合邻居结点的信息,即论文中定义的aggregate的操做。这种操做相似于MPNN中的消息传递过程。node

2. 以前的方法是固有的直推式获得node embeddeding,不能泛化,没法有效适应动态图中新增节点的特性, 每每须要从头训练或至少局部重训练。算法

3 缺少权值共享(Deepwalk, LINE, node2vec)。节点的embedding直接是一个N*d的矩阵, 互相之间没有共享学习参数。网络

4.输入维度固定为|V|。不管是基于skip-gram的浅层模型仍是基于autoencoder的深层模型,输入的维度都是点集的大小。训练过程依赖点集信息的固定网络结构限制了模型泛化到动态图的能力,没法为新加入节点生成embedding。app


GraphSage 的模型框架

 

文中不是对每一个顶点都训练一个单独的embeddding向量,而是训练了一组aggregator functions,这些函数学习如何从一个顶点的局部邻居聚合特征信息(见图1)。每一个聚合函数从一个顶点的不一样的hops或者说不一样的搜索深度聚合信息。测试或是推断的时候,使用训练好的系统,经过学习到的聚合函数来对彻底未见过的顶点生成embedding。函数

 一种邻居特征汇集的方法:性能

1.邻居采样(sample neighborhood)。由于每一个节点的度是不一致的,为了计算高效, 为每一个节点采样固定数量的邻居。学习

2.邻居特征汇集(aggregate feature information from neighbors)。经过汇集采样到的邻居特征,更新当前节点的特征。网络第k层汇集到的 邻居即为BFS过程第k层的邻居测试

3. 训练。既能够用得到的embedding预测节点的上下文信息(context),也能够利用embedding作有监督训练。

采样方法:

  1. 在图中随机采样若干个结点,结点数为传统任务中的batch_size。对于每一个结点,随机选择固定数目的邻居结点(receptive field)(这里邻居不必定是一阶邻居,也能够是二阶邻居)构成进行卷积操做的图。
  2. 将邻居结点的信息经过aggregate函数聚合起来更新刚才采样的结点。
  3. 计算采样结点处的损失。若是是无监督任务,咱们但愿图上邻居结点的编码类似;若是是监督任务,便可根据具体结点的任务标签计算损失

 arrregate函数的选择等:

1.在实践中,每一个节点的receptive field设置为固定大小,且使用了均匀采样方法简化邻居选择过程。

2.做者设计了四种不一样的汇集策略,分别是Mean、GCN、LSTM、MaxPooling。

就aggretor是GCN, 图卷积汇集W(PX),W为参数矩阵,P为邻接矩阵的对称归一化矩阵,X为节点特征矩阵。

 

GraphSage的状态更新公式以下(下式的aggregator 是GCN, 也能够是maxpooling arregator mean aggregator):

 

\mathbf{h}_{v}^{l+1}=\sigma(\mathbf{W}^{l+1}\cdot aggregate(\mathbf{h}_v^l,\{\mathbf{h}_u^l\}),{\forall}u{\in}ne[v])

 

 

 

 

 

 算法:

第四行表示节点vvv的任意相邻节点的聚合信息的集合;

$h_{N(v)}^{k}$表示从节点$v$的相邻节点获取的信息。

AGGGEGATE表示聚合函数;

第5行,将从相邻节点获取的信息和和这个节点自身的信息,进行拼接;

能够发现,对一个新加入的节点a,只须要知道其自身特征和相邻节点,就能够获得其向量表示。没必要从新训练获得其余全部节点的向量表示。固然也能够选择从新训练。可是须要保存全部节点深度为k的表示,

这个算法直观的想法是,每次迭代,或者说每一个深度,节点从相邻节点得到信息。随着迭代次数的增多,节点增量地从图中的更远处得到更多的信息。

graphSAGE并非使用所有的相邻节点,而是作了固定尺寸的采样

既然新增的节点,必定会改变原有节点的表示,那么为何必定要获得每一个节点的一个固定的表示呢?何不直接学习一种节点的表示方法。去学习一个节点的信息是怎么经过其邻居节点的特征聚合而来的。 学习到了这样的“聚合函数”,而咱们自己就已知各个节点的特征和邻居关系,咱们就能够很方便地获得一个新节点的表示了

GraphSAGE的核心:GraphSAGE不是试图学习一个图上全部node的embedding,而是学习一个为每一个node产生embedding的映射

训练相关:

1.为了将算法1扩展到minibatch环境上,给定一组输入顶点,先采样采出须要的邻居集合(直到深度K),而后运行内部循环(算法1的第三行)。
2.出于对计算效率的考虑,对每一个顶点采样必定数量的邻居顶点做为待聚合信息的顶点。设须要的邻居数量,即采样数量为S,若顶点邻居数少于S,则采用有放回的抽样方法,直到采样出SSS个顶点。若顶点邻居数大于SSS,则采用无放回的抽样。(即采用有放回的重采样/负采样方法达到S)

3.文中在较大的数据集上实验。所以,统一采样一个固定大小的邻域集,以保持每一个batch的计算占用空间是固定的(即 graphSAGE并非使用所有的相邻节点,而是作了固定size的采样)。

 

 

 

4.这里须要注意的是,每一层的node的表示都是由上一层生成的,跟本层的其余节点无关,这也是一种基于层的采样方式。
5.在图中的“1层”,节点v聚合了“0层”的两个邻居的信息,v的邻居u也是聚合了“0层”的两个邻居的信息。到了“2层”,能够看到节点v经过“1层”的节点u,扩展到了“0层”的二阶邻居节点。所以,在聚合时,聚合K次,就能够扩展到K阶邻居。

6.邻居的定义:那就是如何选择一个节点的邻居以及多远的邻居。这里做者的作法是设置一个定值,每次选择邻居的时候就是从周围的直接邻居(一阶邻居)中均匀地采样固定个数个邻居。

那我就有一个疑问了?每次都只是从其一阶邻居聚合信息,为什么做者说:随着迭代,能够聚合愈来愈远距离的信息呢?
后来我想了想,发现确实是这样的。虽然在聚合时仅仅聚合了一个节点邻居的信息,但该节点的邻居,也聚合了其邻居的信息,这样,在下一次聚合时,该节点就会接收到其邻居的邻居的信息,也就是聚合到了二阶邻居的信息了。仍是拿出个人看家本领——用图说话:

在GraphSAGE的实践中,做者发现,K没必要取很大的值,当K=2时,效果就灰常好了,也就是只用扩展到2阶邻居便可。至于邻居的个数,文中提到S1×S2<=500,即两次扩展的邻居数之际小于500,大约每次只须要扩展20来个邻居便可。
这也是合情合理,例如在现实生活中,对你影响最大就是亲朋好友,这些属于一阶邻居,而后可能你偶尔从他们口中据说一些他们的同事、朋友的一些故事,这些会对你产生必定的影响,这些人就属于二阶邻居。可是到了三阶,可能基本对你不会产生什么影响了,例如你听你同窗说他同窗据说她同窗的什么事迹,是否是很绕口,绕口就对了,由于你基本不会听到这样的故事,你所接触到的、听到的、看到的,基本都在“二阶”的范围以内。
7.没有这种采样,单个batch的内存和预期运行时是不可预测的,在最坏的状况下是O(∣V∣)O(|\mathcal{V}|)O(∣V∣)。
8.实验发现,K没必要取很大的值,当K=2时,效果就很好了。至于邻居的个数,文中提到S1⋅S2≤500,即两次扩展的邻居数之际小于500,大约每次只须要扩展20来个邻居时得到较高的性能。
论文里说固定长度的随机游走其实就是随机选择了固定数量的邻居.

聚合函数选取

在图中顶点的邻居是无序的,因此但愿构造出的聚合函数是对称的(即也就是对它输入的各类排列,函数的输出结果不变),同时具备较高的表达能力。 聚合函数的对称性(symmetry property)确保了神经网络模型能够被训练且能够应用于任意顺序的顶点邻居特征集合上。

Mean aggregator

mean aggregator将目标顶点和邻居顶点的第k−1层向量拼接起来,而后对向量的每一个维度进行求均值的操做,将获得的结果作一次非线性变换产生目标顶点的第k层表示向量。
文中用下面的式子替换算法1中的4行和5行获得GCN的inductive变形:

1. 均值聚合近似等价在transducttive GCN框架[Semi-supervised classification with graph convolutional networks. In ICLR, 2016]中的卷积传播规则

 

 

 

2.文中称这个修改后的基于均值的聚合器是convolutional的,这个卷积聚合器和文中的其余聚合器的重要不一样在于它没有算法1中第5行的CONCAT操做——卷积聚合器没有将顶点前一层的表示

和聚合的邻居向量.
3.
拼接操做能够看做一个是GraphSAGE算法在不一样的搜索深度或层之间的简单的skip connection[Identity mappings in deep residual networks]的形式,它使得模型得到了巨大的提高

4.举个简单例子,好比一个节点的3个邻居的embedding分别为[1,2,3,4],[2,3,4,5],[3,4,5,6]按照每一维分别求均值就获得了聚合后的邻居embedding为[2,3,4,5]

Mean aggregator

Pooling聚合器,它既是对称的,又是可训练的。Pooling aggregator 先对目标顶点的邻居顶点的embedding向量进行一次非线性变换,以后进行一次pooling操做(max pooling or mean pooling),将获得结果与目标顶点的表示向量拼接,最后再通过一次非线性变换获得目标顶点的第k层表示向量.

1.max表示element-wise最大值操做,取每一个特征的最大值
2.$\sigma$是非线性激活函数
3.全部相邻节点的向量共享权重,先通过一个非线性全链接层,而后作max-pooling
4.按维度应用 max/mean pooling,能够捕获邻居集上在某一个维度的突出的/综合的表现。

参数学习

基于图的损失函数倾向于使得相邻的顶点有类似的表示,但这会使相互远离的顶点的表示差别变大:

 

 

1.$Z_{u}$为节点$u$经过GraphSAGE生成的embedding

 

2.节点v是节点u随机游走到达的邻居

 

3.$\sigma$是sigmoid

 

4.Q是负样本的数目

 

5.embedding 之间的类似度经过向量点积计算

文中输入到损失函数的表示$z_{u}$是从包含一个顶点局部邻居的特征生成出来的,

而不像以前的那些方法(如DeepWalk),对每一个顶点训练一个独一无二的embedding,

而后简单进行一个embedding查找操做获得.

基于图的有监督损失---------------可以使用交叉熵或者范数计算

经过前向传播获得节点u的embedding $z_{u}$,而后梯度降低(实现使用Adam优化器) 进行反向传播优化参数

$W^{k}$和聚合函数内的参数。

新节点embedding的生成

这个$W^{k}$就是dynamic embedding的核心,由于保存下来了从节点原始的高维特征生成低维embedding的方式。如今,若是想获得一个点的embedding,只须要输入节点的特征向量,通过卷积(利用已经训练好的$W^{k}$以及特定聚合函数聚合neighbor的属性信息),就产生了节点的embedding。

GraphSAGE的核心:GraphSAGE不是试图学习一个图上全部node的embedding,而是学习一个为每一个node产生embedding的映射

 

为何GCN是transductive,为啥要把全部节点放在一块儿训练?
不必定要把全部节点放在一块儿训练,一个个节点放进去训练也是能够的。无非是若是想获得全部节点的embedding,那么GCN能够把整个graph丢进去,直接获得embedding,还能够直接进行节点分类、边的预测等任务。

其实,经过GraphSAGE获得的节点的embedding,在增长了新的节点以后,旧的节点也须要更新,这个是没法避免的,由于,新增长点意味着环境变了,那以前的节点的表示天然也应该有所调整。只不过,对于老节点,可能新增一个节点对其影响微乎其微,因此能够暂且使用原来的embedding,但若是新增了不少,极大地改变的原有的graph结构,那么就只能所有更新一次了。从这个角度去想的话,彷佛GraphSAGE也不是什么“神仙”方法,只不过生成新节点embedding的过程,实施起来相比于GCN更加灵活方便了。在学习到了各类的聚合函数以后,其实就不用去计算全部节点的embedding,而是须要去考察哪些节点,就现场去计算,这种方法的迁移能力也很强,在一个graph上学得了节点的聚合方法,到另外一个新的相似的graph上就能够直接使用了.

核心思想:

去学习一个节点的信息是怎么经过其邻居节点的特征聚合而来的。学习到了这样的“聚合函数”,而咱们自己就已知各个节点的特征和邻居关系,咱们就能够很方便地获得一个新节点的表示了。GCN等transductive的方法,学到的是每一个节点的一个惟一肯定的embedding;而GraphSAGE方法学到的node embedding,是根据node的邻居关系的变化而变化的,也就是说,即便是旧的node,若是创建了一些新的link,那么其对应的embedding也会变化,并且也很方便地学到。

本站公众号
   欢迎关注本站公众号,获取更多信息