栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

手撸GCN

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

手撸GCN

今天周六,不是很想看论文,于是自己动手把几种GNN手撸一遍,GCN的代码如下:

1. 得到数据

这里我使用的是经典的Cora数据集,用于进行节点分类,我是直接使用的PyG中提供的数据集,节点特征、节点标签、训练集测试集都可以直接调用:

from torch_geometric.datasets import Planetoid
import torch

# 使用PyG提供的数据集,懒得自己写解析规则
# 这一步如果下载不下来亲测开个VPN就行了
dataset = Planetoid(root='../data/Cora', name='Cora')
data = dataset[0]

# 得到边的index,shape:[2,E]
edge_index=data.edge_index

# 这几步是为邻接矩阵加上自连接,并且进行行归一化
adj_coo=torch.sparse_coo_tensor(edge_index,torch.ones(edge_index.shape[1]),size=(data.num_nodes,data.num_nodes))
adj=adj_coo.to_dense()
D=torch.diag(torch.pow(adj.sum(dim=1),-1))
adj=torch.mm(D,adj)

# 将邻接矩阵表示为torch sparse矩阵,加快计算,减少内存
adj=adj.to_sparse()
2.定义GCN中的一层
import torch
import torch.nn as nn
import torch.nn.functional as F

# 定义GCN中的一层
class GCNLayer(nn.Module):
    def __init__(self, in_features, out_features):
        super(GCNLayer, self).__init__()
        self.W = nn.Parameter(torch.zeros([in_features, out_features]))
        self.init_parameters()

    def init_parameters(self):
        self.W.data.uniform_(0, 1)

    def forward(self,H:torch.Tensor,adj:torch.Tensor):
        # H^(l+1)=AH^(l)W^(l)
        H=torch.mm(H,self.W)
        H=torch.mm(adj,H)
        return F.relu(H)
3. 定义两层GCN模型
import torch.nn as nn
import torch.nn.functional as F

from layers import GCNLayer


# 定义一个两层的GCN
class GCN_NET(nn.Module):
    def __init__(self, num_input, num_hidden, num_classes, dropout=0.5):
        super(GCN_NET, self).__init__()
        self.gcn1 = GCNLayer(num_input, num_hidden)
        self.gcn2 = GCNLayer(num_hidden, num_classes)
        self.dropout = dropout

    def forward(self, X, adj):
        H = self.gcn1(X, adj)
        H = F.dropout(H, self.dropout,training=self.training)
        H = self.gcn2(H, adj)
        return F.log_softmax(H, dim=1)

4.训练模型
from data import adj, data, dataset
from model import GCN_NET
from torch.optim import Adam
import torch.nn.functional as F

# 初始特征,节点标签
features, labels = data.x, data.y
# 初始化模型
model = GCN_NET(data.num_features, 16, dataset.num_classes,dropout=0.2)
# 定义优化器
optimizer = Adam(model.parameters(),lr=1e-2,weight_decay=5e-4)
# 最大迭代次数
epoches = 200

# 将self.training设置为True,可以dropout
model.train()
for epoch in range(epoches):
    predict_label = model(features, adj)
    loss = F.cross_entropy(predict_label[data.train_mask], labels[data.train_mask])
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

# 将self.training设置为false,不允许dropout
model.eval()
predict_label = model(features, adj).max(dim=1).indices
acc_num = predict_label[data.test_mask].eq(labels[data.test_mask]).sum()
print('accuracy:', acc_num / data.test_mask.sum())

训练完成,精确度0.803

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/329647.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号