2202 字
11 分钟
图神经网络:处理图结构数据的强大工具

数据并非总是能整齐地排列在行和列中。实际上,数据经常以图结构的形式呈现出来,比如社交网络、蛋白质结构、推荐系统或交通运输系统等。如果在机器学习模型中忽略了图的拓扑信息,可能会严重影响模型的性能。

图神经网络#

图神经网络(Graph Neural Networks, GNN)是一类专门设计用于处理和分析图结构数据的神经网络模型。与传统的神经网络不同,GNN能够直接处理由节点和边组成的图数据,这使它在处理关系型数据时具有独特优势。图中的每个节点都关联着一个特征向量(或嵌入),用于捕捉其属性或特征。GNN通过聚合来自相邻节点和边的信息来更新这些嵌入。

在现实世界中,很多数据天然具有图结构特征。比如社交网络中的用户关系、科学文献之间的引用关系等。传统的神经网络主要处理规则的网格型数据(如自然语言处理中的序列数据或计算机视觉中的图像数据),而无法有效利用数据之间的关系信息。

GNN的核心特点:#

  • 每个节点都包含一个特征向量,用于描述该节点的属性特征
  • 通过汇聚相邻节点的信息来更新节点的特征表示
  • 能够同时捕捉数据的局部和全局关系

预测任务#

