GNN多任务预测模型实现(一):创建图数据

目录

一. 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

下面是个使用 PyTorch Geometric 库实现 GNN 级任务的代码示例,包括数据集的随机生成、模型定义、训练和验证。 首先,我们需要安装 PyTorch Geometric 库: ```python pip install torch-geometric ``` 然后,我们可以使用以下代码生成个随机的图数据集: ```python import torch from torch_geometric.data import Data # 生成个包含 10 个节点和 20 条边的随机 x = torch.randn(10, 5) # 节点特征 edge_index = torch.randint(0, 10, (2, 20)) # 边索引 y = torch.randint(0, 3, (1, 10)).squeeze() # 级标签 data = Data(x=x, edge_index=edge_index, y=y) ``` 接下来,我们可以定义GNN 模型,并在数据集上进行训练和验证。这里我们使用了个简单的 GCN 模型: ```python import torch.nn.functional as F from torch_geometric.nn import GCNConv class GCN(torch.nn.Module): def __init__(self): super(GCN, self).__init__() self.conv1 = GCNConv(5, 16) self.conv2 = GCNConv(16, 3) def forward(self, data): x, edge_index = data.x, data.edge_index x = F.relu(self.conv1(x, edge_index)) x = self.conv2(x, edge_index) return F.log_softmax(x, dim=1) # 创建模型和优化器 model = GCN() optimizer = torch.optim.Adam(model.parameters(), lr=0.01) # 训练模型 model.train() for epoch in range(100): optimizer.zero_grad() out = model(data) loss = F.nll_loss(out, data.y) loss.backward() optimizer.step() # 验证模型 model.eval() with torch.no_grad(): pred = model(data).argmax(dim=1) acc = (pred == data.y).sum().item() / len(data.y) print(f"Accuracy: {acc:.3f}") ``` 这段代码将随机生成的图数据集输入到 GCN 模型中,并使用交叉熵损失进行训练。在训练结束后,我们使用 argmax 函数获取每个的预测标签,并计算模型的准确率。 注意,这里的数据集只是个示例,实际应用中需要根据具体需求生成更加真实的图数据集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值