李宏毅机器学习第十二周GNN&HW3

摘要

本周主要学习了GNN网络,了解了两类GNN基础类型:继承CNN中的思路的Spatial-based convolution以及以信号处理中卷积操作的定义作为思路的Spectral-based convolution。主要认识了几种基于CNN思路的Spatial-based的GNN模型。之后完成了HW3,主要用了训练增强、focal loss、mixup、tta和残差神经网络。最后阅读了一篇研究GNN文献,该文献主要提出了一种基于限制网络信息流的预处理方法——OOF-GNN,并在不同规模的数据集上取得了稳定且优秀的效果。

Abstract

This week‘s learning mainly focused on GNN networks. Two basic types of GNN is learned. First one is named Spatial-based convolution, which inherits the ideas in CNNs, and second one is named Spectral-based convolution, which takes the definition of convolution operations in signal processing as its idea. Mainly understand several Spatial-based GNN models based on CNN ideas. After that, HW3 is completed, mainly using training augmentation, focal loss, mixup, tta, and residual neural networks. Finally, A research paper on GNN has been read, which mainly proposes a preprocessing method based on limiting network information flow-OOF-GNN, and achieves stable and excellent results on datasets of different scales.

一、GNN

1. Introduction

Graph 是一种由节点以及边(节点间关系)构成的数据结构
在这里插入图片描述

1.1 GNN:why?

GNN可以完成什么任务?

  • 分类任务:修改分子结构后可能导致什么类型的突变

    • 在这里插入图片描述
  • 生成任务:生成针对新冠的靶向药物,同时需要设置一些限制以更好的满足生产

    • 在这里插入图片描述
  • 预测任务:根据输入的人物相关信息确定哪个人是凶手,信息可能包括人物间关系,这时需要GNN来处理

    • 在这里插入图片描述

1.2 GNN: How?

  • GNN如何利用图结构分析节点间关系使得模型的预测更加准确?
  • 当图中节点数量极大时,GNN如何处理?
  • 当不具有所有节点标签时,如何处理?

在这里插入图片描述

上图中褐色为已知标签节点,蓝色为未知标签节点。任务为推断个标签节点。

大致思路为根据相邻节点确定该节点的标签。

在以往学习的神经网络中,通常讲向量或者序列作为处理的数据结构,下面解释,通过一种方法让graph成为可以被神经网络理解的数据结构。

在这里插入图片描述

图可以由如上图中的邻接矩阵表示,而对于邻接矩阵可以进行卷积操作。

但如何使用卷积操作将节点转换为特征图?

  1. 继承CNN中的思路 → \rightarrow →Spatial-based convolution
  2. 以信号处理中卷积操作的定义作为思路 → \rightarrow →Spectral-based convolution

2. Roadmap

课程的大致框架

  1. 本次课程主要精力集中在介绍两类卷积操作的GNN,其中两个经典的网络为
    • Spatial-based convolution → \rightarrow →GAT
    • Spectral-based convolution → \rightarrow →GCN
  2. 简短的理论分析:GIN、GCN
  3. 介绍各种GNN在相应任务上的应用
  4. 最后介绍GNN在自然语言处理方面的应用

在这里插入图片描述

3. Tasks, Dataset, and Benchmark

注:课程中本部分在完成主要内容的介绍之后

在这里插入图片描述

4. Spatial-based GNN

正如上文中介绍的一样,这类GNN沿用了CNN中卷积操作的方式。

以下介绍可能用到的terminology术语

  • aggregate聚合:用相邻特征更新下一层的状态
  • Readout:将所有结点的特征集合起来表示整个图

在这里插入图片描述

4.1 NN4G(Neural Networks for Graph)

  1. 聚合操作

    • 在下图中参数的表示方式的为 h n o d e l a y e r \displaystyle h_{node}^{layer} hnodelayer​,上标表示对应层,下标表示对应节点
    • 第一部分为上一层的相邻节点的参数总和乘以对应参数,第二部分为上一层本节点的值。二者之和即为本层本节点的参数值
    • 例如在hidden layer1的节点 h 3 1 = w ^ 1 , 0 ( h 0 0 + h 2 0 + h 4 0 ) + w ‾ 1 ⋅ x 3 h_3^1=\hat w_{1,0}(h_0^0+h_2^0+h_4^0)+\overline w_1\cdot x_3 h31​=w^1,0​(h00​+h20​+h40​)+w1​⋅x3​
    • 在这里插入图片描述
  2. Readout

    • 各个隐藏层的参数值之和平均值,再乘以对应权重,最后求和,输出为y
    • 在这里插入图片描述

