人工智能机器学习深度学习图计算【免费下载链接】dglPython package built to ease deep learning on graph, on top of existing DL frameworks.项目地址https://gitcode.com/gh_mirrors/dg/dgl点击查看免费下载本指南以 DGL 官方核心示例 examples/core/gat/train.py 与 examples/core/gat/README.md 为主线完整讲解如何在 DGL 中用内建的GATConv模块复现 Veličković 等人提出的 Graph Attention NetworkGAT在 Cora、Citeseer、Pubmed 三个经典引文数据集上做多分类节点分类。读完本文你将掌握 GAT 的数学原理、DGL 官方示例的完整运行方式与命令行参数、两阶段多头注意力模型的构建与聚合细节以及解决低精度过拟合问题的实战技巧。GAT 是什么从图卷积到注意力加权Graph Attention NetworkGAT是图神经网络GNN家族中极具代表性的模型其核心思想是用注意力机制取代固定的归一化系数对于每条边(j → i)模型学习一个注意力分数αᵢⱼ用来表示邻居节点j对节点i的更新贡献权重。节点更新的数学形式为h_i^(l1) Σ_{j∈N(i)} αᵢⱼ · W^(l) · h_j^(l)其中注意力分数通过对“拼接后的特征”做线性投影与LeakyReLU激活得到eᵢⱼ^(l) LeakyReLU( aᵀ [ W h_i ∥ W h_j ] ) αᵢⱼ^(l) softmax_i( eᵢⱼ^(l) )在本仓库中GAT 的官方最小示例位于 examples/core/gat其README.md明确给出了论文链接arXiv:1710.10903以及作者原版 TensorFlow 实现并声明该示例使用DGL 内建的GATConv模块完成训练与评测。运行环境与一键启动命令示例仅依赖 PyTorch 与 DGL 本体无需额外安装第三方库。运行命令为python3 train.py --dataset cora其中--dataset支持三个预置数据集cora、citeseer、pubmed均属于 DGL 内置的引文图数据集节点代表论文、边代表引用关系任务是预测论文的类别。运行过程中会自动下载对应数据集到本地缓存默认~/.dgl/。官方 README 同时给出了各数据集的参考测试精度数据集参考测试精度Test Accuracycora~0.821citeseer~0.710pubmed~0.780注意README 特别提醒由于过拟合用户偶尔会遇到测试精度偏低例如 0.8的情况。解决方法有两个一是加入 Early Stopping早停二是减少最大训练轮数--num_epochs。命令行参数详解train.py 通过argparse暴露了三个参数含义与默认值如下参数类型默认值说明--datasetstrcora数据集名称可选cora、citeseer、pubmed--num_epochsint200训练轮数上限--num_gpusint0使用的 GPU 数量大于 0 且检测到 CUDA 时自动切到 GPU设备选择逻辑见 train.py仅当num_gpus 0且torch.cuda.is_available()为真时才使用cuda设备否则回退到cpu因此纯 CPU 环境无需任何改动即可运行。数据加载与预处理自环Self-Loop的关键作用脚本的数据加载部分位于 train.pytransform AddSelfLoop() # by default, it will first remove self-loops to prevent duplication if args.dataset cora: data CoraGraphDataset(transformtransform) elif args.dataset citeseer: data CiteseerGraphDataset(transformtransform) elif args.dataset pubmed: data PubmedGraphDataset(transformtransform) ... g data[0] g g.int().to(device) features g.ndata[feat] labels g.ndata[label] masks g.ndata[train_mask], g.ndata[val_mask], g.ndata[test_mask]这里有两个值得深入的点1.AddSelfLoop变换的必要性AddSelfLoop定义于 python/dgl/transforms/module.py其作用是为图中每个节点添加自环并返回新图。它的默认参数allow_duplicateFalse表示“先移除已有自环再统一添加”从而避免重复自环——这正是 train.py 注释所说明的行为。为什么 GAT 需要自环GATConv 的源码注释 解释得非常清楚零入度0-in-degree节点不会收到任何消息聚合结果无效可能导致静默的性能退化。GATConv在forward中会主动检查(graph.in_degrees() 0).any()并抛出DGLError提示用户“调用g dgl.add_self_loop(g)解决该问题”。Cora 等引文网络本身存在孤立/无入度节点因此官方示例统一先做自环变换保证每个节点都能聚合到自身特征。若因某些原因无法加自环如异构图中边类型无法确定可显式设置allow_zero_in_degreeTrue关闭检查并自行处理。2. 数据集结构与划分Cora、Citeseer、Pubmed 三个数据集均继承自CitationGraphDataset见 python/dgl/data/citation_graph.py。以 Cora 为例其类文档citation_graph.py给出的统计信息为2708 个节点、10556 条边、7 个类别划分为训练 140 / 验证 500 / 测试 1000。每个图节点自带 1433 维的feat特征、label标签以及train_mask/val_mask/test_mask三个掩码脚本直接通过g.ndata取出使用无需自行划分。模型构建两阶段多头 GAT模型定义在 train.py结构为两层 GAT 多头注意力class GAT(nn.Module): def __init__(self, in_size, hid_size, out_size, heads): super().__init__() self.gat_layers nn.ModuleList() # two-layer GAT self.gat_layers.append( dglnn.GATConv( in_size, hid_size, heads[0], feat_drop0.6, attn_drop0.6, activationF.elu, ) ) self.gat_layers.append( dglnn.GATConv( hid_size * heads[0], out_size, heads[1], feat_drop0.6, attn_drop0.6, activationNone, ) ) def forward(self, g, inputs): h inputs for i, layer in enumerate(self.gat_layers): h layer(g, h) if i len(self.gat_layers) - 1: # last layer h h.mean(1) else: # other layer(s) h h.flatten(1) return h主函数中的实例化train.pyin_size features.shape[1] # Cora 下为 1433 out_size data.num_classes # Cora 下为 7 model GAT(in_size, 8, out_size, heads[8, 1]).to(device)逐层解读第一层GATConv(in_size, 8, heads[0]8)即输入维度 → 8 维隐藏特征、8 个注意力头feat_drop0.6、attn_drop0.6激活函数为F.elu。输出形状为(N, 8, 8)节点数 × 头数 × 每头输出维。中间聚合h.flatten(1)将多头输出展平为(N, 8*864)作为第二层的输入这正是论文中“多头拼接concatenation”的做法。第二层GATConv(64, out_size, heads[1]1)单头、无激活。输出形状为(N, 1, out_size)。最终聚合h.mean(1)对单头维度做平均得到(N, out_size)的 logits对应论文中“多头平均average”的做法。GATConv 底层实现原理python/dgl/nn/pytorch/conv/gatconv.py 是 PyTorch 后端GATConv的完整实现其核心计算过程可分为四步特征变换self.fc将输入特征线性投影到out_feats * num_heads维并重塑为(..., num_heads, out_feats)。同质图上共享一个fc若输入是(in_src, in_dst)元组二部图场景则分别使用fc_src与fc_dst见 gatconv.py。注意力分数计算源码在 gatconv.py 中有一段重要的实现说明——论文原文是“先拼接再线性投影”而 DGL 实现是“先分别投影再相加”两者数学上完全等价将论文中的权重向量a分解为[a_l ∥ a_r]则aᵀ[Wh_i ∥ Wh_j] a_l·Wh_i a_r·Wh_j。这种写法避免了在边上保存[Wh_i ∥ Wh_j]拼接张量内存更省且可借助 DGL 内建函数u_add_v进一步加速。边级 softmaxgraph.edata[a] self.attn_drop(edge_softmax(graph, e))gatconv.py先对原始分数做LeakyReLU再在每条边的“邻居维度”上做 softmax 归一化随后施加注意力 Dropout。消息聚合graph.update_all(fn.u_mul_e(ft, a, m), fn.sum(m, ft))gatconv.py——用注意力权重加权源节点特征u_mul_e再对每个目标节点求和fn.sum得到更新后的特征。最后依次叠加残差连接res_fc、可学习偏置bias与激活函数。关键参数与默认值参数默认值说明in_feats必填输入特征维数传元组可适配单向二部图out_feats必填每个注意力头的输出维数num_heads必填注意力头数量feat_drop0.0特征 Dropout 比例attn_drop0.0注意力权重 Dropout 比例negative_slope0.2LeakyReLU 负斜率residualFalse是否使用残差连接维度不匹配时自动添加线性层activationNone输出激活函数allow_zero_in_degreeFalse为真时跳过零入度节点检查biasTrue是否学习偏置项初始化策略reset_parameters 采用 Glorot/Xavier 初始化线性层权重与注意力参数attn_l、attn_r均使用xavier_normal_且增益按relu计算nn.init.calculate_gain(relu)偏置初始化为 0。注意注意力向量被拆成attn_l作用于源节点与attn_r作用于目标节点两个参数形状均为(1, num_heads, out_feats)。训练与评测流程训练与评测函数位于 train.pydef evaluate(g, features, labels, mask, model): model.eval() with torch.no_grad(): logits model(g, features) logits logits[mask] labels labels[mask] _, indices torch.max(logits, dim1) correct torch.sum(indices labels) return correct.item() * 1.0 / len(labels) def train(g, features, labels, masks, model, num_epochs): train_mask masks[0] val_mask masks[1] loss_fcn nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.parameters(), lr5e-3, weight_decay5e-4) for epoch in range(num_epochs): t0 time.time() model.train() logits model(g, features) loss loss_fcn(logits[train_mask], labels[train_mask]) optimizer.zero_grad() loss.backward() optimizer.step() acc evaluate(g, features, labels, val_mask, model) t1 time.time() print( Epoch {:05d} | Loss {:.4f} | Accuracy {:.4f} | Time {:.4f}.format( epoch, loss.item(), acc, t1 - t0 ) )训练要点优化器Adam学习率5e-3权重衰减weight_decay5e-4与 GAT 论文的超参一致。损失函数nn.CrossEntropyLoss()只在train_mask对应样本上计算。评测口径训练过程中每个 epoch 输出一次验证集精度masks[1]训练结束后在masks[2]测试集上再算一次并打印Test accuracy见 train.py。日志格式Epoch %05d | Loss %.4f | Accuracy %.4f | Time %.4f其中 Time 为该 epoch 的耗时秒。测试集评估在torch.no_grad()下进行先取模型输出中每行最大值对应的类别索引再与真实标签比较返回正确率。精度偏低时的排查与调优README 明确指出由于过拟合测试精度偶尔会低于 0.8。结合脚本实现可按以下顺序排查加早停Early Stopping观察每轮输出的验证集Accuracy当其在若干轮内不再上升时提前终止训练。README 将其列为推荐方案之一。减小训练轮数python3 train.py --dataset cora --num_epochs 100可显著缓解过拟合也可以同时调低feat_drop/attn_drop或增大权重衰减来配合。检查随机种子与初始化GAT 对初始化与 dropout 随机性较为敏感多次运行取均值是评估精度的合理做法参考精度 ~0.821cora、~0.710citeseer、~0.780pubmed即为正常水平区间。测试佐证GATConv 的接口契约GATConv 的单元测试 验证了本文涉及的核心行为可作为理解接口契约的佐证同质图与 block-bipartite 图上h gat(g, feat)的输出形状恒为(N_dst, num_heads, out_dim)test_nn.py。设置get_attentionTrue时第二个返回值为注意力张量形状为(num_edges, num_heads, 1)test_nn.py说明训练脚本中的mean(1)/flatten(1)聚合操作有稳定的形状前提。二部图bipartite场景下feat传(src_feat, dst_feat)元组输出形状同样为(N_dst, num_heads, out_dim)test_nn.py印证了GATConv对同质图与二部图的统一支持。edge_weight参数可额外传入一维边权重与注意力分数相乘后再聚合test_nn.pyGATConv的forward签名中也确有该可选参数gatconv.py。此外DGL 还提供了同一模块的 TensorFlowpython/dgl/nn/tensorflow/conv/gatconv.py与 MXNetpython/dgl/nn/mxnet/conv/gatconv.py后端实现其feat_drop/attn_drop等参数语义与 PyTorch 版一致说明该示例的建模思路可在不同深度学习框架间复用。延伸阅读官方 GAT 论文Graph Attention NetworksarXiv:1710.10903可自行检索获取。模型层源码python/dgl/nn/pytorch/conv/gatconv.py。数据集实现python/dgl/data/citation_graph.py。自环变换实现python/dgl/transforms/module.py。更多 GNN 模型示例查看 examples/core 目录下其他子目录如gat、gcn、graphsage、rgcn等即可快速对比不同模型在同一数据集上的实现差异。赞分享人工智能机器学习深度学习图计算【免费下载链接】dglPython package built to ease deep learning on graph, on top of existing DL frameworks.项目地址https://gitcode.com/gh_mirrors/dg/dgl点击查看免费下载相关推荐NOTEARS 与其他因果发现算法终极对比为何连续优化方案脱颖而出NOTEARS 与其他因果发现算法终极对比为何连续优化方案脱颖而出 因果发现Causal Discovery是从观测数据中还原变量之间因果关系的核心任务人工智能机器学习深度学习图计算终极Torch7图注意力网络指南5步实现GAT模型终极Torch7图注意力网络指南5步实现GAT模型 Torch7是一个强大的科学计算框架特别适用于机器学习和深度学习任务。本文将引导您通过5个简单步骤使用深度学习使用 DGL 在 PyTorch 中实现图注意力网络GAT从 GATConv 到节点分类与多标签训练实战使用 DGL 在 PyTorch 中实现图注意力网络GAT从 GATConv 到节点分类与多标签训练实战 导读 本文以 DGL 官方示例 examples人工智能机器学习深度学习图计算创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
