PYG学习笔记

图的基本构造

一张图实例 described by torch_geometric.data.Data

from torch_geometric.data import Data

edge_index = torch.tensor([[0, 1, 2, 0, 3], [1, 0, 1, 3, 2]], dtype=torch.long)
x = torch.tensor([[-1], [0], [1]], dtype=torch.float)
data = Data(x=x, edge_index=edge_index)
data.x:节点特征-矩阵 [num_nodes, num_node_features]
data.edge_index:具有形状和类型的COO格式的图形连接 [2, num_edges]torch.long
data.edge_attr:边特征-矩阵 [num_edges, num_edge_features]
data.y:要训练的目标(可能具有任意形状), 例如,形状的节点级目标或形状的图形级目标 [num_nodes, *][1, *]
data.pos:具有形状的节点位置矩阵 [num_nodes, num_dimensions]
data.num_nodes: 获取节点数。
data.num_edges: 获取边数。
data.num_node_features: 获取节点特征数。
data.num_edge_features: 获取边特征数。
data.contains_isolated_nodes(): 判断是否包含孤立节点。
data.contains_self_loops(): 判断是否包含自环边。
data.is_directed(): 判断是否是有向图
COO格式
是稀疏矩阵的一种常见表示方法,也被称为坐标格式。COO格式用三个数组来存储一个稀疏矩阵。这三个数组分别是行索引数组、列索引数组和数值数组。
以二维稀疏矩阵为例,行索引数组存储了每个非零元素所在的行号,列索引数组存储了每个非零元素所在的列号,数值数组存储了每个非零元素的值
1 0 0
0 2 0
0 0 3

row = [0, 1, 2]
col = [0, 1, 2]
data = [1, 2, 3]
无权图——只有两行

# Transfer data object to GPU.

device=torch.device('cuda')
data=data.to(device)
contiguous

contiguous是一个用于判断Tensor内存块是否连续的函数。当Tensor内存块不连续时,如果要进行一些需要内存连续性的操作,如view或transpose等操作,就需要先调用contiguous函数,使得Tensor内存块连续,然后才能继续操作

如果在一个非连续的Tensor上调用 view函数,则会抛出异常,此时需要先调用 contiguous函数,使得Tensor内存块连续,然后再调用 view函数
data.validate()

是用于验证数据对象的内部一致性和完整性的函数。它检查数据对象中的各种属性是否匹配并且是否存在必需的属性。如果数据对象中存在问题,validate()函数将引发错误并给出相应的错误消息。这个函数在使用PyTorch Geometric处理自定义数据时非常有用,可以避免一些常见的数据格式错误

图的基准数据集

初始化数据集很简单。数据集的初始化会自动下载其原始文件并将其处理成之前描述的Data格式

from torch_geometric.datasets import TUDataset

dataset = TUDataset(root='/tmp/ENZYMES', name='ENZYMES')
>>> ENZYMES(600)

len(dataset)
>>> 600

dataset.num_classes
>>> 6

dataset.num_node_features
>>> 3

data = dataset[0]
>>> Data(edge_index=[2, 168], x=[37, 3], y=[1])

data.is_undirected()
>>> True
data = dataset[0]
>>> Data(edge_index=[2, 10556], test_mask=[2708],
         train_mask=[2708], val_mask=[2708], x=[2708, 1433], y=[2708])

data.is_undirected()
>>> True

data.train_mask.sum().item()
>>> 140

data.val_mask.sum().item()
>>> 500

data.test_mask.sum().item()
>>> 1000

上数行代码表示神经网络的训练集、验证集、测试集、

小批量

和卷积神经网络相似的,批量处理同样通过loader实现

数据转换

torch_geometric.transforms.Compose

是 PyG 中的一个类,用于将多个数据预处理操作组合在一起,以便在数据集的处理过程中进行调用。这个类使得用户可以将不同的转换函数(如 Z-normalization 或 One-hot Encoding)组合在一起,从而形成一个更大的转换管道。通过这种方式,可以实现将多个转换函数组成一个更加复杂的处理流程,从而可以更加方便地进行数据预处理。torch_geometric.transforms.Compose 可以被传递给 torch_geometric.datasets 中的数据集,或者在自定义数据集的时候使用。

pre_transform

pre_transform=T.KNNGraph(k=6)

是用于在训练过程之前对数据进行预处理的函数。在这个例子中,pre_transform 是一个 KNNGraph 对象,它将在训练之前对数据进行预处理。KNNGraph 的作用是将每个节点连接到它的 k 个最近邻节点,从而生成图的邻接矩阵。这可以帮助模型更好地理解节点之间的关系。其中 k=6 是指每个节点连接到它的 6 个最近邻节点

T.RandomJitter

transform=T.RandomJitter(0.01)

函数。这个函数的作用是在节点坐标上添加一些随机扰动来增加模型的鲁棒性。这里的参数0.01指定了最大的扰动范围,每个节点的坐标值都将在[-0.01, 0.01]之间添加一些随机的值

