图神经网络教程之GAT(pyG)

文章介绍了如何使用PyTorch和PyTorchGeometric库在Cora数据集上构建和训练基于GAT(GraphAttentionNetwork)的节点分类模型,展示了GATConv层的使用和训练过程。
摘要由CSDN通过智能技术生成

图神经网络-pyG-GAT

在上一章节介绍了pyG-GCN的使用,除了GCN,还有一些像GAT、GraphSage等等一些,本文将介绍GAT模型的构建

实现了一个使用Graph Attention Network(GAT)的节点分类模型,该模型在Cora数据集上进行训练和测试。

  1. 首先,导入所需的库和模块:

    • torch_geometric.datasets.Planetoid:用于加载Cora数据集。
    • torch:PyTorch的主要库。
    • torch.nn.functional as F:PyTorch的神经网络函数模块,用于定义神经网络的层和操作。
    • torch_geometric.nn.GATConv:PyTorch Geometric库中的图注意力网络层(Graph Attention Network,GATConv)。
    • torch_geometric.nn.GATConv:PyTorch Geometric库中的图注意力网络层(Graph Attention Network,GATConv)。
  2. 加载Cora数据集:

    dataset = Planetoid(root='./tmp/Cora', name='Cora')
    

    这行代码加载了Cora数据集,该数据集包括节点特征、图的边缘信息以及节点的真实标签。

  3. 定义一个名为GAT_Net的神经网络类:

    class GAT_Net(torch.nn.Module):
    

    这个类继承自PyTorch的torch.nn.Module基类,表示它是一个神经网络模型。

  4. GAT_Net类的构造函数中,定义了两个GAT层:

    def __init__(self, features, hidden, classes, heads=1):
        super(GAT_Net, self).__init__()
        self.gat1 = GATConv(features, hidden, heads=heads)
        self.gat2 = GATConv(hidden * heads, classes)
    
    • GATConv层是图注意力网络层,用于从图数据中提取特征。
    • self.gat1是第一个GATConv层,它将输入特征的维度设置为features,输出hidden维特征,同时可以指定heads的数量。
    • self.gat2是第二个GATConv层,将hidden * heads维特征映射到classes个类别。
  5. forward方法中定义了前向传播过程:

    def forward(self, data):
        x, edge_index = data.x, data.edge_index
    
        x = self.gat1(x, edge_index)
        x = F.relu(x)
        x = F.dropout(x, training=self.training)
        x = self.gat2(x, edge_index)
    
        return F.log_softmax(x, dim=1)
    
    • 输入数据data包括节点特征x和边索引edge_index
    • self.gat1self.gat2分别表示第一层和第二层的图注意力网络操作。
    • 使用ReLU激活函数进行非线性变换。
    • 使用Dropout层进行正则化。
    • 最后,通过F.log_softmax对输出进行softmax操作,以得到每个节点属于不同类别的概率分布。
  6. 检查并设置GPU或CPU设备:

    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    

    这段代码会检查你的系统是否有可用的GPU,并将device设置为GPU或CPU,以便在相应的设备上运行模型。

  7. 创建并将模型移动到所选设备上:

    model = GAT_Net(dataset.num_node_features, 16, dataset.num_classes, heads=4).to(device)
    

    这将实例化GAT_Net模型,并将模型的参数和计算移动到GPU或CPU上。heads参数指定了GAT中的注意力头数量。

  8. 加载Cora数据集的第一个图数据实例:

    data = dataset[0]
    

    这将加载Cora数据集的第一个图数据实例,包括节点特征、图的边缘信息以及节点的真实标签。

  9. 定义优化器(这里使用Adam优化器):

    optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
    

    这行代码创建一个Adam优化器,并将模型的参数传递给它,用于模型参数的更新。学习率为0.01。

  10. 将模型设置为训练模式:

    model.train()
    

    这行代码将模型切换到训练模式,以启用训练时的特定操作,如Dropout。

  11. 开始训练循环,训练模型200个epoch:

    for epoch in range(200):
    

    这是一个训练循环,将模型训练200次。

  12. 在每个epoch中,首先将优化器的梯度清零:

    optimizer.zero_grad()
    

    这行代码用于清除之前的梯度信息,以准备计算新的梯度。

  13. 通过模型前向传播计算预测结果:

    out = model(data)
    

    这会将数据传递给你的GAT模型,然后返回模型的预测结果。

  14. 计算损失函数,这里使用负对数似然损失(Negative Log-Likelihood Loss):

    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
    

    这行代码计算了在训练节点子集上的负对数似然损失。data.train_mask指定了用于训练的节点子集,data.y是节点的真实标签。

  15. 反向传播和参数更新:

    loss.backward()
    optimizer.step()
    

    这两行代码用于计算梯度并执行梯度下降,更新模型的参数,以最小化损失函数。

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