Cora数据集(https://linqs-data.soe.ucsc.edu/public/lbc/cora.tgz)是一个常用的图神经网络基准数据集。该数据集包含了2708篇科学出版物的数据。这些出版物构成了图中的节点。当一篇出版物引用另一篇出版物时,就会在这两个节点(出版物)之间创建一条边。

加载数据集:

from torch_geometric.datasets import Planetoid

dataset = Planetoid(root=”.”, name=“Cora”)
data = dataset[0]
num_labels = len(set(data.y.numpy())

本文分别使用传统的神经网络和图卷积网络预测确定每篇论文的研究主题,总共有7个类别。

1. 传统神经网络#

传统的神经网络由多个层组成:包括输入层、隐藏层和最终的输出层。每一层都由神经元构成,这些神经元通过权重与下一层相连。神经网络的目标是利用训练数据来优化这些权重。当数据通过神经元时,输出会与权重相乘,然后求和,并在每个神经元上通过激活函数进行转换。输出层产生最终的预测结果。神经网络的其他重要组成部分还包括损失函数(用于衡量预测结果与实际结果之间的差异,也就是误差),以及用于更新网络权重的反向传播(通过Adam等优化器实现)。

首先使用传统的神经网络多层感知器(MLP)来训练这个数据集。这里我们不使用图的信息,仅使用每个节点的特征来预测目标。完全忽略了文献之间的引用关系。下面的代码展示了这个神经网络的类定义,它包含2个隐藏层。

1import torch
2import torch.nn as nn
3import torch.nn.functional as F
4
5class MLP(torch.nn.Module):
6 def init(self, input_dim, hidden_dim, output_dim):
7 super().init()
8 self.lin1 = nn.Linear(input_dim, hidden_dim)
9 self.lin2 = nn.Linear(hidden_dim, output_dim)
10
11 def forward(self, data):
12 x = data.x
13 x = F.relu(self.lin1(x))
14 x = self.lin2(x)
15 return F.log_softmax(x, dim=1)

我们使用下面的代码来训练和评估模型:

1device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)
2results = {}
3
4# iterate over the different model types
5for model_class in [MLP]:
6 results[model_class.name] = []
7 for i in range(10):
8 print(f”Training {model_class.name} iteration {i+1}“)
9
10 # the output_dim is the number of unique classes in the set
11 model = model_class(input_dim=data.x.shape[1], hidden_dim=32, output_dim=num_labels).to(device)
12 optimizer = optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
13
14 # deal with the class imbalance
15 class_weights = torch.bincount(data.y) / len(data.y)
16 loss_fn = nn.CrossEntropyLoss(weight=1/class_weights).to(device)
17
18 data = data.to(device)
19
20 # training loop
21 for epoch in range(100):
22 model.train()
23 optimizer.zero_grad()
24 out = model(data)
25
26 # calculate loss
27 train_loss = loss_fn(out[data.train_mask], data.y[data.train_mask])
28 acc = accuracy(out[data.train_mask].argmax(dim=1), data.y[data.train_mask])
29 train_loss.backward()
30 optimizer.step()
31
32 if epoch % 10 == 0:
33 model.eval()
34 with torch.no_grad():
35 val_loss = loss_fn(out[data.val_mask], data.y[data.val_mask])
36 val_acc = accuracy(out[data.val_mask].argmax(dim=1), data.y[data.val_mask])
37 print(f’Epoch {epoch} | Training Loss: {train_loss.item():.2f} | Train Acc: {acc:>5.2f} | Validation Loss: {val_loss.item():.2f} | Validation Acc: {val_acc:>5.2f}‘)
38
39 # final evaluation on the test set
40 model.eval()
41 with torch.no_grad():
42 out = model(data)
43 test_loss = loss_fn(out[data.test_mask], data.y[data.test_mask])
44 test_acc = accuracy(out[data.test_mask].argmax(dim=1), data.y[data.test_mask])
45 print(f’{model_class.name} Test Loss: {test_loss.item():.2f} | Test Acc: {test_acc:>5.2f}‘)
46 results[model_class.name].append([acc, val_acc, test_acc])
47
48
49# print average on test set and standard deviation
50for model_name, model_results in results.items():
51 model_results = torch.tensor(model_results)
52 print(f’{model_name} Test Accuracy: {model_results[:, 2].mean():.2f} ± {model_results[:, 2].std():.2f}’)

我们进行了10次训练,并计算了平均准确率和标准差。MLP类的输出结果是:

MLP Test Accuracy: 54.35 ± 1.06

2. 图卷积网络#

图卷积网络(Graph Convolutional Network, GCN)是图神经网络家族中最基础和重要的模型之一。它的核心思想是将传统卷积神经网络在图像处理中的卷积操作推广到图结构数据上。在GCN中,每个节点会通过一种特殊的”卷积”操作来聚合其邻居节点的信息,这个过程可以类比为在图像中,一个像素点受到周围像素点的影响。具体来说,对于图中的每个节点,GCN会执行两个主要步骤:首先是信息聚合,即收集所有邻居节点的特征,并根据某种权重方案(通常基于图的结构特征)将这些信息加权组合;然后是特征转换,即将聚合后的信息通过一个神经网络层进行非线性变换,得到节点的新特征表示。通过多层GCN的堆叠,每个节点能够逐步获取到更大范围的结构信息,最终学习到既包含局部结构特征又包含全局网络信息的节点表示。这种设计使得GCN在社交网络分析、分子属性预测、推荐系统等众多领域都表现出色,成为了图学习领域的基石模型。

接下来使用相同的数据集来训练图卷积网络并计算准确率。GCN不仅考虑节点特征,还利用了图的边信息。

我们在PyTorch中使用GCNConv来定义卷积层:

1class GCN(torch.nn.Module):
2 def init(self, input_dim, hidden_dim, output_dim):
3 super().init()
4 self.conv1 = GCNConv(input_dim, hidden_dim)
5 self.conv2 = GCNConv(hidden_dim, output_dim)
6
7 def forward(self, data):
8 x, edge_index = data.x, data.edge_index
9 x = F.relu(self.conv1(x, edge_index))
10 x = self.conv2(x, edge_index)
11 return F.log_softmax(x, dim=1)

用于训练的代码与上面的传统神经网络下相同,只是把上面第5行的MLP替换为GCN。

输出结果如下:

GCN Test Accuracy: 78.76 ± 0.38

仅仅通过添加图结构信息,模型的准确率提升了超过24个百分点!通过汇聚邻近节点的信息,GCN能够提供更丰富的数据表示,从而带来更准确的预测结果。这个显著的性能提升充分说明了在处理关系型数据时,图神经网络的优势。

结论#

虽然图神经网络表现优异,但在实际应用时需要注意:

  • 确保数据中的图结构是有意义的,与预测任务相关
  • 考虑计算复杂度的增加是否值得
  • 可以尝试不同的GNN架构,如图注意力网络(GAT),以获得更好的效果

图神经网络展现了强大的数据处理能力,特别是在处理具有复杂关系结构的数据时。通过合理使用GNN,我们能够更好地挖掘数据中蕴含的关系信息,获得更准确的预测结果。

References:

本公众号相关内容推荐#

图神经网络:处理图结构数据的强大工具
https://blog.scidatalab.net/posts/图神经网络-处理图结构数据的强大工具/
作者
Echo
发布于
2024-10-30
许可协议
CC BY-NC-SA 4.0