《Graph Representation Learning》【6】——Graph Neural Networks in Practice

6 Graph Neural Networks in Practice

这一部分,主要会介绍在实践过程中,如何优化GNN模型。比如,我们该选择什么样的损失函数、如何进行正则化、是否要进行预训练等等。

6.1 Applications and Loss Functions

GNN的学习任务一般可以分为3类:
(1)节点分类(node classification)
(2)图分类(graph classification)
(3)关联预测(relation classification)

针对这几类不同的任务,我们可以因地制宜地在 z u , z G ∈ R d z_u,z_G\in R^{d} zu,zGRd上,定义出不同的损失函数,并且可以通过预训练(pre-training)方法来提高模型的表达能力。

6.1.1 GNNs for Node Classification

节点分类是GNN中最流行的基准测试任务之一。这类方法主要基于Cora、Citeseer和Pubmed等引文网络数据集,根据论文在引文网络中的位置,使用基于语言的节点特征(词向量)对论文的类别或主题进行分类,并且每个类别只给出很少数量的带标记(labeled)示例。
针对这种节点分类任务,标准做法是使用完全监督(fully-supervised)的方式来进行训练。
L = ∑ u ∈ V t r a i n − log ⁡ ( s o f t m a x ( z u , y u ) ) s o f t m a x ( z u , z G ) = ∑ i = 1 c y u [ i ] ⋅ e z u T w i ∑ j = 1 c e z u T w j \mathcal L=\sum_{u\in V_{train}}-\log(softmax(z_u,y_u)) \\[2ex] softmax(z_u,z_G)=\sum_{i=1}^{c}y_u[i]\cdot \frac{e^{z_u^Tw_i}}{\sum_{j=1}^{c}e^{z_u^Tw_j}} \\ L=uVtrainlog(softmax(zu,yu))softmax(zu,zG)=i=1cyu[i]j=1cezuTwjezuTwi
其中 y u ∈ Z c y_u\in Z^{c} yuZc是一个「0,1」二值化的独热(one-hot)向量,可以根据节点的label生成,指示了节点u到底在c个类别中属于哪一类。 w i ∈ R d w_i\in R^{d} wiRd是可训练的参数,是为了和 z u T z_u^T zuT一起生成一个标量。这样,softmax函数就很好理解了,代表了节点u属于 y u y_u yu所指示的类别的概率。

Supervised, semi-supervised, transductive, and inductive
节点分类任务到底是监督还是半监督方式,需要根据在训练中不同的节点类型来判别。
节点类型总共分为3类:
(1)训练集节点 V t r a i n V_{train} Vtrain,有标记,训练时可见。需要进行消息传递+计算损失。
(2)传递测试节点 V t r a n s V_{trans} Vtrans,无标记,训练时可见。只需要进行消息传递,不需要计算损失。
(3)归纳测试节点 V i n d V_{ind} Vind,无标记,训练时不可见。既不消息传递,也不计算损失。
使用 V t r a n s V_{trans} Vtrans进行测试的方法属于半监督方法。

6.1.2 GNNs for Graph Classification

图分类任务可以借鉴节点分类任务,使用相似的softmax分类损失;也可以将其视为回归任务,使用均方误差损失。
L = ∑ G i ∈ T ∣ ∣ M L P ( z G i ) − y G i ∣ ∣ 2 2 \mathcal L=\sum_{G_i\in \Tau}||MLP(z_{G_i})-y_{G_i}||_2^2\\ L=GiTMLP(zGi)yGi22
其中 T \Tau T是一个图的标签集合,表示了图 G i G_i Gi属于哪一个类别 y G i ∈ R y_{G_i}\in R yGiR。MLP是一个稠密连接的NN,它的输出是一个标量。

6.1.3 GNNs for Relation Prediction

可以直接使用之前几章中提到的,知识图谱的链接预测模型的损失函数。

6.1.4 Pre-training GNNs

预训练是深度学习的一个技巧。
在GNN模型中,事实证明,随机初始化GNN已经可以取得和使用邻域重构损失进行预训练基本相同的表现。因此,我们需要寻找除了邻域重构损失之外的其他预训练方法。
一个比较成功的模型是DGI,它通过最大化 z u z_u zu z G z_G zG之间的信息,来进行无监督预训练。
L = − ∑ u ∈ V t r a i n E G log ⁡ ( D ( z u , z G ) ) + γ E G ~ log ⁡ ( 1 − D ( z ~ u , z G ) ) \mathcal L=-\sum_{u\in V_{train}}\mathbb E_{G}\log(D(z_u,z_G))+\gamma \mathbb E_{\tilde G}\log(1-D(\tilde z_u,z_{G}))\\ L=uVtrainEGlog(D(zu,zG))+γEG~log(1D(z~u,zG))
其中比较关键的是(人为)损坏后的图 G ~ \tilde G G~,用它训练出来的节点嵌入表示为 z ~ u \tilde z_u z~u。判别器D是用来区分节点嵌入到底是用哪个图训练出来的( G G G G ~ \tilde G G~)。
这一类的无监督预训练方法,核心思想基本都是最大化不同级别的嵌入表示之间的信息、区分真实和损坏的嵌入表示。有时候,它也和NLP当中的“content masking”预训练方法比较相似。

6.2 Efficiency Concerns and Node Sampling

在实践中,如果我们直接按照之前介绍的节点级GNN公式来进行计算,会产生以下的问题:如果节点之间有共同的邻居,会导致冗余计算(???)。

6.2.1 Graph-level Implementations

一种方法是使用GNN的图级实现,使用基于稀疏矩阵乘法来进行消息传递操作。
H ( k + 1 ) = σ ( A H ( k ) W n e i g h ( k + 1 ) + H ( k ) W w e i g h ( k + 1 ) ) H^{(k+1)}=\sigma(AH^{(k)}W_{neigh}^{(k+1)}+H^{(k)}W_{weigh}^{(k+1)}) H(k+1)=σ(AH(k)Wneigh(k+1)+H(k)Wweigh(k+1))
这样做的好处是,每个节点每层的嵌入表示 h u ( k ) h_u^{(k)} hu(k)只会计算一次。缺点也显而易见:整张图一块进行计算可能会引发内存不足,整批(full-batch)梯度下降可能会影响到模型的表现。

6.2.2 Subsampling and Mini-Batching

为了解决图级GNN实现的内存占用问题,我们可以使用mini-batch的方法,每个batch在节点的子集上运行节点级的GNN实现。
当然,每次的节点子集不能随意乱取,需要遵循一定的方法,否则会对模型的效果产生不利影响。首先,选取一个节点的子集,之后每次都对子集中节点的邻居做固定样本大小的采样,得到下一轮batch所用到的节点子集。

6.3 Parameter Sharing and Regularization

正则化是机器学习模型的一个重要组成部分,有一些专门用于GNN的正则化方法。

Parameter Sharing Across Layers
如果GNN的模型有很多层,那么层与层之间的参数共享就很有必要了。核心思想是,在GNN所有的聚合和更新函数中共享参数。

Edge Dropout
在训练过程中,丢弃邻接矩阵中的某些边,可以让模型不容易过拟合。如果之前在训练中采用mini-batch的子采样方法,那么这种正则化方法就会在不知不觉中运用到训练当中,因为每次采样我们都会移除掉邻接矩阵中的一些边。

猜你喜欢

转载自blog.csdn.net/weixin_41650348/article/details/110519977