使用PYG库建立GCN网络进行多标签节点分类任务

本文将介绍如何使用PYG库建立GCN网络,并结合CNN进行特征降维,最终实现对节点标签的准确预测。

数据集描述:

  • 一共有42个时刻的图,边的连接关系相同。
  • 每个图都有37个节点。
  • 节点特征文件是'C:\Users\jh\Desktop\data\input\images\i.png_j.png'的所有图片的RGB像素值,其中'i'表示图,'i'从1到42,'j'表示节点,'j'从0到36。特征图片的尺寸为40 x 40。
  • 每个节点有8个标签,储存在'C:\Users\jh\Desktop\data\input\labels\i_j.txt'文本文件中,标签用空格隔开。
  • 边的关系储存在'C:\Users\jh\Desktop\data\input\edges_L.csv'csv文件中,表格中没有header,第一列为源节点,第二列为目标节点,共有61条无向边。

任务目标:

  • 建立一个CNN网络对节点像素特征x进行降维。
  • 使用前38个图作为训练集,剩下的4个图作为测试集。
  • 用测试集中的每个图的前30个节点预测其余的7个节点的标签。

模型架构:

  • 使用PYG库建立GCN网络实现多标签分类任务。
  • 损失函数由torch.nn模块中的MultiLabelSoftMarginLoss来实现。

代码实现:

import os
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import transforms
from torch_geometric.data import Data, Dataset
from torch_geometric.nn import GCNConv
from torch_geometric.transforms import NormalizeFeatures

# Define the CNN model for feature dimension reduction
class CNNModel(nn.Module):
    def __init__(self):
        super(CNNModel, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, 3, stride=1, padding=1)
        self.pool1 = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(16, 32, 3, stride=1, padding=1)
        self.pool2 = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(10 * 10 * 32, 128)
        self.fc2 = nn.Linear(128, 64)
    
    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.relu(self.conv2(x)))
        x = x.view(-1, 10 * 10 * 32)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# Define the GCN model for multi-label classification
class GCNModel(nn.Module):
    def __init__(self, num_features, num_classes):
        super(GCNModel, self).__init__()
        self.conv1 = GCNConv(num_features, 64)
        self.conv2 = GCNConv(64, num_classes)
    
    def forward(self, x, 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 x

# Define the dataset class
class CustomDataset(Dataset):
    def __init__(self, root, transform=None):
        self.root = root
        self.transform = transform
        self.data = self.process_data()
    
    def process_data(self):
        data = []
        for i in range(1, 43):
            # Load node features
            features_path = os.path.join(self.root, f'images/{i}.png')
            features = self.load_features(features_path)
            
            # Load node labels
            labels_path = os.path.join(self.root, f'labels/{i}_j.txt')
            labels = self.load_labels(labels_path)
            
            # Load edge connections
            edges_path = os.path.join(self.root, 'edges_L.csv')
            edges = self.load_edges(edges_path)
            
            data.append(Data(x=features, y=labels, edge_index=edges))
        
        return data
    
    def load_features(self, path):
        image = Image.open(path)
        if self.transform is not None:
            image = self.transform(image)
        return image
    
    def load_labels(self, path):
        with open(path, 'r') as file:
            labels = file.read().strip().split()
        labels = [int(label) for label in labels]
        return torch.tensor(labels)
    
    def load_edges(self, path):
        edges = []
        with open(path, 'r') as file:
            lines = file.readlines()
            for line in lines:
                source, target = line.strip().split(',')
                edges.append((int(source), int(target)))
        edges = torch.tensor(edges).t().contiguous()
        return edges
    
    def __len__(self):
        return len(self.data)
    
    def __getitem__(self, idx):
        return self.data[idx]

# Initialize the CNN model
cnn_model = CNNModel()

# Initialize the GCN model
gcn_model = GCNModel(64, 8)

# Define the loss function
loss_fn = nn.MultiLabelSoftMarginLoss()

# Define the optimizer
optimizer = optim.Adam(gcn_model.parameters(), lr=0.01)

# Define the data transformations
data_transform = transforms.Compose([
    transforms.Resize((40, 40)),
    transforms.ToTensor()
])

# Load the training and testing datasets
train_dataset = CustomDataset('C:/Users/jh/Desktop/data/input', transform=data_transform)
test_dataset = CustomDataset('C:/Users/jh/Desktop/data/input', transform=data_transform)

# Split the training and testing datasets
train_dataset = train_dataset[:38]
test_dataset = test_dataset[38:]

# Define the data loaders
train_loader = DataLoader(train_dataset, batch_size=1, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=1, shuffle=False)

# Train the model
for epoch in range(10):
    gcn_model.train()
    for data in train_loader:
        optimizer.zero_grad()
        
        # Forward pass through CNN
        features = cnn_model(data.x)
        
        # Forward pass through GCN
        output = gcn_model(features, data.edge_index)
        
        # Calculate loss
        loss = loss_fn(output, data.y.float())
        
        # Backward pass and optimization
        loss.backward()
        optimizer.step()
    
    # Evaluate the model
    gcn_model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_loader:
            features = cnn_model(data.x)
            output = gcn_model(features, data.edge_index)
            predicted_labels = torch.sigmoid(output) > 0.5
            correct += (predicted_labels == data.y).sum().item()
            total += data.y.size(0) * data.y.size(1)
    
    accuracy = correct / total
    print(f'Epoch {epoch+1}, Accuracy: {accuracy}')

代码说明:

  1. CNNModel: 定义了一个简单的CNN模型,用于对节点特征进行降维。
  2. GCNModel: 定义了一个GCN模型,用于进行多标签节点分类。
  3. CustomDataset: 自定义了一个Dataset类,用于加载数据集。
  4. 训练过程: 使用DataLoader加载训练集和测试集,并使用循环进行训练和评估。

注意:

  • 请确保已经安装了以下库:torch, torchvision, torch_geometric。
  • 数据集路径请根据实际情况进行修改。
  • 代码中使用的模型和参数仅供参考,您可以根据实际情况进行调整。

总结:

本文介绍了使用PYG库建立GCN网络进行多标签节点分类任务的完整流程,并提供了相应的代码示例。通过使用CNN进行特征降维,可以有效地提高GCN模型的性能。该方法可以应用于各种图数据分析任务,例如社交网络分析、蛋白质相互作用网络分析等。

使用PYG库建立GCN网络进行多标签节点分类任务

原文地址: https://www.cveoy.top/t/topic/pf5M 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录