6-GNN Model

图机器学习(GNN Model )

1. 前言

1.回顾

首先是传统机器学习难以应用在图结构上。回忆一下节点嵌入任务,具体可以参考第三章。其目的在于将节点映射到d维向量,使得在图中相似的节点在向量域中也相似。我们已经学习了 Shallow” Encoding 的方法来进行映射过程,也就是使用一个大矩阵直接储存每个节点的表示向量,通过矩阵与向量乘法来实现嵌入过程。

目前这样的浅层映射主要会出现以下几个问题:

  1. 需要 o ( ∣ V ∣ ) o(|V|) o(V)复杂度(矩阵的元素数,即表示向量维度d×节点数|V| )的参数,太多节点间参数不共享,每个节点的表示向量都是完全独特的。
  2. transductive【1】:无法获取在训练时没出现过的节点的表示向量
  3. 无法应用节点自身特征信息

【1】归纳式(Inductive)vs 直推式(Transduction)

主要区别是直推式学习时,在训练模型时已经同学用到了训练和测试数据,而归纳式学习训练时只使用了训练数据,在测试时从未见过测试数据。

直推式学习不会建立一个预测模型,如果一个新数据节点加入测试数据集,那么我们需要重新训练模型,然后再预测标签。然而,归纳式学习会建立一个预测模型,遇到新数据节点不需要重新运行算法训练。

简而言之,归纳式学习企图基于已观测训练数据,建立一个通用模型,用来预测任何新数据节点。你可以预测任何数据节点,不局限在无标记数据上。相比之下,直推式学习是基于所有已经观测到的训练和测试数据来建立模型的,这种方法是通过已经有标记的节点信息来预测无标记数据节点。

直推式学习在遇到新的输入数据时会变得比较费事,每当新数据来了,你需要重新运行。然而,归纳式学习一开始就建立了预测模型,因而在新数据来的时候可以用非常少的代价就打上标记。

2. DNN

看下直接用邻居矩阵拼接节点特征,然后直接丢DNN里面是什么情况如

请添加图片描述

缺点:
1.参数量大,和节点数量+特征维度成正比
2.DNN结构训练好后如果图结构变化,邻接矩阵大小也会变化,此时无法适配原DNN
3.DNN对输入顺序是敏感的,而图是无序的,相同图不同的顺序图的邻接矩阵不一样,DNN无法处理无序的结构
因此,借用CNN的思想,将邻居节点信息汇聚到当前节点,但是在CNN中,卷积核大小是固定的,而图的邻居无法用固定大小的卷积核来处理,因此用的是聚合(aggregation) 思想。

3. deep graph encoders

deep graph encoders也就是用图神经网络GNN来进行节点嵌入。映射函数,即之前在第三章出现的node embedding中的encoder: ENC(v)=基于图结构的多层非线性转换

4. 一个GNN网络的结构如图

请添加图片描述

5. 通过网络可以解决的任务有
  1. 节点分类:预测节点的标签
  2. 链接预测:预测两点是否相连
  3. 社区发现:识别密集链接的节点簇
  4. 网络相似性:度量图/子图间的相似性

2. Describe aggregation strategies

1. 核心思想是生成的节点向量是基于其周边邻居

请添加图片描述

2. 分解后每个节点都有自己的计算图

请添加图片描述

3. 当然可以有深度的形式:节点在每一层都有不同embedding
  • 第0层的embedding就是节点的输入节点的特征信息
  • 第k层的embedding可以汇聚第k跳的邻居信息
4. 聚合的基本方式:

请添加图片描述

