【无废话纯干货,代码直接运行成功】Python实现Cora数据集训练图卷积神经网络(GCN)

本博文旨在直接提供一个可用于最新版本Python和Pycharm的GCN代码
首先,附上GCN原始论文链接和code链接
论文: https://arxiv.org/pdf/1609.02907.pdf
code: https://github.com/tkipf/gcn
既然作者们提供了GCN的python代码,为什么我还要写这个博客呢?
原因在于该论文发表于2017年,其原始代码所调用的库与当前的Python以及Pycharm版本已经不兼容,而且代码内部涉及到命令行参数等与模型或算法本身并不必要的编程内容,为了避免铁子们像我一样哼哧哼哧地下载完代码然后报错一直修改,满脸狰狞地敲着键盘,特提供如下所示的全新的、验证过的流畅代码!

import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
from torch_geometric.datasets import Planetoid

# 定义GCN模型
class GCN(torch.nn.Module):
    def __init__(self, num_features, hidden_channels, num_classes):
        super(GCN, self).__init__()  # 调用父类(torch.nn.Module)的构造函数
        self.conv1 = GCNConv(num_features, hidden_channels)  # 第一层图卷积层,输入特征到隐藏层
        self.conv2 = GCNConv(hidden_channels, num_classes)  # 第二层图卷积层,隐藏层到输出层(类别数)

    def forward(self, data):
        x, edge_index = data.x, data.edge_index  # 从data对象中解包节点特征和边索引

        # 第一层图卷积并激活
        x = self.conv1(x, edge_index)  # 应用第一层图卷积
        x = F.relu(x)  # 应用ReLU激活函数
        x = F.dropout(x, training=self.training)  # 可选:在训练模式下应用dropout

        # 第二层图卷积
        x = self.conv2(x, edge_index)  # 应用第二层图卷积

        return F.log_softmax(x, dim=1)  # 返回对数概率,用于分类任务的损失计算


# 加载数据集
dataset = Planetoid(root='/tmp/Cora', name='Cora')  # 加载Cora数据集,并指定数据集存储路径和名称

# 初始化模型
model = GCN(num_features=dataset.num_node_features,  # 节点特征的数量
            hidden_channels=16,  # 隐藏层的节点数(或特征数)
            num_classes=dataset.num_classes)  # 输出的类别数

# 数据准备(这里只是简单地从数据集中取出一个图,实际上Cora数据集包含多个图)
data = dataset[0]  # Cora数据集通常包含多个图,这里只取第一个图进行演示

# 定义优化器
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)  # 使用Adam优化器

# 训练模型
model.train()  # 设置模型为训练模式
for epoch in range(200):  # 训练200个epoch
    optimizer.zero_grad()  # 清空过往梯度
    out = model(data)  # 前向传播,获取模型输出
    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])  # 计算损失(仅针对训练节点)
    loss.backward()  # 反向传播,计算梯度
    optimizer.step()  # 更新模型参数

    if epoch % 10 == 0:  # 每10个epoch打印一次损失
        print(f'Epoch {epoch + 1}, Loss: {loss.item()}')

    # 评估模型
model.eval()  # 设置模型为评估模式
_, pred = model(data).max(dim=1)  # 前向传播,并获取概率最高的类别的索引作为预测结果
correct = int(pred[data.test_mask].eq(data.y[data.test_mask]).sum().item())  # 计算测试集上的正确预测数
accuracy = correct / int(data.test_mask.sum())  # 计算准确率
print(f'Accuracy: {accuracy:.4f}')  # 打印准确率

本着先跑通的初衷,该代码只使用了一个隐含层,较为简单。下一期我会再写文章,详细讲一讲GCN的运作机理以及数学原理,并附上实验结果。下下一期,将对该模型做出修改,如调整dropout、增加隐含层、测试超参数敏感度,并提高其泛化性能。(是的,处女座就是很爱画饼~~~~~)
哦对啦,跑代码之前,先在terminal输入(-i https://pypi.tuna.tsinghua.edu.cn/simple为清华的镜像源,增强稳定性、均衡负载):

pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install torch_geometric -i https://pypi.tuna.tsinghua.edu.cn/simple

此外,如果出现numpy版本不兼容的问题,记得再输入:

pip install numpy==2.0

或者

pip install numpy<2.0

完毕!
我们~
下期见。
(运行结果:
请添加图片描述

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一份使用PyTorch实现12层ResGCNcora数据集进行训练和测试的代码: 首先,需要引入必要的库和包: ```python import torch import torch.nn as nn import torch.nn.functional as F from torch_geometric.nn import GCNConv from torch_geometric.datasets import Planetoid ``` 然后,定义ResGCN模型,包括ResGCN层和一个全连接层: ```python class ResGCN(nn.Module): def __init__(self, in_channels, out_channels): super(ResGCN, self).__init__() self.conv1 = GCNConv(in_channels, out_channels) self.conv2 = GCNConv(out_channels, out_channels) self.res_conv = GCNConv(in_channels, out_channels) self.fc = nn.Linear(out_channels, 7) def forward(self, x, edge_index): res = self.res_conv(x, edge_index) x = self.conv1(x, edge_index) x = F.relu(x) x = self.conv2(x, edge_index) x = x + res x = F.relu(x) x = self.fc(x) return F.log_softmax(x, dim=1) ``` 接着,加载cora数据集: ```python dataset = Planetoid(root='/tmp/Cora', name='Cora') data = dataset[0] ``` 然后,定义模型和优化器: ```python device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = ResGCN(dataset.num_features, 64).to(device) optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4) ``` 接下来,定义训练函数和测试函数: ```python def train(): model.train() optimizer.zero_grad() out = model(data.x.to(device), data.edge_index.to(device)) loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask].to(device)) loss.backward() optimizer.step() return loss.item() def test(): model.eval() out = model(data.x.to(device), data.edge_index.to(device)) pred = out.argmax(dim=1) test_correct = pred[data.test_mask] == data.y[data.test_mask].to(device) test_acc = int(test_correct.sum()) / int(data.test_mask.sum()) return test_acc ``` 最后,进行训练和测试,并输出测试准确率: ```python for epoch in range(1, 101): loss = train() test_acc = test() print('Epoch: {:03d}, Loss: {:.4f}, Test Acc: {:.4f}'.format(epoch, loss, test_acc)) ``` 完整代码如下:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值