赞
踩
目录
三. 图神经网络(Graph Neural Network)
图论(Graph theory)是对图(Graph)的数学研究,是理解复杂系统和关系的基本工具。图是节点(Node)和连接这些节点的边(Edge)的集合的直观表示,图提供了表示实体及其关系的结构,如下图所示。
(1)邻接矩阵(Adjacency matrix)
(2)度矩阵( Degree matrix)
图可以将复杂系统表示为具有交互作用的实体网络,可以分析它们之间的关系,从而更深入地了解其基本结构和模式。图在各个领域都具有广泛用途:
这些领域内在的包含某种关系结构。例如,图是社交网络的自然表征:节点是用户,边代表用户与用户之间的联系。除此之外,图的用途非常广泛,也可以应用于关系结构并不那么自然的领域,例如,图像可以用图来表示,如下图所示。每个像素都是一个节点,边代表相邻像素之间的关系。这样就可以将基于图的算法应用到图像处理和计算机视觉任务中。
同样,一个句子也可以转换成一个图,其中节点是单词,边代表相邻单词之间的关系。这种方法在自然语言处理和信息检索任务中非常有用,因为在这些任务中单词的上下文和含义至关重要。
与文本和图像不同,图没有固定的结构,这种灵活性也使图的处理更具挑战性。没有固定的结构意味着它们可以有任意数量的节点和边,没有特定的排序。此外,图还可以表示动态数据,动态数据的实体之间的联系会随着时间的推移而发生变化。例如,用户和产品之间的关系会随着它们之间的互动而改变。在这种情况下,节点和边会被更新,以反映现实世界中的变化,如新用户、新产品和新关系。
Graph Embedding做的事情是将图表示成为低维向量,类似与nlp将词、句子等embedding。distributed representation的一体化过程,万物皆可embedding。
图嵌入的目标是发现高维图的低维向量表示,而获取图中每个节点的向量表示是十分困难的,并且具有几个挑战,这些挑战一直在推动本领域的研究:
举个形象的例子:
图嵌入就像词嵌入,而图神经网络就像全连接神经网络。词嵌入就是词的向量表达,可以供给一个分类模型做分类。全连接神经网络可以直接对一些问题做分类。同时全连接神经网络可以帮助训练词嵌入(word2vec),同样的,图神经网络也可以帮助训练图嵌入。
在这里看到了另一种解释,我觉得说的很好:
图嵌入是为了把现实中的图数据映射(嵌入)到数学上的某一特征空间中,这样我们就可以用概率分布来描述这个图数据的信息,这个概率分布就是嵌入向量,它 融合了图的结构信息和节点的特征信息。 图嵌入是图数据挖掘的中间任务之一,比如我们要做节点分类,那就要先对图做嵌入,也就是要先拿到节点的嵌入特征向量(也就是embedding向量)后,这样才能将概率分布形式的节点输入分类器或者其他下游任务模型。
早期的图嵌入算法,就好像学一个 非常复杂的大型映射函数,是一个独立的过程,如deepwalk、line等,只是拿到独立的可以表征图数据的嵌入向量。
而图神经网络是一个 端到端(End-to-End)的过程,比如直接通过模型进行节点分类,节点的嵌入向量只是前向过程中得到的隐藏层向量h
,而且这些向量是根据特定下游任务训练出来的。我们可以通过图神经网络针对某一任务做图嵌入,比如对于节点分类任务,训练网络得到适用于节点分类的所有节点嵌入向量。
图神经网络的核心思想是通过消息传递机制(message-passing mechanism)来聚合节点的邻居信息,并更新节点的特征表示。这个过程通常会进行多轮迭代,以便捕获图中更远距离的信息。最终,每个节点的特征表示将包含其邻居和更远节点的信息。
图神经网络的基本组成部分包括:
许多GNN(例如,ConvGNN)可以在端到端学习框架内以(半)监督或纯无监督的方式进行训练,这取决于学习任务和手边可用的标签信息。
接下来借助pytorch-geometric库介绍如何构造图神经网络数据集和模型。
图用于建模对象(节点)之间的成对关系(边)。PyG中的单个图形由torch_geometry .data
的一个实例描述,Data
实例默认包含以下属性:
- import torch
- from torch_geometric.data import Data
- edge_index=torch.tensor([[0,1], #下标从0开始
- [1,0],
- [1,2],
- [2,1]],dtype=torch.long)
- x=torch.tensor([[-1],[0],[1]],dtype=torch.float)
-
- data=Data(x=x,edge_index=edge_index.t().contiguous())
- >>>Data(edge_index=[2,4],x=[3,1])
- import torch
- from torch_geometric.data import Data
- edge_index=torch.tensor([[0,1], #下标从0开始
- [1,0],
- [1,2],
- [2,1]],dtype=torch.long)
- x=torch.tensor([[-1],[0],[1]],dtype=torch.float)
-
- data=Data(x=x,edge_index=edge_index.t().contiguous())
- >>>Data(edge_index=[2,4],x=[3,1])
除了持有一些节点级、边级或图级属性外,Data
还提供了一些有用的实用函数,例如:
- print(data.keys())
- >>>['x','edge_index']
-
- print(data['x'])
- >>>tensor([[-1.0],
- [0.0],
- [1.0]])
-
- for key,item in data:
- print(f'{key} found in data')
- >>>x found in data
- >>>edge_index found in data
-
- 'edge_attr' in data
- >>>False
-
- data.num_nodes
- >>>3
-
- data.num_edges
- >>>4
-
- data.num_node_features
- >>>1
-
- data.has_isolated_nodes()
- >>>False
-
- data.has_self_loops()
- >>>False
-
- data.is_directed()
- >>>False
-
- # Transfer data object to GPU.
- device=torch.device('cuda')
- data=data.to(device)
PYG提供了线上入门教程,可以在线跑图神经网络的代码:Colab Notebooks and Video Tutorials
接下来基于Cora数据集构造一个简单的GCN并训练,Cora是半监督图节点分类的基准数据集:图数据集之cora数据集介绍 --- 适用于GCN任务
下面这个模块的在线代码:https://colab.research.google.com/drive/14OvFnAXggxB8vM4e8vSURUp1TaKnovzX?usp=sharing
- # 加载数据
- from torch_geometric.datasets import Planetoid
- dataset = Planetoid(root='/tmp/Cora',name='Cora')
-
- import torch
- import torch.nn.functional as F
- from torch_geometric.nn import GCNConv
-
- # 定义两层GCN
- class GCN(torch.nn.Module):
- def __init__(self):
- super().__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, training=self.training)
- x = self.conv2(x, edge_index)
-
- return F.log_softmax(x, dim=1)
-
- # 模型训练
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
- model = GCN().to(device)
- data = dataset[0].to(device)
- 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()
- model.eval()
- pred = model(data).argmax(dim=1)
- correct = (pred[data.test_mask]==data.y[data.test_mask]).sum()
- acc = int(correct)/int(data.test_mask.sum())
- print(f'Accuracy: {acc:.4f}')
- >>>Accuracy:0.8150
博客:
Paper:
官网:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。