4.2 DCNN(Diffusion-Convolution Neural Network)

在隐藏层中根据节点到本节点的举例,在各层依次计算均值。例如在第一各隐藏层考虑举例本节点为1的节点的参数的均值。

由此可以生成多个节点特征矩阵,再纵向提取一个节点在所有特征矩阵中对应的参数为一个向量,该向量乘以权重矩阵输出为y

在这里插入图片描述

4.3 DGC(Diffusion Graph Convolution)

与DCNN中相同的方式生成特征矩阵,但将各个节点在各特征矩阵中的参数值求和输出

4.4 MoNET(Mixture Model Networks)

  1. 确定一种度量方式
  2. 使用带权重的对邻接特征求和

如下图中, h 3 1 = w ( u ^ 3 , 0 ) × h 0 0 + w ( u ^ 3 , 2 ) × h 2 0 + w ( u ^ 3 , 2 ) × h 4 0 h_3^1=w(\hat u_{3,0})\times h_0^0+w(\hat u_{3,2})\times h_2^0+w(\hat u_{3,2})\times h_4^0 h31​=w(u^3,0​)×h00​+w(u^3,2​)×h20​+w(u^3,2​)×h40​

其中w为神经网络, u ^ \hat u u^是u的转换,u的计算方式如下

KaTeX parse error: Got function '\deg' with no arguments as argument to '\sqrt' at position 28: …=(\frac1{\sqrt \̲d̲e̲g̲(x)},\frac1{\sq…

其中deg表示该节点的度

在这里插入图片描述

4.5 GraphSAGE

该模型可以使用LSTM作为其聚合方法。由于在图结构中各邻接节点实际上不具有序列性质,因此在输入时将其随机打乱以降低结果序列相关性

在这里插入图片描述

4.6 GAT(Graph Attention Network)

该模型引入了注意力机制,计算节点与相邻节点的相关性,同时设置了可学习的权重矩阵。

  • 输入:各个节点的特征矩阵
  • 计算权重矩阵: e i j = a ( W h ⃗ i , W h ⃗ j ) e_{ij}=a(W\vec h_i,W\vec h_j) eij​=a(Wh i​,Wh j​)
  • 引入注意力机制,计算各邻接节点的相关性
    • α i j = exp ⁡ ( LeakyReLU ( a ⃗ T [ W h ⃗ i ∣ ∣ W h ⃗ j ] ) ) ∑ k ∈ N i exp ⁡ ( LeakyReLU ( a ⃗ T [ W h ⃗ i ∣ ∣ W h ⃗ k ] ) ) \displaystyle\alpha_{ij}=\frac{\exp(\text{LeakyReLU}(\vec a^T[W\vec h_i||W\vec h_j]))}{\sum_{k\in \Nu_i}\exp(\text{LeakyReLU}(\vec a^T[W\vec h_i||W\vec h_k]))} αij​=∑k∈Ni​​exp(LeakyReLU(a T[Wh i​∣∣Wh k​]))exp(LeakyReLU(a T[Wh i​∣∣Wh j​]))​

在这里插入图片描述

4.7 GIN(Graph Isomorphism Network)

该模型引入了可学习的聚合函数和更新函数。在红色方框部分使用求和方式而非max或mean的原因是,后两者无法在图结构上生效,即对于相当数量的图操作后结果相同

在这里插入图片描述

下次课程内容

  1. Tasks, Dataset, and Benchmark

  2. Graph Signal Processing and Spectral-based GNN

  3. Graph Generation

  4. GNN for NLP

二、HW3

HW3Image Classification

任务介绍-食物分类

在这里插入图片描述

1. 大致要求

在这里插入图片描述

1.1数据增强

修改图片数据,使得图片辨识度降低,增强模型稳定性降低过拟合的可能性
实现:通过transforms中函数调整图

在这里插入图片描述

1.2进阶的数据增强方法——mixup

将两个输入图片混合,同时修改标签,还需要修改loss函数
在这里插入图片描述
编程中可能需要的内容:
在这里插入图片描述

  • torch.utils.Dataset,__getitem__()需要返回一张由两张照片混合得来的照片
  • torch.utils.Dataset,__getitem__()需要返回一个由向量表示的标签,为每个类分配概率
  • 需要给出交叉熵的数学公式,CrossEntropyLoss并不支持多标签

1.3测试数据增强

训练时使用经过数据增强的图片以及原图片,使用原图片作为测试集合。设置最终预测为训练预测与测试预测的结合

在这里插入图片描述

在这里插入图片描述

1.4交叉验证

在模型训练的不同阶段使用不同的部分作为验证集,当模型的验证集遍历过所有数据时循环完成。
实现:你需要结合训练与验证数据路径,重新编写获取函数以取得新的训练与验证集

在这里插入图片描述

ensemble集合

可能性的均值、投票、编码

在这里插入图片描述

2. 实验代码

2.1 import

仅对在训练中添加的内容进行说明

  • from torchvision.models import densenet201:引用已有模型,在使用过程中不使用已经训练好的参数
  • import ttach as tta:Test Time Augmentation库
    • 如没有,则!pip install ttach
# Import necessary packages.
import numpy as np
import pandas as pd
import torch
import os
import torch.nn as nn
import torchvision.transforms as transforms
from PIL import Image
# "ConcatDataset" and "Subset" are possibly useful when doing semi-supervised learning.
from torch.utils.data import ConcatDataset, DataLoader, Subset, Dataset
from torch.autograd import Variable
import torch.nn.functional as F

from torchvision.datasets import DatasetFolder, VisionDataset
from torchvision.models import densenet201


# This is for the progress bar.
from tqdm.auto import tqdm
import random

import ttach as tta

2.2 训练增强

# Normally, We don't need augmentations in testing and validation.
# All we need here is to resize the PIL image and transform it into Tensor.
test_tfm = transforms.Compose([
    transforms.Resize((128, 128)),
    transforms.ToTensor(),
])

# However, it is also possible to use augmentation in the testing phase.
# You may use train_tfm to produce a variety of images and then test using ensemble methods
train_tfm = transforms.Compose([
    # Resize the image into a fixed shape (height = width = 128)
    transforms.Resize((128, 128)),
    transforms.RandomHorizontalFlip(p=1),   # 随机水平翻转
    transforms.RandomVerticalFlip(p=1),     # 随机上下翻转
    transforms.RandomGrayscale(0.5), # 随机灰度化
    transforms.RandomSolarize(threshold=192.0),
    transforms.ColorJitter(brightness=.5,hue=0.5), # 改变图像的亮度和饱和度
    transforms.RandomRotation(degrees=(0, 180)), # 图像随机旋转
    transforms.RandomInvert(),# 改变图像的颜色
    # You may add some transforms here.
    # ToTensor() should be the last one of the transforms.
    transforms.ToTensor(),
])

2.3 Focal Loss

相较于交叉熵,focal loss侧重控制正负样本的权重,以及控制容易分类和难以分类的样本的权重。
注:正样本需要学习,负样本让网络泛化能力更强的无关样本,难样本即难以辨识的样本
α \alpha α平衡正面/负面例子,当 y = 1 y=1 y=1,有 α t = α \alpha_t=\alpha αt​=α;当 y = 0 y=0 y=0,有 α t = 1 − α \alpha_t=1-\alpha αt​=1−α
FL ( p t ) = − α 1 ( 1 − p t ) γ log ⁡ ( p t ) \text{FL}(p_t)=-\alpha_1(1-p_t)^\gamma\log(p_t) FL(pt​)=−α1​(1−pt​)γlog(pt​)

class FocalLoss(nn.Module):
    def __init__(self, gamma=0, alpha=None, size_average=True):
        super(FocalLoss, self).__init__()
        self.gamma = gamma
        self.alpha = alpha
        if isinstance(alpha,(float,int)): self.alpha = torch.Tensor([alpha,1-alpha])
        if isinstance(alpha,list): self.alpha = torch.Tensor(alpha)
        self.size_average = size_average

    def forward(self, input, target):
        if input.dim()>2:
            input = input.view(input.size(0),input.size(1),-1)  # N,C,H,W => N,C,H*W
            input = input.transpose(1,2)    # N,C,H*W => N,H*W,C
            input = input.contiguous().view(-1,input.size(2))   # N,H*W,C => N*H*W,C
        target = target.view(-1,1)

        logpt = F.log_softmax(input)
        logpt = logpt.gather(1,target)
        logpt = logpt.view(-1)
        pt = Variable(logpt.data.exp())

        if self.alpha is not None:
            if self.alpha.type()!=input.data.type():
                self.alpha = self.alpha.type_as(input.data)
            at = self.alpha.gather(0,target.data.view(-1))
            logpt = logpt * Variable(at)

        loss = -1 * (1-pt)**self.gamma * logpt
        if self.size_average: return loss.mean()
        else: return loss.sum()

2.4 模型构造

使用了densenet201作为分类模型,其作为一种深度卷积神经网络,通过在网络中引入密集连接来增强特征重用和梯度流动,从而提高模型的性能和泛化能力。相较于ResNet,更加侧重特征的重用和信息的共享,在计算效率上略有损失。引用了ttach.ClassificationTTAWrapper进行tta。

# "cuda" only when GPUs are available.
device = "cuda" if torch.cuda.is_available() else "cpu"


# The number of training epochs and patience.
n_epochs = 3
patience = 300 # If no improvement in 'patience' epochs, early stop

# Initialize a model, and put it on the device specified.
model = densenet201(pretrained=False)
in_features = model.classifier.in_features
model.classifier = nn.Linear(in_features,11)
model.to(device)


tta_model = tta.ClassificationTTAWrapper(model,transforms=tta.aliases.d4_transform(),merge_mode='mean')

# For the classification task, we use cross-entropy as the measurement of performance.
criterion = FocalLoss()

# Initialize optimizer, you may fine-tune some hyperparameters such as learning rate on your own.
optimizer = torch.optim.Adam(model.parameters(), lr=0.0003, weight_decay=1e-5) 

2.5 mixup

def mixup_data(x, y, alpha=1.0, use_cuda=True):
    '''Returns mixed inputs, pairs of targets, and lambda'''
    if alpha > 0:
        lam = np.random.beta(alpha, alpha)
    else:
        lam = 1

    batch_size = x.size()[0]
    if use_cuda:
        index = torch.randperm(batch_size).cuda()
    else:
        index = torch.randperm(batch_size)

    mixed_x = lam * x + (1 - lam) * x[index, :]
    y_a, y_b = y, y[index]
    return mixed_x, y_a, y_b, lam


def mixup_criterion(criterion, pred, y_a, y_b, lam):
    return lam * criterion(pred, y_a) + (1 - lam) * criterion(pred, y_b)

2.6 残差网络

残差网络由多个残差块组成,如下图。
公式为 y = H ( x , w h ) + x y=H(x,w_h)+x y=H(x,wh​)+x。简单来说,残差块将经过处理的数据与未经处理的数据相加后输入激活函数最后输出。
在网络的训练过程中,经过处理的拟合函数效果不一定是增强的,训练算法可能找不到勇于期望函数的参数值。针对这种情况,残差块的输出包含未经处理的部分,可以降低训练对于拟合函数的影响。
在这里插入图片描述

class Residual_Network(nn.Module):
    def __init__(self):
        super(Residual_Network, self).__init__()
        
        self.cnn_layer1 = nn.Sequential(
            nn.Conv2d(3, 64, 3, 1, 1),
            nn.BatchNorm2d(64),
        )

        self.cnn_layer2 = nn.Sequential(
            nn.Conv2d(64, 64, 3, 1, 1),
            nn.BatchNorm2d(64),
        )

        self.cnn_layer3 = nn.Sequential(
            nn.Conv2d(64, 128, 3, 2, 1),
            nn.BatchNorm2d(128),
        )

        self.cnn_layer4 = nn.Sequential(
            nn.Conv2d(128, 128, 3, 1, 1),
            nn.BatchNorm2d(128),
        )
        self.cnn_layer5 = nn.Sequential(
            nn.Conv2d(128, 256, 3, 2, 1),
            nn.BatchNorm2d(256),
        )
        self.cnn_layer6 = nn.Sequential(
            nn.Conv2d(256, 256, 3, 1, 1),
            nn.BatchNorm2d(256),
        )
        self.fc_layer = nn.Sequential(
            nn.Linear(256* 32* 32, 256),
            nn.ReLU(),
            nn.Linear(256, 11)
        )
        self.relu = nn.ReLU()

    def forward(self, x):
        # input (x): [batch_size, 3, 128, 128]
        # output: [batch_size, 11]

        # Extract features by convolutional layers.
        # 第一层不做残差连接
        x1 = self.cnn_layer1(x)
        x1 = self.relu(x1)
        # 第二层进行残差连接
        # 残差就是计算出的x1
        Residual = x1 
        x2 = self.cnn_layer2(x1)
        # 在通过激活函数之前进行残差连接
        x2 = x2 + Residual
        x2 = self.relu(x2)
        # 第三层不进行残差连接
        x3 = self.cnn_layer3(x2)
        x3 = self.relu(x3)
        # 残差就是计算出的x3
        # 第四层进行残差连接
        Residual = x3
        x4 = self.cnn_layer4(x3)
        x4 = x4 + Residual
        x4 = self.relu(x4)
        # 第五层不进行残差连接
        x5 = self.cnn_layer5(x4)
        x5 = self.relu(x5)
        # 第六层进行残差连接
        Residual = x5
        x6 = self.cnn_layer6(x5)
        x6 = x6 + Residual
        x6 = self.relu(x6)
        # The extracted feature map must be flatten before going to fully-connected layers.
        xout = x6.flatten(1)
        # The features are transformed by fully-connected layers to obtain the final logits.
        xout = self.fc_layer(xout)
        return xout

3. 训练过程简述

主要完成了数据增强、tta、focal loss部分的代码,并使用已有模型densenet201进行训练。完成了mixup部分的代码,但并未用于训练过程。并未修改参数设置,如epoch等。

修改后训练结果如下

在这里插入图片描述

三、文献阅读

1. 题目

题目:Depth-defying OOF-GNN: Sailing smoothly amidst GNN waves

作者:Aafaq Mohi ud din, Shaima Qureshi

期刊:Knowledge-Based Systems, Volume 280, 25 November 2023, 110991

2. abstract

GNN iteratively transmits neural information along the edges of the input graph, and GNN integrates node feature information with graph structure. However, not all neighbor node information is necessary for downstream tasks, so this paper proposes a flexible method based on restricting unnecessary information in the delivery process - OOF-GNN. The efficacy of the model has been demonstrated in various aspects, such as under-reaching, over-smoothing, and over-squashing, as well as improving the performance of the GNN model in node classification tasks.

GNN通过沿着输入图的边缘迭代传递神经信息,GNN 将节点特征信息与图结构集成在一起。但并非所有邻接节点信息对于下游任务是必要的,因此本文提出了一种基于限制传递过程中不必要信息的方法——OOF-GNN。该模型在各个方面的功效已经得到了证明,例如under-reaching, over-smoothing, and over-squashing,以及提高GNN模型在节点分类任务中的性能。

3. 网络架构

OOF-GNN可以理解为一种基于GNN模型的数据预处理方法,额外边以及权重生成算法详见4.2.2部分。其大致流程如下

OOF-GNN方法说明
上图流程可以用下图表示
在这里插入图片描述

4. 文献解读

4.1 Introduction

GNN 模型无选择的从节点的相邻节点聚合数据,这导致了一定数量的无效信息流被传递。该论文证明了不同类别的信息流在网络中的作用是不同的,例如类间信息流、类内信息流。在预测过程中,引入了概率标签传播方法来确定未知节点的标签,并证实了利用该方法生成的伪标签可以增强模型有效性。最终基于上述研究,该论文提出了OFF-GNN的方法,并证明了该模型的有效性。
下图展示了该论文如何分类信息流与节点
在这里插入图片描述

4.2 创新点

4.2.1 概念解释

本部分主要介绍OOF-GNN模型的设计目的
部分概念的解释

  • 由于基本思路是使用重复的消息传递来从更广泛的周围范围中吸收更多的邻域信息,若不能满足则会出现under-reaching
  • 浅层设计可能会阻碍从高层邻接节点中提取信息。另一方面,过于深度的网络结构可能会导致过度平滑over-smoothing,从而导致不同类的节点表示无法区分
  • 在每个节点的感受野中包含多次转接的邻接节点可能会导致过度挤压over-squashing,这使得图难以有效地从较远的节点传输消息。
over-smoothing

过平滑是一种现象,在这种现象中,随着图卷积层数的增加,GNN中节点的表示变得无法区分,最终导致精度下降。
下图中的实验结果显示了过平滑现象
在这里插入图片描述由具有邻接矩阵A、特征矩阵X和权重矩阵W的通用GNN架构表示的单个消息传递层如下: H = A ~ T X W T H = \tilde A^TXW^T H=A~TXWT
传递的标准过程通常是计算节点的特性及其相邻节点的特性的加权和,然后输入非线性激活函数。
H i ( k ) = σ ( ∑ j ∈ N ( i ) X j ( k − 1 ) W ( k − 1 ) ) H_i^{(k)}=\sigma (\sum j\in N(i)X_j^{(k-1)}W^{(k-1)}) Hi(k)​=σ(∑j∈N(i)Xj(k−1)​W(k−1))
其中 σ \sigma σ为激活函数, N ( i ) N(i) N(i)为邻接节点集合, W ( k − 1 ) W^{(k-1)} W(k−1)是一个可学习的权重矩阵
在此例子中,消息传递规则如下: H i ( k ) = σ ( 1 k ∑ j ∈ N ( i ) X j ( k − 1 ) W ( k − 1 ) ) H_i^{(k)}=\sigma(\frac1k\sum j\in N(i)X_j^{(k-1)}W^{(k-1)}) Hi(k)​=σ(k1​∑j∈N(i)Xj(k−1)​W(k−1))
当应用上述规则进行K次迭代后
H i ( K ) = σ ( 1 k k ∑ j 1 ∈ N ( i ) ∑ j 2 ∈ N ( j 1 ) ⋯ ∑ j K ∈ N ( j K − 1 ) X j K ( 0 ) W ( 0 ) W ( 1 ) … W ( K − 1 ) ) H_i^{(K)}=\sigma (\frac1{k^k}\sum_{j_1\in N(i)}\sum_{j_2\in N(j_1)}\dots \sum_{j_K\in N(j_{K-1})}X_{j_K}^{(0)}W^{(0)}W^{(1)}\dots W^{(K-1)}) Hi(K)​=σ(kk1​∑j1​∈N(i)​∑j2​∈N(j1​)​⋯∑jK​∈N(jK−1​)​XjK​(0)​W(0)W(1)…W(K−1))
其中 X j K ( 0 ) X_{j_K}^{(0)} XjK​(0)​是节点 j K j_K jK​的初始特征向量
随着层数K的增加,节点表示逐渐更多地依赖于图的局部结构,这可能导致关于全局结构的信息丢失。

over-squashing

随着GNN深度的增加,它从目标节点周围的L-hop的邻域中获取信息,导致信息溢出。高维扩展的数据被压缩成一个固定大小的向量,限制了模型的表达能力,这也是深度GNN无法达到100%acc的原因。
对于给定的 G = ( V , E ) G=(V,E) G=(V,E),给定节点V的感受野中的节点集取决于GNN的深度,并定义了节点周围的L-hop邻域。设节点v的感受野中的节点集由 N v L N_v^L NvL​表示,其递归定义为:
N v 0 N_v^0 Nv0​是节点v的特征向量 x v x_v xv​
N v 1 = N v 0 ⋀ N_v^1=N_v^0\bigwedge Nv1​=Nv0​⋀v的1-hop邻域
N v L = N v L − 1 ⋀ N_v^L=N_v^{L-1}\bigwedge NvL​=NvL−1​⋀v的L-hop邻域
随着层数的增加,每个节点的感受野内的节点数量呈指数级上涨。但越来越多数据被压缩成固定长的向量时,训练精度急剧下降,这可能导致模型的泛化能力下降

OFF-GNN是一种满足以下四个主要目标的方法

  • 在整个图上传播信息的能力(避免过度平滑)
  • 避免过度挤压效应,减小或避免瓶颈效应
  • 时间复杂度和空间复杂度应低于二次方水平
  • 对基础模型适用
4.2.2 OOF-GNN

本方法的核心是

赋予inter-class edges和intra-class edges不同的权重,同时增强链接没有共享标签邻域的节点的边。

这产生了一个受控的信息传递环境,其中只有相关信息在相似节点之间传递,且减少了不必要信息的影响。

Label generation procedure

标签传播是一种技术,其使用迭代方法,通过概率关系分类器在数据集上传播标签来为这些未标记节点分配标签,公式如下:
P ( Y v = c ) = 1 ∑ ( v , u ) ∈ E A v , u ∑ ( v , u ) ∈ E A v , u P ( Y v = c ) P(Y_v=c)=\frac1{\sum_{(v,u)\in E}A_{v,u}}\sum_{(v,u)\in E}A_{v,u}P(Y_v=c) P(Yv​=c)=∑(v,u)∈E​Av,u​1​∑(v,u)∈E​Av,u​P(Yv​=c)
其中c是与节点v相关联的标签, A ~ \tilde A A~是邻接矩阵
该方法增强了模型在半监督学习方面的能力,扩展了标签数据集,并使得模型在未知标签上的稳定性得到了强化。

inter-class & intra-class weight assignment

首先,类间权重分配,权重因子 β \beta β的分配定义为
e β = { e i j ∣ A [ i , j ] ≠ 0 ⋀ ( L ~ i ≠ L ~ j ) } e_\beta=\{e_{ij}|A[i,j]\neq0\bigwedge(\tilde L_i\neq\tilde L_j)\} eβ​={eij​∣A[i,j]=0⋀(L~i​=L~j​)}
其次,类内权重分配,该方法期望减小类内边的影响,权重因子 α \alpha α的分配定义如下:
e α = { e i j ∣ A [ i , j ] ≠ 0 ⋀ ( L ~ i = = L ~ j ) } e_\alpha=\{e_{ij}|A[i,j]\neq0\bigwedge(\tilde L_i==\tilde L_j)\} eα​={eij​∣A[i,j]=0⋀(L~i​==L~j​)}

Edge augmentations

通过在共享相同标签的节点之间引入虚拟边来增强孤立节点的信息量,边的扩充可以定义为:
e ~ α = { e i j ∣ A [ i , j ] = 0 ⋀ ( L ~ i = = L ~ j ) ⋀ d e g ( i ) ≤ ϕ } \tilde e_\alpha=\{e_{ij}|A[i,j]=0\bigwedge(\tilde L_i==\tilde L_j)\bigwedge deg(i)\leq\phi\} e~α​={eij​∣A[i,j]=0⋀(L~i​==L~j​)⋀deg(i)≤ϕ}
————————
基于上述三个概念,有算法1,解释如下
算法1解释

4.3 实验过程

实验基于以下四个问题进行

  • 所提出的OOF-GNN方法能否有效地缓解过度平滑现象,并解决图神经网络中覆盖不足的问题?
  • 当应用于节点分类任务的不同数据集时,OOF-GNN方法能否在性能上优于标准GNN?
  • 所提出的OOF-GNN能否有效地减轻深度GNN中过度挤压的影响,并有助于缓解信息传播过程中的瓶颈?
  • OOF-SAGE的综合分析:权重因子α和β的变化如何影响图神经网络中OOF-SAGE技术的信息聚合过程和性能?
4.3.1 数据集

使用三个著名的引文网络数据集评估所考虑的模型的性能,即Cora、Citeseer和PubMed,这三个数据集是用于评估基于图的机器学习模型的基准引用网络数据集。评估采用了WebKB Cornell、WebKB Texas和WebKB Wisconsin数据集。这些数据集为评估所提出方法的性能和功能多样性提供了不同的背景。此外,使用OGBN Arxiv数据集评估模型的有效性。

4.3.2 Baseline models

常用的各向同性GNN包括vanilla GCN(图卷积网络)和GraphSage。
各向异性GNN包括GAT(图注意力网络)。
该评估中还使用了广泛认可的正则化技术,如DropEdge和EGAI,它们起到信息减少器的作用。此外,还包括一种被称为JKNET的连接跳过技术。

4.3.3 参数设置

对于OFF-GNN框架,建立了与OFF-SAGE的比较标准(OFF-GNN应用于GraphSAGE)。参数初始化是随机进行的。我们方法的超参数设置范围如下:
α ∈ { 0 , 0.3 , 0.5 , 0.7 , 1 } \alpha\in\{0,0.3,0.5,0.7,1\} α∈{0,0.3,0.5,0.7,1}
β ∈ { 0 , 0.3 , 0.5 , 0.7 , 1 } \beta\in\{0,0.3,0.5,0.7,1\} β∈{0,0.3,0.5,0.7,1}
ϕ \phi ϕ设置为大于或等于平均节点度
深度 L ∈ { 1 , 2 , 4 , 8 , 16 , 32 } L\in\{1,2,4,8,16,32\} L∈{1,2,4,8,16,32}
实验在配备64GB GPU内存架构的Quadro P4000上执行,采用预定义的优化器和学习率。
这些配置在各种方法中保持一致,PyTorch和PyTorch Geometric框架作为主干。

4.4 结论

4.4.1 RQ1

研究了OOF-SAGE在不同数量的GNN层上的性能,并考虑了在Cora数据集上不同 α \alpha α和 β \beta β的影响。在 α = 0.5 , β = 0.3 \alpha=0.5, \beta=0.3 α=0.5,β=0.3上取得了实验中的最佳数据,并用于后续实验。
OOF-SAGE模型在不同深度层下的性能
上图显示,将GNN中的层数或者hop数调高到某个点可能不会有益于精度的提升。此外,还显示了超参数调整对于性能的影响, α , β \alpha, \beta α,β对于性能的影响尤其突出

下图考虑了不同模型和数据集在不同层数下的表现效果,结果表明,虽然Graph SAGE模型在两层时有最好的效果,但效果随着层数的增加而减弱。而OOF-GNN在16层和32层也保持较好的效果。

在这里插入图片描述
在所有数据集中OOF-SAGE表现出超过最先进水平的性能,如下图
Cora数据集上各种GNN架构的准确度分数
一行中模型相同,一列中模型层数相同,颜色强度表示不同数据集上的性能。
在大多数GNN框架中,精度随着深度增加而下降,但在OOF-GNN中,其通过更深层次的架构展示了稳定性,甚至准确性相较其他模型有一定提升。
显然,OOF-GNN通过限制信息流传递,缓解了过度平滑问题,即面向RQ1缓解了GNN的困境

4.4.2 RQ2

下表中表明在多个不同规模的数据集上,OOF-SAGE的表现都显著优于原基础模型。且该数据建立在十次重复实验基础上,确保了结果的稳定性
在这里插入图片描述

4.4.3 RQ3

该问题强调的过度挤压现象主要出现在较大规模的数据集中,因此选用了pubmed, OGBN-Arxiv, OGBN-Products作为展示的数据集。OOF-SAGE表现优于原模型。但仍无法解决随着hop数增大效果逐渐降低的问题,这个可能是未来研究的方向。
在这里插入图片描述

4.4.4 RQ4

从设计目的上来讲, α , β \alpha, \beta α,β的目的是为了使得网络能够选择性的合并类内和类间信息,这种灵活性使得模型能够根据特定的任务和数据集特征调整其信息流。
该研究中,提供了两个参数对于网络影响的描述,并将这种影响显示在下图中
在这里插入图片描述

  • α , β = 0 \alpha, \beta=0 α,β=0的OOF-SAGE的行为突出了邻域感知信息聚合和正则化在增强模型预测能力方面发挥的关键作用。
  • 当在OOF-SAGE中将超参数 α , β \alpha, \beta α,β设置为1时,该方法等效于GraphSAGE模型。
  • α = 0 , β = 1 \alpha=0,\beta=1 α=0,β=1,很容易受到过度挤压。类内信息的缺乏限制了模型捕捉单个类内细粒度关系的能力,可能会影响其判别能力。同时,类间信息的不受控制的聚合可能导致过度挤压,降低节点表示的显著性。
  • α = 1 , β = 0 \alpha=1,\beta=0 α=1,β=0,提高了性能,但也使模型更容易受到过度平滑的影响
总结

当应用于更深层次的架构时,OOF-SAGE实现了最先进的性能,同时有效地解决了过平滑和过类化的问题。

小结

本周主要学习了GNN网络,了解了两类GNN基础类型:继承CNN中的思路的Spatial-based convolution以及以信号处理中卷积操作的定义作为思路的Spectral-based convolution。主要认识了几种基于CNN思路的Spatial-based的GNN模型。之后完成了HW3,主要用了训练增强、focal loss、mixup、tta和残差神经网络。最后阅读了一篇研究GNN文献,该文献主要提出了一种基于限制网络信息流的预处理方法——OOF-GNN,并在不同规模的数据集上取得了稳定且优秀的效果。后续学习将继续了解另一种GNN的基础类型,并尝试使用pytorch实现GNN。

参考文献

[1] Mohi ud din, A. and Qureshi, S. :(2023)‘Depth-defying oof-gnn: Sailing smoothly amidst GNN Waves’, [J]Knowledge-Based Systems, 280, p. 110991. doi:10.1016/j.knosys.2023.110991.

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