图的学习方法

from torch_geometric.datasets import Planetoid
import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
dataset = Planetoid(root='tmp/Cora', name='Cora')
class GCN(torch.nn.Module):
    def __init__(self):
        super().__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_index
        x = self.conv1(x, edge_index)
        x = F.relu(x)
        x = F.dropout(x, training=self.training)
        x = self.conv2(x, edge_index)

        return F.log_softmax(x, dim=1)

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GCN().to(device)
data = dataset[0].to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)

model.train()
for epoch in range(200):
    optimizer.zero_grad()
    out = model(data)
    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()

model.eval()
pred = model(data).argmax(dim=1)
correct = (pred[data.test_mask] == data.y[data.test_mask]).sum()
acc = int(correct) / int(data.test_mask.sum())
print(f'Accuracy: {acc:.4f}')

这段代码用于对模型进行测试并计算分类准确率。首先,使用模型对测试数据集(data.test_mask)进行前向传递,并取预测结果的最大值作为类别标签。这可以通过调用model(data).argmax(dim=1)来实现,其中model是一个已经训练好的模型,data是一个torch_geometric.data.Data对象,它包含了测试数据的图结构和特征。argmax(dim=1)函数用于返回每个样本的预测类别的索引。

接下来,将预测正确的样本数计算出来,这可以通过比较预测结果和真实标签,然后将结果进行求和操作实现,即(pred[data.test_mask] == data.y[data.test_mask]).sum()。这里只对测试集的样本进行计算,因此使用了data.test_mask来进行切片,而不是对整个数据集进行计算。

最后,将预测正确的样本数除以测试集样本总数,得到测试集分类准确率,即acc = int(correct) / int(data.test_mask.sum())。其中,int函数用于将correct和data.test_mask.sum()转换为整数类型,以确保准确率的计算结果为浮点数。最终,通过print(f'Accuracy: {acc:.4f}')将准确率输出到控制台。

GCNConv()

是PyG中的图卷积层,用于实现基于图的卷积神经网络(GCN)。它的输入是一个具有节点特征矩阵和邻接矩阵的图数据,并输出经过卷积计算后的节点特征矩阵。

in_channels(输入特征维度)、

out_channels(输出特征维度)

bias(是否使用偏置项)

GCNConv()通过对输入节点特征和邻接矩阵进行矩阵乘法和卷积操作来计算输出节点特征。它使用标准化邻接矩阵进行卷积,以确保稳定性和收敛性。

dropout()

是一个用于防止神经网络过拟合的技术,它可以随机地丢弃(设置为零)一部分神经元的输出。这样一来,这些被丢弃的神经元就不再参与到前向传播和反向传播的计算中,从而避免了模型对某些特定的输入模式进行过度优化的情况。在 PyTorch 中,可以通过 dropout() 函数来实现这个功能。

dropout_layer = nn.Dropout(p=0.5)

其中 p 参数表示丢弃率,即将多少比例的输入设置为零。例如,上述代码中的 dropout_layer 对象将会按照 50% 的概率随机地将输入中的某些元素设置为零。在训练时,dropout() 函数会在每个 mini-batch 中随机地丢弃一些神经元的输出;

而在测试时,则会保留所有神经元的输出,因此输出值需要乘上一个恰当的缩放因子来进行调整

log_softmax()

函数是PyTorch中的一个函数,用于计算输入张量的对数softmax。softmax函数将输入张量映射到[0,1]区间并归一化,而对数softmax则将softmax的输出进行对数转换。这个函数通常在训练神经网络中用于计算多分类问题的损失函数,可以看作是交叉熵函数的一个变体。

output = torch.nn.functional.log_softmax(input, dim=None, _stacklevel=3, dtype=None)
input是输入张量
dim是在哪个维度上进行softmax操作,默认为最后一维。
dtype是输出张量的数据类型

log_softmax()softmax()的基础上进行了改进。它首先对输入进行指数函数变换,然后将指数函数的和取对数。该函数既可以减少计算复杂度,也可以防止数值下溢。同时,使用log_softmax()可以避免梯度消失的问题

model.train()

函数是用来设置模型处于训练模式的。当你使用深度学习模型进行训练时,需要在训练开始前调用此函数,以启用模型中特定层(如 Dropout)的训练模式。在训练模式下,这些层会执行其特定的训练行为,比如说 Dropout 层会以一定的概率随机失活神经元,防止过拟合。而在模型预测时,一般需要调用 model.eval() 函数来设置模型处于评估模式。在评估模式下,这些层会执行它们的评估行为,如 Dropout 层会完全保留神经元,保证评估的稳定性

nll_loss()函数

全称Negative Log-Likelihood Loss,是用于训练分类模型的损失函数之一。它的作用是计算负对数似然损失,将神经网络的输出概率分布与真实标签的对数概率分布进行比较

猜你喜欢

转载自blog.csdn.net/weixin_62375715/article/details/129432569
今日推荐