DGL节点分类【官网的例子】

官网: https://docs.dgl.ai/tutorials/blitz/1_introduction.html#sphx-glr-tutorials-blitz-1-introduction-py
论文地址
点击跳转
参考文章:https://aistudio.baidu.com/projectdetail/2246479?shared=1

Cora 数据集介绍

Cora数据集包含2708篇科学出版物, 5429条边,总共7种类别。数据集中的每个出版物都由一个 0/1 值的词向量描述,表示字典中相应词的缺失/存在。 该词典由 1433 个独特的词组成。意思就是说每一个出版物都由1433个特征构成,每个特征仅由0/1表示。

  • NumNodes: 2708。表示图中有2708个节点
  • NumEdges: 10556。图中有10556条边。看其他说有5429条边但是dgl官网这个例子上显示10556。
  • NumFeats: 1433。每个节点具有1433个特征。
  • NumClasses: 7。数据集中的目标分类数为7。
  • NumTrainingSamples: 140。训练样本数量为140。
  • NumValidationSamples: 500。验证样本数量为500。
  • NumTestSamples: 1000。测试样本数量为1000。

在这里插入图片描述

  • ind.cora.x : 训练集节点特征向量,保存对象为:scipy.sparse.csr.csr_matrix,实际展开后大小为: (140, 1433)
  • ind.cora.tx : 测试集节点特征向量,保存对象为:scipy.sparse.csr.csr_matrix,实际展开后大小为: (1000, 1433)
  • ind.cora.allx : 包含有标签和无标签的训练节点特征向量,保存对象为:scipy.sparse.csr.csr_matrix,实际展开后大小为:(1708, 1433),可以理解为除测试集以外的其他节点特征集合,训练集是它的子集
  • ind.cora.y : one-hot表示的训练节点的标签,保存对象为:numpy.ndarray
  • ind.cora.ty : one-hot表示的测试节点的标签,保存对象为:numpy.ndarray
  • ind.cora.ally : one-hot表示的ind.cora.allx对应的标签,保存对象为:numpy.ndarray
  • ind.cora.graph : 保存节点之间边的信息,保存格式为:{ index : [ index_of_neighbor_nodes ] }
  • ind.cora.test.index : 保存测试集节点的索引,保存对象为:List,用于后面的归纳学习设置。

一些细节解释

import os
os.environ["DGLBACKEND"] = "pytorch"#设置环境变量以选择后端框架为PyTorch的方式
import dgl
import dgl.data
import torch
import torch.nn as nn
import torch.nn.functional as F

dataset = dgl.data.CoraGraphDataset()
#用于加载Cora数据集。CoraGraphDataset函数会自动下载并处理Cora数据集,使其转换成适合图神经网络处理的格式。
#这个还会自动的输出关于该数据库的描述例如:点的数量,边的数量等等
print(f"Number of categories: {dataset.num_classes}")#输出Cora数据集中类别的总数。
g = dataset[0]
#一个DGL数据集对象可能包含一个或多个图表。本教程中使用的Cora数据集仅包含一个图表。
print("Node features")
print(g.ndata)
print(len(g.ndata))
for i in g.ndata.keys():
    print(i)
for i in g.ndata.values():
    print(i,len(i))

输出结果:

  NumNodes: 2708
  NumEdges: 10556
  NumFeats: 1433
  NumClasses: 7
  NumTrainingSamples: 140
  NumValidationSamples: 500
  NumTestSamples: 1000
Done loading data from cached files.
Number of categories: 7
Node features
{'train_mask': tensor([ True,  True,  True,  ..., False, False, False]), 'label': tensor([3, 4, 4,  ..., 3, 3, 3]), 'val_mask': tensor([False, False, False,  ..., False, False, False]), 'test_mask': tensor([False, False, False,  ...,  True,  True,  True]), 'feat': tensor([[0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        ...,
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.]])}
5
train_mask
label
val_mask
test_mask
feat
tensor([ True,  True,  True,  ..., False, False, False]) 2708
tensor([3, 4, 4,  ..., 3, 3, 3]) 2708
tensor([False, False, False,  ..., False, False, False]) 2708
tensor([False, False, False,  ...,  True,  True,  True]) 2708
tensor([[0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        ...,
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.]]) 2708