dataset = Planetoid(root='./tmp/Cora',name='Cora')
class GAT_Net(torch.nn.Module):
    def __init__(self, features, hidden, classes, heads=1):
        super(GAT_Net, self).__init__()
        self.gat1 = GATConv(features, hidden, heads=heads)
        self.gat2 = GATConv(hidden*heads, classes)

    def forward(self, data):
        x, edge_index = data.x, data.edge_index

        x = self.gat1(x, edge_index)
        x = F.relu(x)
        x = F.dropout(x, training=self.training)
        x = self.gat2(x, edge_index)

        return F.log_softmax(x, dim=1)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GAT_Net(dataset.num_node_features, 16, dataset.num_classes, heads=4).to(device)
data = dataset[0]
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

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).max(dim=1)
correct = pred[data.test_mask].eq(data.y[data.test_mask]).sum()
acc = int(correct)/ int(data.test_mask.sum())
print('GAT',acc)
好的,基于神经网络的联邦推荐中,使用GAT计算用户建模中的用户-项目得出嵌入向量的算法描述如下: 假设我们有一个用户-项目G = (V, E),其中V表示节点集合,E表示边集合。对于每个节点v∈V,它都有一个特征向量f_v∈R^d,表示节点v的属性信息。我们希望通过GAT层来获取节点v的嵌入向量h_v∈R^k,其中k是嵌入向量的维度。 具体而言,GAT层可以被描述为: $$ h_{v}^{l}=\sigma\left(\sum_{u \in N(v)} \alpha_{u, v}^{l} W^{l} h_{u}^{l-1}\right) $$ 其中,$h_{v}^{l}$是节点v在第l层的嵌入向量,$W^{l}$是第l层的权重矩阵,$\alpha_{u, v}^{l}$表示节点u和节点v之间的注意力权重,计算方法为: $$ \alpha_{u, v}^{l}=\frac{\exp \left(\operatorname{LeakyReLU}\left(a^{l} \cdot\left[h_{v}^{l-1} \| h_{u}^{l-1}\right]\right)\right)}{\sum_{v \in N(u)} \exp \left(\operatorname{LeakyReLU}\left(a^{l} \cdot\left[h_{v}^{l-1} \| h_{u}^{l-1}\right]\right)\right)} $$ 其中,$\|$表示向量拼接操作,$\operatorname{LeakyReLU}$是激活函数,$a^{l}$表示第l层的注意力矩阵。 GAT层的整个计算过程可以通过多层堆叠来获得更丰富的特征表示,即: $$ h_{v}^{0}=f_{v}, \quad h_{v}^{l}=\sigma\left(\sum_{u \in N(v)} \alpha_{u, v}^{l} W^{l} h_{u}^{l-1}\right) $$ 其中,$h_{v}^{0}$表示节点v的初始特征向量。通过多层堆叠,我们可以得到节点v的最终嵌入向量$h_{v}^{L}$,其中$L$表示最后一层。具体而言,可以通过以下公式计算: $$ h_{v}=h_{v}^{L}=\operatorname{concat}\left(h_{v}^{1}, h_{v}^{2}, \ldots, h_{v}^{L-1}, h_{v}^{L}\right) $$ 其中,$\operatorname{concat}$表示向量拼接操作,将节点v在所有层的嵌入向量拼接在一起,得到最终的嵌入向量$h_{v}$。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NoteLoopy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值