> 技术文档 > 图神经网络入门:从GNN开始01图卷积网络GCN节点分类 02图注意力网络GAT 03图自编码器GAE 04 门控图神经网络GGNN

图神经网络入门:从GNN开始01图卷积网络GCN节点分类 02图注意力网络GAT 03图自编码器GAE 04 门控图神经网络GGNN

           目录

一.基础1-[图论、图算法、CNN]

二.基础2-[图卷积神经网络GCN]

三.torch-geometric.nn工具包安装(包含各种算法和数据集)

四.GCN任务[节点分类-Cora 数据集]

五.图注意力网络(GAT)

六.图自编码器(GAE)

七.图循环神经网络 (GRNN)

八.门控图神经网络(GGNN)

九. 应用场景


        图神经网络(GNN)的概念由 Franco Scarselli Bruna 等人于 2009 年首次提出。在他们名为“图神经网络模型”的论文中,提出了现有神经网络的扩展,用于处理以图结构表示的数据,这些数据往往是非欧几里得结构数据,即节点间连接关系是任意的,无法用固定网格表示(如社交网络中的朋友关系)。

        李沐老师有一篇【2021GNN】论文解读:  A Gentle Introduction to Graph Neural Networks

        本文参考的B站课程链接:【图神经网络GNN/GCN教程】

        GNN中输入也是特征,输出也是特征,邻接矩阵不变。多层GNN,可以使感受野越来越大,直至获取全局特征。

        GNN 模型可以处理非循环图、循环图、有向图和无向图。应用主要有:

  • [节点分类]:通过考虑邻居的标签来预测节点的标签。
  • [链接预测]:预测图中各个实体之间的关系。 例如,社交网络的预测连接。
  • [图聚类]:将图的节点划分为簇。 基于边权重或边距离或通过将图视为对象并将相似对象分组在一起来完成划分。
  • [图分类]:将图分类为类别。 这可以应用于社交网络分析和自然语言处理中的文档分类。 NLP 中的其他应用包括文本分类、提取文本之间的语义关系和序列标记。
  • [计算机视觉]:在计算机视觉领域,GNN 可用于生成目标检测的感兴趣区域。 它们还可以用于图像分类,从而生成场景图。 然后场景生成模型识别图像中的对象以及它们之间的语义关系。 该领域的其他应用包括交互检测和区域分类。

        GNN 的核心思想是通过迭代地聚合每个节点邻居的信息来更新节点的表示。这种聚合操作可以概括为以下步骤:

  • 消息传递(Message Passing):每个节点从其邻居接收信息。
  • 特征更新:使用某种函数(通常是神经网络)来更新节点特征。
  • 迭代更新:多次迭代上述步骤,直到节点特征达到稳定状态。

        节点特征更新公式:

        研究方向可能包括:

  • 提高图神经网络的计算效率,以便处理更大规模的图数据。
  • 提高图神经网络的泛化能力,以便在更多的应用场景中取得更好的性能。
  • 研究如何处理非静态图数据,以便更好地处理实际应用中的图数据。

一.基础1-[图论、图算法、CNN]

        基本概念:(1)Level Graph;(2)S-T cut;(3)Bipartite Graph;(4)Hungarian Algorithm;(5)Shapley Algorithm;(6)蒙特卡洛算法(Monte carlo Algorithm),随机梯度下降采用的是该算法。主要是依据大数定律验证正确性。 课程可学习:Monte Carlo Algorithms_哔哩哔哩_bilibili

  • 邻接矩阵(Adjacency Matrix):一个用于表示图中节点之间关系的矩阵。
  • 特征矩阵(Feature Matrix):一个用于表示节点特征的矩阵。
  • 卷积核矩阵(Kernel Matrix):一个用于表示卷积操作的矩阵。