进程已结束,退出代码为 0

从上面可以看到该数据集的点的特征名称有5个。
需要注意的是,当运行数据集加载代码的时候会自动生成两个文件。
在这里插入图片描述
当您运行上述代码,加载Cora数据集时,DGL会自动下载原始数据文件,并在本地处理这些数据以构建图结构。处理完成后,为了提高未来加载数据的效率,DGL会将处理后的图数据保存到本地文件系统中。这就是cora_v2_dgl_graph.bin和cora_v2_dgl_graph.pkl文件的作用。

  • cora_v2_dgl_graph.bin: 这个文件包含了处理后的Cora图数据的二进制表示。具体来说,它保存了图的结构(节点和边的信息)以及节点和边的特征数据。使用二进制格式可以有效地压缩数据大小,并加快数据的加载速度。
  • cora_v2_dgl_graph.pkl: 这个文件是一个Pickle格式的文件,通常用于保存Python对象。在这个上下文中,它可能被用来存储与图相关的额外信息,例如数据集的元数据(如类别标签的映射)。然而,具体存储哪些信息可能取决于DGL的版本和数据集的实现细节。

这两个文件使得在您下次需要加载Cora数据集时,DGL可以直接从这些本地文件中读取处理好的图数据,而无需重新执行下载和处理的步骤。这大大减少了数据准备的时间,特别是在进行多次实验或模型训练时。

import os
os.environ["DGLBACKEND"] = "pytorch"#设置环境变量以选择后端框架为PyTorch的方式
import dgl
import dgl.data
import torch
import torch.nn as nn
import torch.nn.functional as F

dataset = dgl.data.CoraGraphDataset()
#用于加载Cora数据集。CoraGraphDataset函数会自动下载并处理Cora数据集,使其转换成适合图神经网络处理的格式。
#这个还会自动的输出关于该数据库的描述例如:点的数量,边的数量等等
print(f"Number of categories: {dataset.num_classes}")#输出Cora数据集中类别的总数。
g = dataset[0]
#一个DGL数据集对象可能包含一个或多个图表。本教程中使用的Cora数据集仅包含一个图表。
print("Edge features")
print(g.edata)

在这里插入图片描述
上图说明了边没有特征。
在这里插入图片描述
可以看到一共2708个点每一个点的特征维度是1433。

总代码

import os
os.environ["DGLBACKEND"] = "pytorch"#设置环境变量以选择后端框架为PyTorch的方式
import dgl
import dgl.data
import torch
import torch.nn as nn
import torch.nn.functional as F

dataset = dgl.data.CoraGraphDataset()
#用于加载Cora数据集。CoraGraphDataset函数会自动下载并处理Cora数据集,使其转换成适合图神经网络处理的格式。
#这个还会自动的输出关于该数据库的描述例如:点的数量,边的数量等等
print(f"Number of categories: {dataset.num_classes}")#输出Cora数据集中类别的总数。
g = dataset[0]
#一个DGL数据集对象可能包含一个或多个图表。本教程中使用的Cora数据集仅包含一个图表。
print("Node features")
print(g.ndata)
print("Edge features")
print(g.edata)


from dgl.nn import GraphConv


class GCN(nn.Module):
    def __init__(self, in_feats, h_feats, num_classes):
        super(GCN, self).__init__()
        self.conv1 = GraphConv(in_feats, h_feats)
        self.conv2 = GraphConv(h_feats, num_classes)

    def forward(self, g, in_feat):#刚开始的in_feat是(2708,1433)
        h = self.conv1(g, in_feat)#(2708,16)
        h = F.relu(h)
        h = self.conv2(g, h)#(2708,7)
        return h

model = GCN(g.ndata["feat"].shape[1], 16, dataset.num_classes)#1433,16,7

