文章目录
- Planetoid数据集属性
- 访问这些属性
- 示例输出
- 解释
- 使用数据集属性在模型中
- NormalizeFeatures
- 为什么要归一化特征
- `NormalizeFeatures` 变换
- 示例代码
- 整体示例
- 总结
在 PyTorch Geometric 中,
Planetoid
类加载的数据集具有一些预定义的属性,用于访问有关数据集的信息。这些属性包含了节点数、边数、特征数和类别数等信息。
Planetoid数据集属性
以下是一些常用的 Planetoid
数据集属性:
num_classes
:类别的数量(即分类任务中的类别数)。num_features
:每个节点的特征数。num_nodes
:节点的数量。num_edges
:边的数量。
访问这些属性
加载数据集之后,可以直接通过数据集对象访问这些属性。例如:
from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures# 加载Cora数据集,并应用NormalizeFeatures变换
dataset = Planetoid(root='/tmp/Cora', name='Cora', transform=NormalizeFeatures())
data = dataset[0]# 访问数据集属性
num_classes = dataset.num_classes
num_features = dataset.num_features
num_nodes = data.num_nodes
num_edges = data.num_edgesprint(f'Number of classes: {num_classes}')
print(f'Number of features: {num_features}')
print(f'Number of nodes: {num_nodes}')
print(f'Number of edges: {num_edges}')
示例输出
Number of classes: 7
Number of features: 1433
Number of nodes: 2708
Number of edges: 10556
解释
num_classes
:在Cora数据集中,节点属于7个不同的类别。num_features
:每个节点有1433个特征。num_nodes
:图中总共有2708个节点。num_edges
:图中总共有10556条边。
这些属性帮助你了解数据集的基本结构和规模,从而更好地设计和调整模型。
使用数据集属性在模型中
这些属性在定义模型时非常有用,例如在GCN模型中:
from torch_geometric.nn import GCNConvclass GCN(torch.nn.Module):def __init__(self):super(GCN, self).__init__()self.conv1 = GCNConv(dataset.num_features, 16)self.conv2 = GCNConv(16, dataset.num_classes)def forward(self, data):x, edge_index = data.x, data.edge_indexx = self.conv1(x, edge_index)x = F.relu(x)x = F.dropout(x, training=self.training)x = self.conv2(x, edge_index)return x
这里,dataset.num_features
和 dataset.num_classes
分别用作输入特征数和输出类别数,从而定义GCN层的输入和输出大小。
NormalizeFeatures
transform=NormalizeFeatures()
是在加载数据集时对数据进行特征归一化的一种方式。在 PyTorch Geometric 中,NormalizeFeatures
是一个常见的变换,用于将节点特征矩阵的每一行归一化。
为什么要归一化特征
归一化特征有助于提升图神经网络(GNN)的训练效果和收敛速度。归一化可以确保不同特征的数值范围相同,从而避免某些特征对模型训练产生过大的影响。
NormalizeFeatures
变换
NormalizeFeatures
变换的主要功能是将每个节点特征向量归一化,使得每个节点的特征向量的 L2 范数为 1。具体来说,如果节点 i i i的特征向量为 x i \mathbf{x}_i xi,则归一化后的特征向量为 x i / ∥ x i ∥ \mathbf{x}_i / \|\mathbf{x}_i\| xi/∥xi∥。
示例代码
以下是如何在加载数据集时使用 NormalizeFeatures
进行特征归一化的示例代码:
import torch
from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures# 加载Cora数据集,并应用NormalizeFeatures变换
dataset = Planetoid(root='/tmp/Cora', name='Cora', transform=NormalizeFeatures())
data = dataset[0]# 打印归一化后的特征
print(data.x)
整体示例
结合之前的代码,这里是一个完整的示例,展示如何加载 Cora 数据集并对其进行特征归一化,然后训练和评估图神经网络模型:
import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures# 加载Cora数据集,并应用NormalizeFeatures变换
dataset = Planetoid(root='/tmp/Cora', name='Cora', transform=NormalizeFeatures())
data = dataset[0]# 计算训练、验证和测试集的大小
num_train = data.train_mask.sum().item()
num_val = data.val_mask.sum().item()
num_test = data.test_mask.sum().item()print(f'Number of training nodes: {num_train}')
print(f'Number of validation nodes: {num_val}')
print(f'Number of test nodes: {num_test}')# 定义GCN模型
class GCN(torch.nn.Module):def __init__(self):super(GCN, self).__init__()self.conv1 = GCNConv(dataset.num_node_features, 16)self.conv2 = GCNConv(16, dataset.num_classes)def forward(self, data):x, edge_index = data.x, data.edge_indexx = self.conv1(x, edge_index)x = F.relu(x)x = F.dropout(x, training=self.training)x = self.conv2(x, edge_index)return x # 返回未归一化的logits# 初始化模型和优化器
model = GCN()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
data = data.to('cuda')
model = model.to('cuda')# 训练模型
def train():model.train()optimizer.zero_grad()out = model(data) # out 的形状是 [num_nodes, num_classes]train_out = out[data.train_mask] # 选择训练集节点的输出train_labels = data.y[data.train_mask] # 选择训练集节点的标签loss = F.cross_entropy(train_out, train_labels) # 计算交叉熵损失loss.backward()optimizer.step()return loss.item()# 评估模型
def test():model.eval()out = model(data)pred = out.argmax(dim=1) # 提取预测类别correct = (pred[data.test_mask] == data.y[data.test_mask]).sum()acc = int(correct) / int(data.test_mask.sum())return accfor epoch in range(200):loss = train()acc = test()print(f'Epoch {epoch+1}, Loss: {loss:.4f}, Accuracy: {acc:.4f}')
总结
通过在加载数据集时应用 NormalizeFeatures
变换,你可以确保每个节点的特征向量被归一化,从而提高模型的训练效果和收敛速度。这在处理图神经网络任务时是一个很常见且有用的预处理步骤。