二.基础2-[图卷积神经网络GCN]

         只要知道每一个节点和每个节点间的关系,就可以往图上套用。但是计算机视觉(CV)和自然语言处理(NLP)不常用,因为图像和文本数据的格式是固定的。比如,将图像resize成固定大小,进行卷积操作即可得到特征。

        传统NN中,一定要求格式是固定的。GNN用于输入是不同长度的情形。GNN目的就是重构(更新)特征。采用的方法叫嵌入(embedding),在自然语言处理(NLP)中词嵌入中也用到了。

        GCN思路是:针对一个节点计算特征后,平均其邻居特征和自身特征后传入NN。涉及到邻接矩阵、度矩阵、特征矩阵。        

        [归一化处理]​​:对聚合结果进行归一化,避免节点度数不同带来的偏差。                

        具体来说,(省略了矩阵头上的~)

        1.把对角均为1的对角矩阵(自己的特征)加入邻接矩阵\\mathbf{A},x特征矩阵\\mathbf{X}\\mathbf{AX}

        2.度矩阵\\mathbf{D},和倒数\\mathbf{D}^{-1},为了求它的平均\\mathbf{D}^{-1}(\\mathbf{AX})=(\\mathbf{D}^{-1}\\mathbf{A})\\mathbf{X}

          (相当于 行归一化)。同理对列做归一化,(\\mathbf{D}^{-1}\\mathbf{A})\\mathbf{X}\\mathbf{D}^{-1}=\\mathbf{D}^{-1}\\mathbf{A}\\mathbf{D}^{-1}\\mathbf{X}

        3.\\mathbf{D}^{-1}\\mathbf{A}\\mathbf{D}^{-1}\\mathbf{X}--->\\mathbf{D}^{-\\frac{1}{2}}\\mathbf{A}\\mathbf{D}^{-\\frac{1}{2}}\\mathbf{X}

                 为什么度要1--->1/2,有些点度很大,有些点度很小。而度很小的点,计算不一定准确。

       GCN通过 \\frac{1}{\\sqrt{deg(v_i)} \\sqrt{deg(v_j)}}将权重重新更新。

       GCN 的单层传播规则如下:

        其中可以看成是归一化后的邻接矩阵,相当于给l层所有节点的embedding做了一次线性变换,左乘邻接矩阵表示对于每个节点来说,该节点的特征变为邻居节点特征相加后的结果。 

        两个GCN层输出embedding计算为:

 

​        

        [卷积层数]:根据六度分离原理,卷积层数不会很大。 

        GCN 主要有两种类型:

  • 空间卷积网络: 相邻节点的特征被组合成中心节点, 特征的求和类似于普通的卷积运算。
  • 谱卷积网络:在谱网络中,卷积运算是通过计算在傅里叶域中定义的拉普拉斯特征分解完成。

三.torch-geometric.nn工具包安装(包含各种算法和数据集)

        依赖的下载地址: https://pytorch-geometric.com/whl/ ,选对应版本复制链接或下载本地,安装即可。

        cp是指python的版本,cp39-mac。

         官方介绍: 如数据集:torch_geometric.datasets — pytorch_geometric documentation

pip install torch-cluster https://data.pyg.org/whl/torch-2.7.0%2Bcpu/torch_cluster-1.6.3-cp39-cp39-macosx_10_9_universal2.whlpip install torch-scatter https://data.pyg.org/whl/torch-2.7.0%2Bcpu/torch_scatter-2.1.2-cp39-cp39-macosx_10_9_universal2.whlpip install torch-sparse https://data.pyg.org/whl/torch-2.7.0%2Bcpu/torch_sparse-0.6.18-cp39-cp39-macosx_11_0_universal2.whl#torch-spline-conv下载后本地安装pip install torch-spline-conv torch_spline_conv-1.2.2-cp39-cp39-macosx_10_9_universal2.whlpip install torch-geometric

