图数据处理代码(全)

来源:投稿 作者:张宇
编辑:学姐

单张图被PyG表示为 torch_geometric.data.Data 类型,有如下属性:

data.x : 节点的特征矩阵 , 形状为 [num_nodes, num_node_features]

data.edge_index : COO格式的图的边shape [2, num_edges] and type torch.long

data.edge_attr :边的特征矩阵 shape [num_edges, num_edge_features]

data.y : 训练数据的标签,节点级的目标 shape [num_nodes, *] or 图级的目标 shape [1, *]

data.pos : 节点的位置矩阵 shape [num_nodes, num_dimensions]

import torch
from torch_geometric.data import Data

# 一个无权无向图的例子
# 边的索引 COO格式 就是说第一行代表行索引 第二行代表列索引
# 节点0 1之间有一条边 12之间有一条边edge_index = torch.tensor([[0, 1, 1, 2],
[1, 0, 2, 1]], dtype=torch.long)
# 节点0 1 2的特征分别是
x = torch.tensor([[-1], [0], [1]], dtype=torch.float)

data = Data(x=x, edge_index=edge_index)
# 不是COO格式的边 是使用边的两个节点的元组形式
import torch
from torch_geometric.data import Data
edge_index = torch.tensor([[0, 1],
[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提供了如下方法进行访问:

# 可以使用类似字典的方式
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
对于Data类的更多方法可以看这里
常用的基准数据集
PyG提供了大量的基准数据集,比如Planetoid datasets (Cora, Citeseer, Pubmed),更多图的数据集可
以看这个链接 这里 ,以及这里 。
使用PyG处理数据非常简单,并且下载下来就是源文件格式(raw file,可能在一些程序中看见这个单
词),并且会自动处理为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
# 也可以向PyTorch一样转到GPU里面
device = torch.device('cuda')
data = data.to(device)

对于Data类的更多方法可以看这里:

https://pytorch-geometric.readthedocs.io/en/latest/modules/data.html#torch_geometric.data.Data

常用的基准数据集

PyG提供了大量的基准数据集,比如Planetoid datasets (Cora, Citeseer, Pubmed),更多图的数据集可以看这个链接👇

https://pytorch-geometric.readthedocs.io/en/latest/modules/data.html#torch_geometric.data.Data

https://github.com/nd7141/graph_datasets

使用PyG处理数据非常简单,并且下载下来就是源文件格式(raw file,可能在一些程序中看见这个单词),并且会自动处理为Data格式,例如:

from torch_geometric.datasets import TUDataset
# 导入数据集 参数分别为:保存的文件 导入数据集的名字
dataset = TUDataset(root='/tmp/ENZYMES', name='ENZYMES')
>>> ENZYMES(600) # 这个数据集包含600张图
len(dataset)
>>> 600
dataset.num_classes
>>> 6
#节点特征数
dataset.num_node_features
>>> 3
# 查看第一张图
data = dataset[0]
>>> Data(edge_index=[2, 168], x=[37, 3], y=[1])
data.is_undirected()
>>> True # 无向图

我们可以看到数据集中的第一个图包含37个节点,每个节点有3个特性。有168/2 = 84条无向边,图被分配到一个类中。此外,数据对象只持有一个图级目标。

我们甚至可以使用切片、long或bool张量来分割数据集。例如,要创建90/10的训练/测试分割,输入:

train_dataset = dataset[:540]
>>> ENZYMES(540)
test_dataset = dataset[540:]
>>> ENZYMES(60)
# 同样 也可以打乱数据
dataset = dataset.shuffle()
>>> ENZYMES(600)
# 等于这个操作
perm = torch.randperm(len(dataset))
dataset = dataset[perm]
>> ENZYMES(600)

让我们再试一个!让我们下载Cora,半监督图节点分类的标准基准数据集,这个数据集是图神经网络论文中经常看见的数据集,是一个论文的引用图,节点的特征为论文的词向量:

from torch_geometric.datasets import Planetoid
dataset = Planetoid(root='/tmp/Cora', name='Cora')
>>> Cora()
len(dataset)
>>> 1 # 数据集只有一张图
dataset.num_classes
>>> 7 # 分为7类
dataset.num_node_features
>>> 1433 # 每个节点有1433维特征
data = dataset[0]
>>> Data(edge_index=[2, 10556], test_mask=[2708],
train_mask=[2708], val_mask=[2708], x=[2708, 1433], y=[2708])
data.is_undirected()
>>> True

Data对象保存每个节点的标签,以及额外的节点级属性:

train_mask、val_mask和test_mask,其中Train_mask表示要训练哪个节点(140个节点),

Val_mask表示使用哪些节点进行验证,例如,执行早期停止(500个节点),

Test_mask表示要测试哪个节点(1000个节点)。

比如data.train_mask 是一个一维的bool类型的tensor,里面的数据是True就代表是训练数据。

data.train_mask.sum().item()
>>> 140
data.val_mask.sum().item()
>>> 500
data.test_mask.sum().item()
>>> 1000

Mini-Batches

神经网络通常以批处理方式进行训练。PyG通过创建稀疏块对角邻接矩阵(由edge_index定义)和连接节点维上的特征和目标矩阵来实现小批量的并行化。这种组合允许在一个批处理中不同数量的节点和边:

PyG包含它自己的torch_geometric.loader.DataLoader ,它已经处理了这个连接过程。其实使用的过程和torch里面的DataLoader是一样的:

from torch_geometric.datasets import TUDataset
from torch_geometric.loader import DataLoader
dataset = TUDataset(root='/tmp/ENZYMES', name='ENZYMES', use_node_attr=True)
loader = DataLoader(dataset, batch_size=32, shuffle=True)
for batch in loader:
batch
>>> DataBatch(batch=[1082], edge_index=[2, 4066], x=[1082, 21], y=[32])
batch.num_graphs
>>> 32

torch_geometric.data.Batch从torch_geometric.data.Data 继承,并包含称为batch 的附加属性。

batch是一个列向量,保存了batch中每个节点和对应图的映射关系。

可以使用batch来计算batch中每个图中各个节点的平均特征。

from torch_scatter import scatter_mean
from torch_geometric.datasets import TUDataset
from torch_geometric.loader import DataLoader
dataset = TUDataset(root='/tmp/ENZYMES', name='ENZYMES', use_node_attr=True)
loader = DataLoader(dataset, batch_size=32, shuffle=True)
for data in loader:
data
>>> DataBatch(batch=[1082], edge_index=[2, 4066], x=[1082, 21], y=[32])
data.num_graphs
>>> 32
# 按图维度求平均
x = scatter_mean(data.x, data.batch, dim=0)
x.size()
>>> torch.Size([32, 21])

Data Transforms

下面以一个例子来解释,ShapeNet数据集是包含17000个3D点云的数据集。

from torch_geometric.datasets import ShapeNet
dataset = ShapeNet(root='/tmp/ShapeNet', categories=['Airplane'])
dataset[0]
>>> Data(pos=[2518, 3], y=[2518])

我们可以通过transforms将点云生成最近邻图,将点云数据集转换为图数据集:

import torch_geometric.transforms as T
from torch_geometric.datasets import ShapeNet
# 主要就是加了最后一个参数pre_transform
dataset = ShapeNet(root='/tmp/ShapeNet', categories=
['Airplane'],pre_transform=T.KNNGraph(k=6))
dataset[0]
>>> Data(edge_index=[2, 15108], pos=[2518, 3], y=[2518])

pre_transform参数可以在数据存入磁盘之前进行转换,在下次使用时,数据集将自动包含边。

此外,我们可以使用transform参数来随机增强一个Data对象,例如,将每个节点的位置转换为一个小数字:

import torch_geometric.transforms as T
from torch_geometric.datasets import ShapeNet
dataset = ShapeNet(root='/tmp/ShapeNet', categories=['Airplane'],
pre_transform=T.KNNGraph(k=6),
transform=T.RandomTranslate(0.01))
dataset[0]
>>> Data(edge_index=[2, 15108], pos=[2518, 3], y=[2518])

图学习方法

在学习了PyG中的数据处理、datasets, loader 以及 transforms之后,是时候实现我们的第一个图形神经网络了!

我们将使用一个简单的GCN层,并在Cora引文数据集上复制实验。关于GCN的解释,请看 http://tkipf.g ithub.io/raph-convolutional-networks/ 。

首先,加载数据集:

from torch_geometric.datasets import Planetoid
dataset = Planetoid(root='/data/Cora', name='Cora')

然后定义一个两层的GCN,和torch里面的定义方式一样,只是在传入GCN网络时传的是两个参数,第一个是数据特征,第二个是边的index。数据特征x就是每个节点的特征向量,edge_index就是(2,节点数)的Tensor,表示哪两个节点之间有边。卷积层后面的ReLU激活函数以及dropout层也是常用的,也不做介绍。

import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
然后对网络进行训练,训练的方式也是和torch中形式一样的:
最后网络新的训练精度进行测试
最后做个总结的话就是,使用PyG的图神经网络,其实和torch总体使用过程是差不多的,最重要的就是
DataLoader的写法。如果使用 torch_geometric.datasets 中没有的数据集的话,将数据转化为图的
形式可能需要一些时间。
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)

然后对网络进行训练,训练的方式也是和torch中形式一样的:

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

总结

最后做个总结的话就是,使用PyG的图神经网络,其实和torch总体使用过程是差不多的,最重要的就是DataLoader的写法。如果使用 torch_geometric.datasets 中没有的数据集的话,将数据转化为图的形式可能需要一些时间。

关注下方《学姐带你玩AI》🚀🚀🚀

AI干货、论文资料、数据集……持续更新中

码字不易,欢迎大家点赞评论收藏!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MATLAB源程序代码MATLAB像处理信号处理设计源码52个合集: MATLAB DCT水印源程序代码.rar MATLAB GUI实现动态画曲线的源程序代码.rar MATLAB三次样条插值法 求信号的包络线 源代码.rar MATLAB中colorbar的设置 源程序代码.rar MATLAB中的基本语法和语句示例代码.rar MATLAB使用欧拉Euler法求解微分方程组 源程序代码.rar MATLAB信号处理 频谱分析加汉宁窗函数 源代码.rar MATLAB光通过三稜镜色散动画.rar MATLAB动画 龟兔赛跑 源程序代码.rar MATLAB四阶龙格库塔法 求解微分方程数值解 源程序代码.rar MATLAB像处理 Hough霍夫曼直线检测 源程序代码.rar MATLAB像处理实现直线识别(拟合角平分线).rar MATLAB像处理实现螺纹识别 源程序代码.rar MATLAB夜间车牌识别程序.rar MATLAB实现txt文本数据分离的源程序代码.rar MATLAB实现不同插值方法的GUI界面设计 源程序代码.rar MATLAB实现偏微分方程的差分计算 源程序代码.rar MATLAB实现单摆在外力矩作用下的动画 源程序代码.rar MATLAB实现像中值 均值 维纳滤波 源程序代码.rar MATLAB实现像分割otsuf 源程序代码.rar MATLAB实现像去噪 滤波 锐化 边缘检测 源程序代码.rar MATLAB实现学生成绩查询系统 源代码程序.rar MATLAB实现正方体旋转 源程序代码.rar MATLAB实现灰度预测模型的源代码.rar MATLAB实现线性拟合和相关系数 源程序代码.rar MATLAB实现股票价格预测 源程序代码.rar MATLAB寻找素数的源程序代码.rar MATLAB希尔伯特Hilbert变换求包络谱 源程序代码.rar MATLAB建模 人口增长模型 源程序代码.rar MATLAB拟合求解圆心和半径 源程序代码.rar MATLAB文字连通域源程序代码.rar MATLAB求解偏微分方程(扩散方程)有限差分法 源程序代码.rar MATLAB求解无穷区间定积分问题 源程序代码.rar MATLAB求解混沌系统微分方程组.rar MATLAB求解矩阵的特征值 源程序代码.rar MATLAB求解非线性方程组 fsolve源程序代码.rar MATLAB求解非线性最小二乘法拟合问题 源程序代码.rar MATLAB牛顿法求解非线性方程组 源程序代码.rar MATLAB生成Gif片程序源代码.rar MATLAB符号计算实例 函数的最值点渐近线拐点 源程序.rar MATLAB绘制 维维安尼Viviani曲线 源代码程序.rar MATLAB绘制分子结构 源程序代码.rar MATLAB绘制圆形并填充斜线 源程序代码.rar MATLAB计算粒子速度分布 源程序代码.rar MATLAB设计的简单滤波器程序源代码.rar MATLAB霍夫曼Huffman编码译码GUI界面设计 源程序代码.rar RBF神经网络的训练 MATLAB源程序代码.rar 基于仿射变换的数字象置乱技术 MATLAB源程序代码.rar 拉格朗日插值 MATLAB源程序代码.rar 杨氏双孔干涉实验的MATLAB计算机模拟 源程序代码.rar 牛顿Newton插值 MATLAB源程序代码.rar 蒙特卡洛法求椭圆面积的MATLAB源程序代码.rar

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值