PyG教程1:数据的介绍

1.图的创建

数据描述的是同构图的数据,可以用于节点,边预和图属性的关系。

classData(x: Optional[Tensor] = None, edge_index: Optional[Tensor] = None, 
edge_attr: Optional[Tensor] = None, y: Optional[Tensor] = None,
pos: Optional[Tensor] = None, **kwargs)

属性介绍:

  • data.x: 节点特征矩阵,shape为[num_nodes, num_node_features]

  • data.edge_index: 边索引(边表),shape为[2, num_edges],在这个包含两行的数组中,第1行与第2行中对应索引位置的值分别表示一条边的源节点和目标节点,LongTensor类型。

  • data.edge_attr:边特征矩阵,shape为[num_edges, num_edges_featrues]Tensor类型

  • data.y:    图级标签或节点级标签,Tensor类型

  • data.pos:节点的位置矩阵,shape为[num_nodes, num_dimensions]Tensor类型

Data类的初始化函数中参数默认值都为None,这意味着没有哪个参数是必要的,在实际使用时需要根据待构造图的实际情况来传入相应的属性

简单的示例:

import torch
from torch_geometric.data import Data

edge_index = torch.tensor([[0, 1, 1, 2],
                           [1, 0, 2, 1]], dtype=torch.long)
x = torch.tensor([[-1], [0], [1]], dtype=torch.float)

data = Data(x=x, edge_index=edge_index)
>>> 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)

Common Benchmark Datasets

PyG包含了很多公用的数据集,如(Cora, Citeseer, Pubmed)。

Mini-Batches

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

PyG教程1:数据的介绍_第1张图片

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         #每次以32次的批次处理
    >>> DataBatch(batch=[1082], edge_index=[2, 4066], x=[1082, 21], y=[32])

    batch.num_graphs
    >>> 32

Data Transforms

 Transform在计算机视觉中十分常用,主要是用于图片格式的转换和数据增强。PyG同样有其自己的transform操作,使用Data对象作为输入,返回一个新的Data对象。
可以用torch_geometric.transforms.Compose来将变换操作连起来,且可以选择在存入磁盘前操作(pre_transform)或者在访问数据集中的graph前执行(transform)。下面是是一个在ShapeNet数据集(一个包含17000个三维点云,给个点云中的每一点都有一个分类标签,标签共有16种)上做transform的实例。
 

from torch_geometric.datasets import ShapeNet

dataset = ShapeNet(root='/tmp/ShapeNet', categories=['Airplane'])

dataset[0]
>>> Data(pos=[2518, 3], y=[2518])

我们可以用K近邻的方法将每一个point cloud 都转换成图经由transfoms,这里选择最近的6个邻居。

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))

dataset[0]
>>> Data(edge_index=[2, 15108], pos=[2518,3], y=[2518])

此外还可以用transform来做一些数据增强,如给每一个点的坐标都加一个小扰动。LeaL

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])

Learning Methods on Graphs 

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch_geometric
from torch_geometric.nn import MessagePassing
from torch_geometric.utils import to_networkx
import networkx as nx
from torch_geometric.data import Data
import matplotlib.pyplot as plt

import torch_geometric.transforms as T
from torch_geometric.datasets import ShapeNet

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

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}')

你可能感兴趣的:(论文研读,深度学习,pytorch,人工智能)