四.GCN任务[节点分类-Cora 数据集]

          [GCN的论文出处]:Kipf T, Welling M. Semi-supervised classification with graph convolutional networks[C]. The fifth International Conference on Learning Representations, Toulon, France, 2017.

        有一篇博主的解读备阅:GNN教程:图神经网络“开山之作”!    

        图卷积操作的基本思想是将图数据映射到特定的特征空间,以便更好地捕捉图数据中的模式和关系。具体来说,图卷积操作可以看作是一种线性操作,它可以将图数据表示为一种特定的矩阵形式,然后通过矩阵乘法和线性变换来实现映射。   

        图神经网络的具体操作步骤如下;

        (原博主链接:https://juejin.cn/post/7325131333964120101)

  1. (1)将图数据转换为矩阵形式,以便进行图卷积操作。具体来说,将邻接矩阵、特征矩阵和卷积核矩阵构成一个矩阵形式的图数据。

  2. (2)对图数据进行卷积操作,以便将节点特征映射到特定的特征空间。具体来说,使用卷积核矩阵对图数据进行线性变换,以实现节点特征的映射。

  3. (3)对映射后的节点特征进行激活函数处理,以引入非线性性。具体来说,我们可以使用常见的激活函数,如ReLU、Sigmoid等,对映射后的节点特征进行处理。

        举个例子:使用 PyTorch Geometric 加载 Cora 数据集,并实现了一个简单的两层 GCN 模型。第一层将节点特征映射到16维空间,第二层将其映射到类别数,并使用 ReLU 激活函数进行非线性变换。

        若加载数据集报错,那可能是Github访问问题,先解决一下:

#找到并打开终端,可用【Command + 空格】聚焦搜索\"终端\" 回车打开。#修改hosts文件,Mac的hosts文件路径: /etc/hostssudo vi /etc/hosts#编辑hosts文件,在最后加上:20.27.177.113 github.com# 输入:wq命令保存#访问下Github.com 试试
import torchimport torch.nn.functional as Ffrom torch_geometric.nn import GCNConvfrom torch_geometric.datasets import Planetoidimport matplotlib.pyplot as pltimport networkx as nxfrom sklearn.manifold import TSNE# 加载Cora数据集dataset = Planetoid(root=\'datadownload\', name=\'Cora\')data = dataset[0]class GCN(torch.nn.Module): def __init__(self): super(GCN, self).__init__() self.conv1 = GCNConv(dataset.num_node_features, 16) self.conv2 = GCNConv(16, dataset.num_classes) def forward(self, data): x, edge_index = data.x, data.edge_index x = self.conv1(x, edge_index) x = F.relu(x) x = F.dropout(x, p=0.2, training=self.training) # Dropout操作,减少过拟合风险 x = self.conv2(x, edge_index) #x = F.log_softmax(x, dim=1) return x #return # 创建模型并训练print(f\'dataset.num_node_features:{dataset.num_node_features}\')model = GCN()print(model)device = torch.device(\'mps\')model = model.to(device)data = data.to(device)loss_function = torch.nn.CrossEntropyLoss()optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)# 训练函数def train(): model.train() optimizer.zero_grad() out = model(data) loss = loss_function(out[data.train_mask], data.y[data.train_mask]) loss.backward() optimizer.step() return loss.item(),out# 测试函数def test(): model.eval() with torch.no_grad(): logits = model(data) accs = [] for mask in [data.train_mask, data.val_mask, data.test_mask]: pred = logits[mask].max(1)[1] acc = pred.eq(data.y[mask]).sum().item() / mask.sum().item() accs.append(acc) return accs# 训练过程train_losses = []train_accs = []val_accs = []test_accs = []for epoch in range(200): loss,out = train() train_acc, val_acc, test_acc = test() train_losses.append(loss) train_accs.append(train_acc) val_accs.append(val_acc) test_accs.append(test_acc) if epoch % 10 == 0: print(f\'Epoch: {epoch:03d}, Loss: {loss:.4f}, \'  f\'Train: {train_acc:.4f}, Val: {val_acc:.4f}, Test: {test_acc:.4f}\')# 可视化图结构def visulize_graph(h, color): z = TSNE(n_components=2).fit_transform(h.detach().cpu().numpy()) plt.figure(figsize=(10, 10)) plt.xticks([]) plt.yticks([]) plt.scatter(z[:, 0], z[:, 1], s=70, c=color.cpu().numpy(), cmap=\'Set2\') plt.axis(\'off\') plt.savefig(\'datadownload/cora-graph.png\', dpi=300, bbox_inches=\'tight\') plt.close() visulize_graph(out, data.y)

       节点分类结果: Train Accuracy: 1.0000,Validation Accuracy: 0.7720, Test Accuracy: 0.8030 

五.图注意力网络(GAT)

        [论文出处]:Veličković, P., et al. (2018). Graph Attention Networks. ICLR.

        图注意力网络(Graph Attention Network, GAT)通过引入注意力机制来聚合邻居节点的特征。GAT 使用注意力系数来衡量邻居节点的重要性。

        GAT使用 GATConv 代替了 GCNConv。

from torch_geometric.nn import GATConvclass GAT(torch.nn.Module): def __init__(self): super(GAT, self).__init__() self.gat1 = GATConv(dataset.num_node_features, 8, heads=8, concat=True) self.gat2 = GATConv(8 * 8, dataset.num_classes, heads=1, concat=False) def forward(self, data): x, edge_index = data.x, data.edge_index x = self.gat1(x, edge_index) x = F.elu(x) x = self.gat2(x, edge_index) return F.log_softmax(x, dim=1)# 创建并训练GAT模型model = GAT()optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)model.train()for epoch in range(200): optimizer.zero_grad() out = model(data) loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask]) loss.backward() optimizer.step() print(f\'Epoch {epoch}, Loss: {loss.item()}\')

        结果:Train Accuracy: 1.0000,Validation Accuracy: 0.7320, Test Accuracy: 0.7730

六.图自编码器(GAE)

        图自编码器(Graph Autoencoder, GAE)是一种用于无监督学习图嵌入的方法。GAE 通过编码器和解码器来学习节点的低维表示。

        使用了 Variational Graph Autoencoder (VGAE) 来进行图的无监督学习。GAE 可以有效地学习图的潜在结构,特别适合于节点嵌入和链接预测任务。

from torch_geometric.nn import GCNConv, VGAEclass Encoder(torch.nn.Module): def __init__(self, in_channels, out_channels): super(Encoder, self).__init__() self.conv1 = GCNConv(in_channels, 2 * out_channels, cached=True) self.conv2 = GCNConv(2 * out_channels, out_channels, cached=True) def forward(self, data): x, edge_index = data.x, data.edge_index x = F.relu(self.conv1(x, edge_index)) return self.conv2(x, edge_index) # 定义模型和优化器encoder = Encoder(dataset.num_node_features, 16)model = VGAE(encoder)optimizer = torch.optim.Adam(model.parameters(), lr=0.01)model.train()for epoch in range(200): optimizer.zero_grad() z = model.encode(data.x, data.edge_index) loss = model.recon_loss(z, data.edge_index) loss.backward() optimizer.step() print(f\'Epoch {epoch}, Loss: {loss.item()}\')

        结果:Train Accuracy: 1.0000,Validation Accuracy: 0.7900, Test Accuracy: 0.7990 

七.图循环神经网络 (GRNN)

        图循环神经网络 (GRNN:Graph Recurrent Neural Network) 利用多关系图并使用基于图的正则化器来提高平滑度并减轻过度参数化。 由于邻域的确切大小并不总是已知,因此使用循环 GNN 层使网络更加灵活。 GRNN 可以学习适合数据的最佳扩散模式。 它还能够处理节点涉及多个关系的情况。 该网络的计算成本也很低,因为操作数量根据图边的数量线性缩放。

八.门控图神经网络(GGNN)

        在具有长期依赖性的问题上,门控图神经网络(GGNN:Gated Graph Neural Network)比循环图神经网络表现更好。 长期依赖关系由节点和边缘门编码。 长期时间依赖性由时间门编码。 因此,门控图神经网络通过添加门控机制来改进循环图神经网络。 这些门负责不同状态下的信息记忆和遗忘。

class GCN_GRU(torch.nn.Module): def __init__(self): super(GCN_GRU, self).__init__() self.gru = nn.GRU(input_size=dataset.num_node_features, hidden_size=16) self.gcn = GCN() def forward(self, data): x, edge_index = data.x, data.edge_index x = self.gru(x) x = self.gcn(data) return x

结果:Train Accuracy: 1.0000,Validation Accuracy: 0.7680, Test Accuracy: 0.7880

九. 应用场景

(1)社交网络分析

在社交网络中,GNN 可以用于节点分类(如用户兴趣预测)、边预测(如好友推荐)以及社区发现等任务。GCN 和 GAT 等模型能够有效地捕获社交网络中的复杂关系。

(2)推荐系统

在推荐系统中,用户和商品可以看作是图中的节点,用户与商品之间的交互(如评分、点击)可以作为图的边。通过 GNN,我们可以构建用户和商品的嵌入,用于预测用户对某商品的兴趣。

(3)生物信息学

在生物信息学中,GNN 被广泛用于蛋白质结构预测、药物发现和基因相互作用网络的分析。通过 GNN,可以有效地学习分子结构的表示,从而加速药物的筛选和发现。