def train(g, model):
    optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
    best_val_acc = 0
    best_test_acc = 0

    features = g.ndata["feat"]#(2708,1433)
    labels = g.ndata["label"]#(2708),其中labels的每一个值在[0-6]之间代表其所属的类
    train_mask = g.ndata["train_mask"]#(2708)
    val_mask = g.ndata["val_mask"]#(2708)
    test_mask = g.ndata["test_mask"]#(2708)
    for e in range(100):
        # Forward
        logits = model(g, features)#logits的维度(2708,7)
        # Compute prediction
        pred = logits.argmax(1)#每一行找到最大值的索引.(2708)
        # Compute loss
        # Note that you should only compute the losses of the nodes in the training set.
        loss = F.cross_entropy(logits[train_mask], labels[train_mask])
        #根据train_mask和train_mask取出训练好的预测标签和其真正对应的标签计算交叉熵损失
        # Compute accuracy on training/validation/test
        train_acc = (pred[train_mask] == labels[train_mask]).float().mean()
        #将预测标签和真的标签对比一样就是True,否则就是False,将其转换成浮点数,计算均值其实就是其准确率
        #需要注意的是这里训练是所有的点都进入网络,但是只有训练集才更新其参数
        val_acc = (pred[val_mask] == labels[val_mask]).float().mean()
        test_acc = (pred[test_mask] == labels[test_mask]).float().mean()

        # Save the best validation accuracy and the corresponding test accuracy.
        if best_val_acc < val_acc:
            best_val_acc = val_acc
            best_test_acc = test_acc

        # Backward
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if e % 5 == 0:
            print(
                f"In epoch {e}, loss: {loss:.3f}, val acc: {val_acc:.3f} (best {best_val_acc:.3f}), test acc: {test_acc:.3f} (best {best_test_acc:.3f})"
            )


model = GCN(g.ndata["feat"].shape[1], 16, dataset.num_classes)
train(g, model)

print(dgl.backend.backend_name)  # 应该输出 'pytorch'
######################################################################
# Training on GPU
# ---------------
#
# Training on GPU requires to put both the model and the graph onto GPU
# with the ``to`` method, similar to what you will do in PyTorch.
#
# .. code:: python
#
#    g = g.to('cuda')
#    model = GCN(g.ndata['feat'].shape[1], 16, dataset.num_classes).to('cuda')
#    train(g, model)
#

需要注意的一个点:
在图神经网络(GNN)中,确保只有训练集参与反向传播的关键在于损失函数的计算。具体来说,虽然整个图的所有节点都参与前向传播过程,以便节点可以接收来自其邻居的信息,但在计算损失和进行反向传播时,只考虑训练集中的节点。这是通过使用所谓的“掩码”(mask)操作来实现的。

 loss = F.cross_entropy(logits[train_mask], labels[train_mask])
 这里只是用训练集来计算损失,计算得到的损失仅基于训练集,反向传播过程(loss.backward())也因此只会更新这部分数据对应的模型参数梯度。

