图神经网络与 Transformer 多模型对比实战:从数据处理到结果分析全流程

在机器学习与深度学习领域,模型的选择与对比是优化算法性能的关键环节。本文将基于 Python 和 PyTorch 框架,结合torch_geometric库,详细展示图卷积网络(GCN)、图注意力网络(GAT)、视觉 Transformer(ViT)以及混合模型(Hybrid)的完整实现过程。从数据加载、模型定义、训练评估到结果保存,每一步都提供可复用的代码,适合算法研究、学术论文写作和工程实践参考。

数据参考(注意:直接用链接中的数据替换):https://download.csdn.net/download/lestatlu/90690594

一、环境配置与基础库导入

在开始代码编写之前,需要导入必要的库,并完成设备选择(优先使用 GPU 加速)。

import time
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import pandas as pd
from torch_geometric.nn import GCNConv, GATConv
from torch_geometric.data import Data
from sklearn.neighbors import kneighbors_graph
from sklearn.metrics import accuracy_score, classification_report, recall_score, precision_score, cohen_kappa_score
from torch.nn import TransformerEncoder, TransformerEncoderLayer

# 设备选择
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
start_time = time.time()

上述代码中,torch.device用于自动检测并选择可用的计算设备(GPU 或 CPU),time.time()用于记录程序运行总时长,方便后续性能评估。

二、数据加载与预处理

数据是模型训练的基础,本案例假设已有预处理好的特征数据和标签数据,需进行划分和格式转换。

# 加载数据
X_all_samples = np.load(r'your_path/X_all_samples.npy')
y_all_samples = np.load(r'your_path/y_all_samples.npy')
train_indices = np.load(r'your_path/global_train_indices.npy')
test_indices = np.load(r'your_path/global_test_indices.npy')

# 创建训练集和测试集
X_train = X_all_samples[train_indices]
y_train = y_all_samples[train_indices]
X_test = X_all_samples[test_indices]
y_test = y_all_samples[test_indices]

y_train = y_train.astype(np.int64)
y_test = y_test.astype(np.int64)
num_classes = np.max(y_train.astype(np.int64)) + 1
# 验证类别数一致性
assert np.max(y_train) + 1 == num_classes, "类别数不一致"

# 转换为Tensor
x_train = torch.tensor(X_train, dtype=torch.float32, device=device)
y_train_tensor = torch.tensor(y_train, dtype=torch.long, device=device)
x_test = torch.tensor(X_test, dtype=torch.float32, device=device)
y_test_tensor = torch.tensor(y_test, dtype=torch.long, device=device)

关键步骤解析

  1. 使用np.load加载本地保存的 Numpy 数组数据,你需要将your_path替换为实际的数据存储路径。
  2. 通过索引划分训练集和测试集,并将标签数据类型转换为np.int64,确保与 PyTorch 的torch.long类型兼容。
  3. 将 Numpy 数组转换为torch.Tensor,并移动到选定的计算设备(GPU 或 CPU)上。

构建图结构

对于 GCN 和 GAT 模型,需要构建图结构数据,这里采用 K 近邻算法生成邻接关系。

# 构建图结构
knn_graph = kneighbors_graph(x_train.cpu().numpy(), n_neighbors=5, mode='connectivity', include_self=True)
edge_index = torch.tensor(knn_graph.nonzero(), dtype=torch.long).to(device)
train_data = Data(x=x_train, edge_index=edge_index)

knn_graph_test = kneighbors_graph(x_test.cpu().numpy(), n_neighbors=5, mode='connectivity', include_self=True)
edge_index_test = torch.tensor(knn_graph_test.nonzero(), dtype=torch.long).to(device)
test_data = Data(x=x_test, edge_index=edge_index_test)

核心逻辑

  • kneighbors_graph函数根据特征数据计算每个样本的 K 近邻关系(这里n_neighbors = 5表示每个样本连接 5 个最近邻)。
  • 将邻接关系转换为torch.Tensor格式,并与特征数据封装成torch_geometric.data.Data对象,满足图神经网络输入要求。

三、模型定义

3.1 图卷积网络(GCN)

class GCNModel(nn.Module):
    def __init__(self, input_dim, output_dim, hidden_dim=256, num_layers=3):
        super().__init__()
        self.convs = nn.ModuleList([GCNConv(input_dim, hidden_dim)])
        for _ in range(num_layers - 1):
            self.convs.append(GCNConv(hidden_dim, hidden_dim))
        self.fc_out = nn.Linear(hidden_dim, output_dim)

    def forward(self, data):
        x, edge_index = data.x, data.edge_index
        for conv in self.convs:
            x = conv(x, edge_index).relu()
        return self.fc_out(x)

模型架构

  • 通过nn.ModuleList堆叠多个GCNConv层,逐步提取图数据的特征。
  • 最后由全连接层fc_out输出分类结果。

3.2 图注意力网络(GAT)

class GATModel(nn.Module):
    def __init__(self, input_dim, output_dim, hidden_dim=256, heads=4, num_layers=3):
        super().__init__()
        self.convs = nn.ModuleList([GATConv(input_dim, hidden_dim, heads=heads)])
        for _ in range(num_layers - 1):
            self.convs.append(GATConv(hidden_dim * heads, hidden_dim, heads=heads))
        self.fc_out = nn.Linear(hidden_dim * heads, output_dim)

    def forward(self, data):
        x, edge_index = data.x, data.edge_index
        for conv in self.convs:
            x = conv(x, edge_index).relu()
        return self.fc_out(x)