上面的聚合(Aggregation)是用的平均的方式(我感觉是求和后归一化,因为分母可以放到求和号前面),其中 B l , W l B_l,W_l Bl,Wl是用于线性变换的参数,也是模型需要训练的参数。虽然每层参数不一样,但是每层的参数是交互的。同时上面的公式也可以写成矩阵的形式:
1. 让 H ( l ) = [ h 1 [ l ] … … h ∣ V ∣ ( l ) ] T , 节点 e m b e d d i n g 的矩阵形式 2. 邻居消息聚合: ∑ u ∈ N v h u ( l ) = A v H ( l ) 邻接矩阵里面 v 节点这行 3. D 是度矩阵,是一个对角矩阵: D v , v = D e g ( v ) = ∣ N ( v ) ∣ 4. 则归一化可以表示为: D − 1 = 1 ∣ N ( v ) ∣ ( 其实也很好理解,毕竟在邻接矩阵中一行中所有的值加起来才是度,度矩阵这样就天然的满足做归一化的分母 ) 5. 因此上图中邻居节点的汇聚的矩阵形式可以写成 : ∑ u ∈ N v h u ( l ) N ( v ) → H ( l + 1 ) = D − 1 A H l 6. 因此整个式子可以写成 : H l + 1 = σ ( A ~ H ( l ) W l T + H ( l ) B l T ) , 其中 A ~ = D − 1 A 1.让H^{(l)}=[h_1^{[l]}……h_{|V|}^{(l)}]^T,节点embedding的矩阵形式\\ 2.邻居消息聚合:\sum_{u\in N_v}h_u^{(l)}=A_vH^{(l)}邻接矩阵里面v节点这行\\ 3.D是度矩阵,是一个对角矩阵:D_{v,v}=Deg(v)=|N(v)|\\ 4.则归一化可以表示为:D^{-1}=\frac{1}{|N_{(v)}|}\\ (其实也很好理解,毕竟在邻接矩阵中一行中所有的值加起来才是度,度矩阵这样就天然的满足做归一化的分母)\\ 5.因此上图中邻居节点的汇聚的矩阵形式可以写成: \sum_{u\in N_v}\frac{h_u^{(l)}}{N(v)}\rightarrow H^{(l+1)}=D^{-1}AH^{l}\\ 6.因此整个式子可以写成:H^{l+1}=\sigma(\textcolor{red}{\widetilde{A}H^{(l)}W_l^T}+\textcolor{blue}{H^{(l)}B_l^T}),其中\widetilde{A}=D^{-1}A 1.H(l)=[h1[l]……hV(l)]T,节点embedding的矩阵形式2.邻居消息聚合:uNvhu(l)=AvH(l)邻接矩阵里面v节点这行3.D是度矩阵,是一个对角矩阵:Dv,v=Deg(v)=N(v)4.则归一化可以表示为:D1=N(v)1(其实也很好理解,毕竟在邻接矩阵中一行中所有的值加起来才是度,度矩阵这样就天然的满足做归一化的分母)5.因此上图中邻居节点的汇聚的矩阵形式可以写成:uNvN(v)hu(l)H(l+1)=D1AHl6.因此整个式子可以写成:Hl+1=σ(A H(l)WlT+H(l)BlT),其中A =D1A
请添加图片描述

​ 红色:邻居聚合

​ 蓝色:自身转换

#有向图的时候换成D^-1A,无向图则是D^0.5AD^0.5
def normalize_adj(mx):
    """Row-normalize sparse matrix"""
    rowsum = np.array(mx.sum(1))  #  矩阵行求和
    r_inv = np.power(rowsum, -1).flatten()  # 求和的-1次方
    r_inv[np.isinf(r_inv)] = 0.   # 如果是inf,转换成0
    r_mat_inv = sp.diags(r_inv)  # 构造对角戏矩阵
    mx = r_mat_inv.dot(mx)    # 构造D-1*A,非对称方式,简化方式
    return mx

def normalize_features(mx):
    """Row-normalize sparse matrix"""
    rowsum = np.array(mx.sum(1))
    r_inv = np.power(rowsum, -1).flatten()
    r_inv[np.isinf(r_inv)] = 0.
    r_mat_inv = sp.diags(r_inv)
    mx = r_mat_inv.dot(mx)
    return mx

3. GNN Model 设计

1. 如何训练GNN

节点嵌入 z u z_u zu

  1. 有监督学习:直接进行训练,优化目标 m i n θ L ( Y , f ( z v ) ) min_\theta L(Y,f(z_v)) minθL(Y,f(zv))

​ 1. 如回归问题可以用L2 loss,分类问题可以用交叉熵

​ 2. 比如二分类交叉熵: L = − ∑ v ∈ V ( y v l o g ( σ ( z v T θ ) ) + ( 1 − y v ) l o g ( 1 − σ ( z v T θ ) ) ) L=-\sum_{v\in V}(y_vlog(\sigma(z_v^T\theta))+(1-y_v)log(1-\sigma(z_v^T\theta))) L=vV(yvlog(σ(zvTθ))+(1yv)log(1σ(zvTθ)))
1. y v 就是节点分类的标签 2. z v T 就是编码器的输入,节点的嵌入向量 3. θ 就是分类中的权重,也就是训练的参数 1.y_v就是节点分类的标签\\ 2.z_v^T就是编码器的输入,节点的嵌入向量\\ 3.\theta 就是分类中的权重,也就是训练的参数 1.yv就是节点分类的标签2.zvT就是编码器的输入,节点的嵌入向量3.θ就是分类中的权重,也就是训练的参数

  1. 无监督学习:用图结构作为学习目标