可以打印参数看一下
在这里插入图片描述

  • 24
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是一个简单的图神经网络节点分类的代码示例: ```python import torch import torch.nn.functional as F from torch_geometric.nn import GCNConv class GCN(torch.nn.Module): def __init__(self, num_features, num_classes): super(GCN, self).__init__() self.conv1 = GCNConv(num_features, 16) self.conv2 = GCNConv(16, num_classes) def forward(self, x, edge_index): x = F.relu(self.conv1(x, edge_index)) x = F.dropout(x, training=self.training) x = self.conv2(x, edge_index) return F.log_softmax(x, dim=1) ``` 这个模型使用了 PyTorch Geometric 库中的 GCNConv 层来进行图卷积操作。输入的节点特征 x 和边索引 edge_index 会被传入两个 GCNConv 层中,最后输出一个经过 softmax 处理的概率分布,表示每个节点属于不同类别的概率。 ### 回答2: 图神经网络(Graph Neural Network,GNN)是一种用于处理图结构数据的深度学习模型。节点分类是GNN的一种常见任务,通过将节点分为不同的类别来预测节点的标签。 下面是一个简单的图神经网络节点分类的代码示例: 1. 首先导入所需的库,包括PyTorch和DGL(Deep Graph Library): ```python import torch import torch.nn as nn import dgl import dgl.function as fn from dgl.nn.pytorch import GraphConv ``` 2. 定义图神经网络模型,这里使用了两层Graph Convolutional Network(GCN): ```python class GCN(nn.Module): def __init__(self, in_feats, hid_feats, out_feats): super(GCN, self).__init__() self.conv1 = GraphConv(in_feats, hid_feats) self.conv2 = GraphConv(hid_feats, out_feats) def forward(self, g, features): x = torch.relu(self.conv1(g, features)) x = self.conv2(g, x) return x ``` 3. 创建图和特征,并初始化模型: ```python # 创建图 g = dgl.graph(([0, 1, 2, 3], [1, 2, 3, 0])) # 创建节点特征 features = torch.tensor([[0.0], [1.0], [2.0], [3.0]]) # 创建标签(用于训练) labels = torch.tensor([0, 1, 0, 1]) # 初始化模型 in_feats = features.shape[1] hid_feats = 2 out_feats = 2 model = GCN(in_feats, hid_feats, out_feats) ``` 4. 定义损失函数和优化器: ```python criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.01) ``` 5. 进行模型训练: ```python def train(epoch): model.train() optimizer.zero_grad() logits = model(g, features) loss = criterion(logits, labels) loss.backward() optimizer.step() print('Epoch {}, Loss: {:.4f}'.format(epoch, loss.item())) for epoch in range(100): train(epoch) ``` 以上代码中,首先定义了一个两层的GCN模型,然后创建了一个包含4个节点的图和对应的节点特征和标签。接着定义了损失函数和优化器,并进行了模型的训练。每个epoch,模型会前向传播计算输出,然后计算损失并进行反向传播更新模型参数。 这只是一个简单的示例,实际应用中可能还需要进行更复杂的模型设计和调参。此外,为了更好地处理大规模图数据,还可以使用更高级的图神经网络模型和优化算法。 ### 回答3: 图神经网络(Graph Neural Network,简称GNN)是一种能够处理图数据的神经网络模型。节点分类是GNN的一种常见任务,即给定一个图,预测出每个节点的类别。下面是一个简单的例子,演示了如何使用DGL库构建一个GNN模型来进行节点分类的代码。 首先,需要导入必要的库,包括DGL库和其他相关的深度学习库: ```python import dgl import torch import torch.nn as nn import torch.nn.functional as F from dgl.nn import GraphConv ``` 接下来,定义一个GNN模型类,继承自`nn.Module`: ```python class GNN(nn.Module): def __init__(self, in_dim, hidden_dim, num_classes): super(GNN, self).__init__() self.graph_conv1 = GraphConv(in_dim, hidden_dim) self.graph_conv2 = GraphConv(hidden_dim, hidden_dim) self.graph_conv3 = GraphConv(hidden_dim, num_classes) def forward(self, g, features): h = self.graph_conv1(g, features) h = F.relu(h) h = self.graph_conv2(g, h) h = F.relu(h) h = self.graph_conv3(g, h) return h ``` 在`__init__`函数中,定义了三个GraphConv层,每个层的输入维度、隐藏层维度和输出类别数目分别为`in_dim`、`hidden_dim`和`num_classes`。在`forward`函数中,通过多次使用GraphConv层和ReLU激活函数进行特征的传播和变换。 最后,训练和评估模型的代码如下所示: ```python # 构建图数据 g = dgl.graph(([0, 1, 2, 3, 4], [1, 2, 3, 4, 0])) features = torch.randn(5, in_dim) labels = torch.tensor([0, 1, 0, 1, 0]) # 初始化模型和优化器 model = GNN(in_dim, hidden_dim, num_classes) optimizer = torch.optim.Adam(model.parameters(), lr=0.01) # 训练模型 for epoch in range(num_epochs): logits = model(g, features) loss = F.cross_entropy(logits, labels) optimizer.zero_grad() loss.backward() optimizer.step() print('Epoch {}, Loss: {}'.format(epoch, loss.item())) # 评估模型 with torch.no_grad(): logits = model(g, features) predicted_labels = torch.argmax(logits, dim=1) accuracy = torch.sum(predicted_labels == labels).item() / len(labels) print('Accuracy: {}'.format(accuracy)) ``` 在训练阶段,通过计算预测值和真实标签之间的交叉熵损失来优化模型。在评估阶段,使用训练好的模型对新的样本进行预测,并计算准确率。 以上是一个简单的图神经网络节点分类的代码示例,实际应用中可以根据具体情况进行调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值