关键特性

  • GATConv层引入注意力机制,增强模型对图结构中节点关系的捕捉能力。
  • 多头注意力机制(heads参数)进一步提升特征表达能力。

3.3 视觉 Transformer(ViT)

class ViTModel(nn.Module):
    def __init__(self, input_dim, output_dim, hidden_dim=256, num_layers=3, num_heads=4):
        super().__init__()
        self.proj = nn.Linear(input_dim, hidden_dim)
        self.pos_embed = nn.Parameter(torch.randn(1, hidden_dim))
        encoder_layer = TransformerEncoderLayer(hidden_dim, num_heads, hidden_dim * 4)
        self.transformer = TransformerEncoder(encoder_layer, num_layers)
        self.fc_out = nn.Linear(hidden_dim, output_dim)

    def forward(self, data):
        x = self.proj(data.x) + self.pos_embed
        x = x.unsqueeze(1).permute(1, 0, 2)
        x = self.transformer(x)
        return self.fc_out(x.squeeze(0))

设计要点

  • proj层将输入特征映射到 Transformer 所需的维度。
  • pos_embed添加位置编码,弥补 Transformer 对序列顺序信息的缺失。
  • TransformerEncoder层通过多头注意力和前馈网络进行特征提取。

3.4 混合模型(Hybrid)

class HybridModel(nn.Module):
    def __init__(self, input_dim, output_dim, cnn_dim=64, trans_dim=128, num_heads=2, num_layers=3):
        super().__init__()
        self.cnn = nn.Sequential(
            nn.Conv1d(1, cnn_dim, 3, padding=1),
            nn.ReLU(),
            nn.MaxPool1d(2),
            nn.Conv1d(cnn_dim, cnn_dim * 2, 3, padding=1),
            nn.ReLU(),
            nn.MaxPool1d(2)
        )
        self.cnn_out_dim = cnn_dim * 2 * (input_dim // 4)
        self.proj = nn.Linear(self.cnn_out_dim, trans_dim)
        encoder_layer = TransformerEncoderLayer(trans_dim, num_heads, trans_dim * 4)
        self.transformer = TransformerEncoder(encoder_layer, num_layers)
        self.fc_out = nn.Linear(trans_dim, output_dim)

    def forward(self, data):
        x = data.x.unsqueeze(1)
        x = self.cnn(x).view(x.size(0), -1)
        x = self.proj(x).unsqueeze(1).permute(1, 0, 2)
        x = self.transformer(x)
        return self.fc_out(x.squeeze(0))

创新融合

  • 结合 1D 卷积神经网络(CNN)和 Transformer,先通过 CNN 提取局部特征。
  • 再利用 Transformer 进行全局特征学习,实现优势互补。

四、训练与评估函数

def train_evaluate(model, model_name, train_data, test_data, y_train, y_test):
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    criterion = nn.CrossEntropyLoss()

    # 训练循环
    model.train()
    for epoch in range(1000):
        optimizer.zero_grad()
        out = model(train_data)
        loss = criterion(out, y_train)
        loss.backward()
        optimizer.step()

    # 评估
    model.eval()
    with torch.no_grad():
        pred = model(test_data).argmax(dim=1).cpu().numpy()
    true = y_test.cpu().numpy()

    metrics = {
        "OA (%)": accuracy_score(true, pred) * 100,
        "AA (%)": recall_score(true, pred, average='macro') * 100,
        "Kappa": cohen_kappa_score(true, pred),
    }
    pa = precision_score(true, pred, average=None) * 100
    for i, p in enumerate(pa):
        metrics[f"PA_Class_{i} (%)"] = p
    return metrics

核心流程

  1. 使用 Adam 优化器和交叉熵损失函数进行模型训练。
  2. 训练完成后,在测试集上进行评估,计算总体精度(OA)、宏平均召回率(AA)、Kappa 系数以及每个类别的精度(PA)。

五、主流程与结果保存

model_classes = [
    ("GCN", GCNModel),
    ("GAT", GATModel),
    ("ViT", ViTModel),
    ("Hybrid", HybridModel)
]

results = {name: [] for name, _ in model_classes}

# 训练评估所有模型
for name, model_cls in model_classes:
    model = model_cls(
        input_dim=x_train.shape[1],
        output_dim=num_classes
    ).to(device)
    fold_metrics = train_evaluate(model, name, train_data, test_data, y_train_tensor, y_test_tensor)
    results[name].append(fold_metrics)
    del model
    torch.cuda.empty_cache()

# 结果统计与保存
final_results = []
for model_name, metrics_list in results.items():
    df = pd.DataFrame(metrics_list)
    mean = df.mean()
    std = df.std()

    result_row = {"Method": model_name}
    for col in df.columns:
        result_row[f"{col} Mean"] = round(mean[col], 2)
        result_row[f"{col} Std"] = round(std[col], 2)
    final_results.append(result_row)

results_df = pd.DataFrame(final_results)
results_df.to_excel("all.xlsx", index=False)
print("\n结果已保存至 all.xlsx")
print(f"总运行时间: {time.time() - start_time:.2f}秒")

执行逻辑

  1. 循环遍历所有模型类,实例化模型并进行训练和评估。
  2. 统计每个模型的评估指标均值和标准差,并保存到 Excel 文件中。
  3. 打印总运行时间,方便对比不同模型的训练效率。数据参考(注意:直接用链接中的数据替换):https://download.csdn.net/download/lestatlu/90690594
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI_RSER

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值