​ 1. 比如节点相似性(随机游走、矩阵分解、图中节点相似性……等)

​ 2. L = ∑ z u , z v C E ( y u , v , D E C ( z u , z v ) ) L=\sum_{z_u,z_v}CE(y_{u,v},DEC(z_u,z_v)) L=zu,zvCE(yu,v,DEC(zu,zv))

​ 1. 如果u和v相似,则 y u , v = 1 y_{u,v}=1 yu,v=1

​ 2. CE是交叉熵

​ 3. DEC是节点嵌入的decoder(如内积)

2. 模型设计
1. 单层GNN

GNN Layer = Message + Aggregation

请添加图片描述


请添加图片描述

注意事项:

通常是用 h v l − 1 来计算 h v l h_v^{l-1}来计算h_v^{l} hvl1来计算hvl,生成消息要生成节点本身的消息,而且本身的消息和邻居的消息使用不同的参数,例如:

请添加图片描述

邻居的消息计算完毕后进行aggregation,然后再把邻居汇聚的结果(黄色虚线框)和节点本身的消息(红色虚线框)进行concat或者sum,例如:

请添加图片描述

几种经典的模型(GCN,GrahphSAGE,GAT),都有着自己独特的消息传递和聚合的方式

2. 多层GNN
  1. 连接GNN网络层部分

请添加图片描述

  1. 连接GNN网络层的标准方式:按序堆叠。输入原始节点特征,输出L层后计算得到的节点嵌入向量

请添加图片描述


4. GNN模型设计中出现的问题

1. 多层GNN中出现over-smoothing 过渡平滑的问题

当GNN层数过深,所有的节点的embedding都趋向一致。(如果我们想用节点嵌入做节点分类任务,这就凉了)这里要提到Receptive field概念,类似CNN中的感受野,例如:

请添加图片描述

由于节点的embedding基本是由Receptive field覆盖的节点决定的,Receptive field越大,重合的节点越多,两个节点的embedding就越相似,这个现象就是over-smoothing。

总之:堆叠很多GNN网络层→节点具有高度重合的感受野→节点嵌入高度相似→过平滑问题

2. 解决过渡平滑的方案
  1. 不要用太深的GNN,而是加强每层GNN的表达能力,例如将aggregation中简单的线性变换,换成DNN。
  2. 加入不传递消息的GNN层,也就是非GNN层,如对每个节点应用MLP(在GNN层之前或之后均可,分别叫 pre-process layers 和 post-process layers)
    pre-processing layers:如果节点特征必须经过编码就很重要(如节点表示图像/文字时)
    post-processing layers:如果在节点嵌入的基础上需要进行推理和转换就很重要(如图分类、知识图谱等任务中)

请添加图片描述


5.如何让模型变得更深

1.增加skip connections【2】

如果实际任务还是需要很多层GNN网络,那么可以在GNN模型中增加skip connections(残差连接的方式)通过对过平滑问题进行观察,我们可以发现,靠前的GNN层可能能更好地区分节点。(就很明显嘛这事)因此我们可以在最终节点嵌入中增加靠前GNN层的影响力,实现方法是在GNN中直接添加捷径,保存上一层节点的嵌入向量其作用类似变相制造了多个路径,相当于做了多个模型的混合,就好比你找一个人来做评估,得到结果比较单一,找一帮人来评估,得到的结果就比较具有鲁棒性。

请添加图片描述

【2】相当于制造了多个模型(如图所示),N个skip connections就相当于创造了 2 N 2^N 2N 条路径,每一条路径最多有N个模块。这些路径都会对最终的节点嵌入产生影响,相当于自动获得了一个浅GNN和深GNN的融合模型。

请添加图片描述

2.skip connections示例
  1. 标准的GCN层是橘色的部分F(x),带有skip connections的GCN层则是添加了蓝色的部分X

请添加图片描述

  1. skip connections也可以跨多层,直接跨到最后一层,在最后一层聚合之前各层的嵌入(通过concat / pooling / LSTM)

请添加图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值