目录

一. Data说明

二. 数据集构建

1. 单一图的构建

 2. 图数据集的构建

三. 数据加载器

五. 样本获取

1. 单一图获取读取

2. 数据集图读取

 

六. 参考文章


一. Data说明

    在GNN制作数据集,PyTorch 中有一个专门用于图数据的库 torch-geometric(简称 PyG),它里面有很多功能来处理图数据。构建 GNN 数据集时,数据通常由以下几部分组成:

  • 节点特征(Node Features):每个节点的特征向量。
  • 边列表(Edge List):图中边的连接信息,通常是一个 (source_node, target_node) 的二元组。
  • 图标签(Graph Labels):如果是图分类任务,每个图有一个标签;如果是节点分类任务,每个节点有一个标签。
  • 边特征(Edge Features):如果边也有特征,可以附加上边特征。

PyG中的数据集使用一个torch_geometric.data.Data对象表示,具体表示为:

  • data.x:具有形状的节点特征矩阵[num_nodes,num_Node_features]
  • data.edge_index:COO格式的图形连接,形状为[2,num_edges],类型为torch.long
  • data.edge_attr:具有形状的边缘特征矩阵[num_edges,num_edge_features]
  • data.y:要训练的目标(可以具有任意形状),例如,形状为[num_nodes,*]的节点级目标(每个节点都有标签)或形状为[1,**]的图级目标(整张图只有一个标签)
  • data.pos:形状为[num_nodes,num_dimensions]的节点位置矩阵

        如果想要让一个 GNN 模型同时进行图分类和节点分类任务。你可以使用一个共享的图神经网络结构,同时在最后通过不同的头(head)来分别进行不同任务的预测。


二. 数据集构建

1. 单一图的构建

        单一图的构建比较简单,由于数据集的构建因为有监督学习和无监督学习也会有区别。下面案例展示建立一个三任务的有监督图数据

import torch
from torch_geometric.data import Data

# 模拟数据
num_students = 100
num_features = 18  # 例如:浏览次数、参与度等
num_classes_interest = 3  # 学科兴趣类别数(只考虑语数英3)
num_classes_participation = 3  # 参与度类别数(只考虑语数英)

# 随机生成特征矩阵和边列表
x = torch.randn((num_students, num_features))
edge_index = torch.randint(0, num_students, (2, 200))  # 200条边

# 随机生成标签(实际中应根据数据生成)
# 回归任务
y_interest = torch.randn(num_students, num_classes_interest)  # 生成连续值
y_participation = torch.randn(num_students, num_classes_participation)  # 生成连续值

# 创建数据对象
data = Data(x=x, edge_index=edge_index, y_interest=y_interest, y_participation=y_participation)


# 根据打印一些示例数据
print("Interest Labels:", y_interest[:10])
print("Participation Values:", y_participation[:10])
print(data)

 2. 图数据集的构建

        可以继承自torch_geometric.data.Dataset,实现必要方法来定义和管理数据集。

import torch
from torch_geometric.data import Dataset, Data
import numpy as np

class CustomGraphDataset(Dataset):
    def __init__(self, root_dir, num_graphs, transform=None):
        """
        Args:
            root_dir (str): 存放数据的根目录
            num_graphs (int): 数据集的图数量
            transform (callable, optional): 可选的转换操作
        """
        self.root_dir = root_dir
        self.num_graphs = num_graphs
        self.transform = transform

    def len(self):
        return self.num_graphs  # 数据集中图的数量

    def get(self, idx):
        # 这个get方法模拟一个图的数据(可以根据具体问题从文件加载数据)
        num_nodes = 100  # 图中节点的数量
        num_edges = 200  # 图中边的数量
        
        # 随机生成节点特征 (num_nodes x num_features)
        node_features = torch.rand((num_nodes, 16))  # 假设每个节点有16维特征
        
        # 随机生成边列表 (2 x num_edges)
        edge_index = torch.randint(0, num_nodes, (2, num_edges))
        
        # 随机生成节点标签 (节点的分类标签)
        node_labels = torch.randint(0, 2, (num_nodes,))  # 假设有2类标签
        
        # 创建图数据对象
        data = Data(x=node_features, edge_index=edge_index, y=node_labels)
        
        # 如果有转换操作,应用转换
        if self.transform:
            data = self.transform(data)
        
        return data

三. 数据加载器

  torch-geometric 中的 DataLoader 可以直接用于 GNN 数据集的加载。你可以使用它来批量加载图数据,PyG 会自动处理批次中多个图的组合。

from torch_geometric.loader import DataLoader

# 假设有1000个图的数据集
train_dataset = CustomGraphDataset(root_dir="data/train", num_graphs=1000)

# 使用DataLoader加载数据集
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)

# 迭代训练数据
for data in train_loader:
    # data包含批量图的特征、边信息、标签等
    print(data.x.shape)  # (batch_size, num_nodes, node_feature_dim)
    print(data.edge_index.shape)  # (2, num_edges)
    print(data.y.shape)  # (batch_size, num_nodes)
    break  # 只打印第一个批次

五. 样本获取

1. 单一图获取读取

        训练需要时,直接调用就行了,像下面一样:

# 训练模型
def train(model, data, optimizer, loss_fn, epochs=200):
    for epoch in range(epochs):
        model.train()
        optimizer.zero_grad()

        # 前向传播
        out = model(data.x, data.edge_index)

        # 计算损失
        loss = loss_fn(out.view(-1), data.y)

        # 反向传播
        loss.backward()
        optimizer.step()

        if epoch % 20 == 0:
            print(f'Epoch {epoch}, Loss: {loss.item()}')

2. 数据集图读取

         用上面创建的CustomGraphDataset来举例,从文件中加载一个图,你可能会使用类似以下的代码来构建图数据:

import networkx as nx
from torch_geometric.utils import from_networkx

# 假设你有一个NetworkX图
G = nx.erdos_renyi_graph(n=100, p=0.1)  # 一个简单的随机图

# 设置节点特征
for i in G.nodes:
    G.nodes[i]['feature'] = np.random.rand(16)  # 16维特征

# 将NetworkX图转换为PyG数据对象
data = from_networkx(G)

# 假设节点分类任务
data.x = torch.tensor([G.nodes[i]['feature'] for i in G.nodes], dtype=torch.float)
data.y = torch.randint(0, 2, (data.x.size(0),))  # 随机节点标签


最后,

        后续多任务模型的实现,训练都会陆续更新,希望文章对您有所帮助! 


参考文章

Introduction by Example — pytorch_geometric documentationhttps://pytorch-geometric.readthedocs.io/en/latest/get_started/introduction.html#data-handling-of-graphshttps://pytorch-geometric.readthedocs.io/en/latest/get_started/introduction.html#data-handling-of-graphs

Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