PyTorch Geometric 实验性功能实战:基于 contrib 包的 RBCD 图对抗攻击与 PGM 图神经网络可解释性 PyTorch Geometric 实验性功能实战基于 contrib 包的 RBCD 图对抗攻击与 PGM 图神经网络可解释性【免费下载链接】pytorch_geometricGraph Neural Network Library for PyTorch项目地址: https://gitcode.com/GitHub_Trending/py/pytorch_geometric导读本文围绕 examples/contrib/README.md 展开系统讲解 PyTorch GeometricPyG中torch_geometric.contrib实验性功能包的四个官方示例RBCDResource-based Critical Data图对抗攻击的逃逸Evasion与投毒Poisoning两种场景以及 PGMProbabilistic Graphical Model概率图模型解释器在节点分类与图分类任务上的应用。读完本文你将掌握GRBCDAttack/PRBCDAttack的调用方式、超参数调优要点以及如何用PGMExplainer解释 GNN 的预测结果并能直接运行仓库中的四个示例脚本进行验证。认识 contrib 包PyG 的实验性功能试验场torch_geometric.contrib是 PyG 为早期、实验性代码提供的暂存区staging area。根据 examples/contrib/README.md 的说明其中的模块未来可能被移入主库。这意味着API 可能变动contrib 中的类和方法不保证向后兼容升级 PyG 版本时需关注 CHANGELOG示例即文档由于处于实验阶段官方文档对 contrib 功能的说明较少examples/contrib 目录下的示例脚本就是最直接的用法参考独立模块化contrib 包按功能分为contrib.nn网络与攻击模块与contrib.explain可解释性模块等子包详见 torch_geometric/contrib/nn/init.py 与 torch_geometric/contrib/explain/init.py。本目录共包含四个示例覆盖两大主题示例文件主题rbcd_attack.pyRBCDResource-based Critical Data攻击的逃逸示例rbcd_attack_poisoning.pyRBCD 攻击结合数据投毒策略的示例pgm_explainer_node_classification.pyPGM 解释器用于节点分类任务pgm_explainer_graph_classification.pyPGM 解释器用于图分类任务运行环境与前置依赖四个示例均依赖 PyTorch 与 PyG 主库其中投毒示例额外依赖higher库用于内层循环inner-loop优化pip install higherrbcd_attack_poisoning.py在导入higher失败时会直接退出并提示安装命令见 rbcd_attack_poisoning.py。所有示例会自动选择cuda若可用否则cpu设备。数据文件默认下载到示例脚本同级的data/目录。RBCD 图对抗攻击原理与 API攻击原理松弛化的随机块坐标下降RBCD 系列攻击源自论文Robustness of Graph Neural Networks at Scale其核心思想是只扰动邻接矩阵增删边不扰动节点特征因此适用于任何能处理带权图、且对边权可微的 GNN 模型如GCNConv、GraphConv。其中两个攻击类定义在 torch_geometric/contrib/nn/models/rbcd_attack.pyPRBCDAttack投影随机块坐标下降攻击期间将邻接矩阵的离散条目从{0, 1}松弛到[0, 1]通过梯度更新边权再用投影操作保证松弛后的 L0 预算约束最后采样得到离散的扰动图GRBCDAttack贪心随机块坐标下降共享 PRBCD 的梯度机制但每一步贪心地基于梯度直接翻转边torch.topk(gradient, step_size)取梯度最大的边置 1实现见 rbcd_attack.py 中 GRBCDAttack._update。两种攻击都通过随机块采样控制内存开销每轮只在一批随机的候选边至多block_size条上计算梯度。由于块是有放回采样后去重实际块大小通常略小于设定值见源码 rbcd_attack.py 的 docstring 说明。二者可用于局部攻击local与全局攻击global通过idx_attack指定攻击目标单个节点或整个测试集逃逸攻击evasion测试时与投毒攻击poisoning训练时分别对应两个示例脚本。PRBCDAttack 核心参数参数默认值含义与调优要点model必填待评估的 GNN 模块block_size必填每轮随机采样的候选边数量是内存开销的主要来源示例中取250_000epochs125攻击轮数贪心模式下预算耗尽可提前终止epochs_resampling100前多少轮进行块重采样之后转为固定搜索空间微调lossprob_margin衡量攻击强度的损失可选masked、margin、prob_margin、tanh_margin或传入自定义可调用对象metric同loss用于监控/早停的第二个可不可微指标lr1000边权更新学习率PRBCD 最重要的超参数之一最佳实践是让预算在几步内耗尽is_undirectedTrue图是否为无向图logTrue是否打印攻击进度tqdm 进度条源码中的损失函数实现见 rbcd_attack.py给出了更精确的语义margin真实类得分与最高非目标类得分之差m -s_y max_{y≠y} s_yprob_margin对 softmax 概率计算 margin聚焦决策边界附近的节点tanh_margin对 margin 取 tanh同样关注边界节点masked仅在预测正确的节点上计算交叉熵argmax labels的样本才计入损失。attack() 方法签名pert_edge_index, perts attack( x, # 节点特征矩阵 edge_index, # 边索引 labels, # 标签 budget, # 允许翻转增删的边数上限 idx_attackNone, # 攻击目标节点索引/掩码None 表示全部 **kwargs, # 透传给 GNN 模块的额外参数 )返回值为(perturbed_edge_index, flipped_edges)二元组即扰动后的边索引与具体被翻转的边列表。attack()内部会在 attack 方法 中维护attack_statistics字典记录每步的损失、投影前后的概率质量等供后续分析或绘图。实战一逃逸攻击Evasion——测试时篡改图结构examples/contrib/rbcd_attack.py 演示了在 Cora 数据集上分别对 GAT 做局部攻击、对 GCN 做全局攻击的完整流程。构造可攻击的模型示例中定义了两个模型类GCNrbcd_attack.py 第 20-44 行两层GCNConv关键点是normalizeFalse关闭卷积内部归一化改为在forward中调用gcn_norm只归一化一次并支持skip_norm标志——这样攻击过程中边权重变化时无需重复做昂贵的归一化GATrbcd_attack.py 第 47-86 行由于标准GATConv不接受边权示例通过继承GATConv重写edge_update实现带边权的 GATWeightedGATConv。其技巧是将源/目标注意力系数相加模拟拼接并用alpha torch.log2(edge_attr)将边权以对数形式融入注意力边权为 1 时 alpha 不变为 0 时趋近 -Inf从而规避后续 exp/softmax 的下溢问题自环边权初始化为fill_value1.。局部攻击攻击单个节点node_idx 42 local_budget 2 # 训练节点 42 的度为 2即最多翻 2 条边 grbcd GRBCDAttack(gat, block_size250_000) prbcd PRBCDAttack(gat, block_size250_000, metricmetric, lr2_000) # GRBCD攻击单节点 pert_edge_index, perts grbcd.attack( data.x, data.edge_index, data.y, budgetlocal_budget, idx_attack[node_idx], )metric定义为负的准确率越小越好与损失方向一致def metric(*args, **kwargs): return -accuracy(*args, **kwargs)示例通过PRBCDAttack._probability_margin_loss源码中为静态方法rbcd_attack.py计算攻击前后目标节点真实类到最佳非目标类的置信度边界confidence margin直观展示攻击效果边界值从攻击前的正值跌向负值意味着模型对目标节点的分类信心被显著破坏随后打印被翻转的具体边(u, v)列表。全局攻击攻击整个测试集# 扰动 5% 的边无向图每条边存两份故除以 2 global_budget int(0.05 * data.edge_index.size(1) / 2) pert_edge_index, perts grbcd.attack( data.x, data.edge_index, data.y, budgetglobal_budget, idx_attackdata.test_mask, # 目标为全部测试节点 )全局攻击后用copy.copy(data)复制数据并替换edge_index重新评估 GCN 在测试集上的准确率打印Clean accuracy → Perturbed accuracy的下降幅度。逃逸场景下模型参数在攻击前后保持不变这正对应测试时攻击的定义。学习率选择的启发式源码 rbcd_attack.py 中 _update_edge_weights 显示PRBCD 的实际学习率会按lr * budget / num_nodes / sqrt(max(0, epoch - epochs_resampling) 1)做启发式修正使其与预算、图规模无关并在重采样阶段结束后固定搜索空间自然衰减。示例注释给出的经验法则是选择一个能让预算在几步内耗尽的学习率如lr2_000同时高学习率还能缓解边权松弛{0,1} → [0,1]带来的松弛间隙relaxation gap影响。GRBCD 由于是贪心翻转在小预算下比 PRBCD 更快但结果的一致性略逊示例注释明确指出。实战二投毒攻击Poisoning——训练时污染图结构examples/contrib/rbcd_attack_poisoning.py 演示了训练时攻击在 GCN 重新训练之前篡改邻接矩阵观察最终模型性能下降。相比逃逸攻击投毒需要模拟攻击者修改图后受害者在其上重新训练模型的过程因此必须引入双层优化bi-level optimization。双层优化的实现内层循环重训练示例通过子类化PRBCDAttack并重写两个关键钩子来实现_forwardrbcd_attack_poisoning.py 第 44-55 行每次前向先model.reset_parameters()然后在torch.enable_grad()下用扰动后的图train(self.model, ped, n_epochs, lr, weight_decay)完整重训模型50 轮、学习率 0.04、权重衰减 5e-4模拟受害者对新图的适应过程_forward_and_gradientrbcd_attack_poisoning.py 第 57-102 行借助higher.innerloop_ctx构建可微的内层训练循环让扰动边权的梯度能够穿过整个重训练过程反向传播同时将梯度裁剪到范数0.5以保证数值稳定性。示例开头有一句关键注释rbcd_attack_poisoning.py 第 25-26 行投毒场景下边权最终会被忽略邻接矩阵的预处理如归一化应放在模型内部参与反向传播这正是示例 GCN 把gcn_norm放进forward的原因。攻击流程与结果验证prbcd PoisoningPRBCDAttack(gcn, block_size250_000, metricmetric, lr100) global_budget int(0.05 * data.edge_index.size(1) / 2) pert_edge_index, perts prbcd.attack( data.x, data.edge_index, data.y, budgetglobal_budget, idx_attackdata.test_mask, ) # 用扰动后的图从零重训并评估 gcn.reset_parameters() pert_data copy.copy(data) pert_data.edge_index pert_edge_index train(gcn, pert_data) pert_acc test(gcn, pert_data) print(fPRBCD: Accuracy dropped from {clean_acc:.3f} to {pert_acc:.3f})注意验证阶段同样要reset_parameters()后重新训练才符合投毒影响后续训练的真实语义。由于重训练引入随机性示例注释提示投毒场景的数值波动比逃逸场景更大。利用 attack_statistics 绘制调试曲线示例最后用 matplotlib 绘制攻击过程的诊断曲线rbcd_attack_poisoning.py 第 126-144 行左轴红色实线每步loss右轴蓝色虚线/实线prob_mass_after_update投影前的边权概率质量与prob_mass_after_projection投影后实际使用的预算。这张图正是验证学习率应让预算尽快耗尽这一经验法则的工具若蓝线迟迟达不到预算上限说明学习率偏低攻击在松弛空间中徘徊、效率低下。深入 PGM 解释器用概率图模型解释 GNN 预测PGMExplainer实现了论文PGMExplainer: Probabilistic Graphical Model Explanations for Graph Neural NetworksarXiv:1903.03894源码位于 torch_geometric/contrib/explain/pgm_explainer.py。它生成的Explanation对象提供node_mask与pgm_stats两个核心输出其中pgm_stats保存了每个节点由Chi-squared 检验计算出的 p 值用于量化该节点对预测的影响显著性。PGMExplainer 核心参数参数默认值含义feature_indexNone被扰动的特征索引None表示扰动全部特征perturbation_moderandint特征扰动方式randint、mean、zero、max、uniformperturbations_is_positive_onlyFalse是否限制扰动值为正is_perturbation_scaledFalse是否归一化扰动特征的范围num_samples100用于显著性检验的扰动采样次数max_subgraph_sizeNone解释考虑的邻居节点数上限significance_threshold0.05p 值阈值低于该值判定节点对预测有显著影响pred_threshold0.1判断扰动后输出与原始输出不同的缓冲阈值各扰动模式的底层实现在 pgm_explainer.py 的 _perturb_features_on_nodesrandint将特征置为 0/1 随机值mean/zero/max分别用列均值、0、列最大值替换uniform则在0.05 * max(x)幅度内加均匀噪声。与 Explainer 框架的集成PGM 解释器不是独立运行的而是作为算法插件接入 PyG 的统一可解释性框架torch_geometric.explain.Explainer。调用时需同时配置ModelConfig声明任务类型multiclass_classification、任务层级node或graph与返回类型raw。实战三节点分类解释Coraexamples/contrib/pgm_explainer_node_classification.py 在 Cora 上训练一个两层 GCN关闭卷积内归一化改由T.GCNNorm()变换预处理然后解释节点 100 的预测explainer Explainer( modelmodel, algorithmPGMExplainer(), node_mask_typeattributes, explanation_typephenomenon, model_configModelConfig(modemulticlass_classification, task_levelnode, return_typeraw)) node_idx 100 explanation explainer(xdata.x, edge_indexedge_index, indexnode_idx, targetpredicted_target, edge_weightedge_weight) print(fSignificance of relevant neighbors: {explanation.pgm_stats})要点解析explanation_typephenomenon表示用模型预测结果而非真实标签作为解释目标因此传入targetpredicted_target训练采用F.nll_losslog_softmax输出与return_typeraw兼容解释器会自动提取目标节点的k_hop_subgraph邻域并执行扰动-显著性检验最终pgm_stats给出每个相关邻居的 p 值p 值低于significance_threshold默认 0.05的节点即为对预测起关键作用的邻居。实战四图分类解释MNIST Superpixelsexamples/contrib/pgm_explainer_graph_classification.py 将 PGM 解释器用于图级分类模型是带NNConv边属性为 2 维坐标差与graclusmax_pool分层池化的网络数据集为 MNIST 超像素图MNISTSuperpixels经T.Cartesian(catFalse)变换生成边属性。explainer Explainer( modelmodel, algorithmPGMExplainer(perturb_feature_list[0], perturbation_modemean), explanation_typephenomenon, node_mask_typeobject, model_configdict(modemulticlass_classification, task_levelgraph, return_typeraw))与节点分类示例的区别task_levelgraph解释目标是整张图node_mask_typeobject节点分类示例为attributes配合max_pool_x/global_mean_pool这类池化层perturb_feature_list[0]perturbation_modemean只扰动第一个特征超像素的 x 坐标用列均值替换扰动空间更小、解释更聚焦解释器对测试集的每张图逐一解释通过explanation.available_explanations遍历输出如node_mask、pgm_stats示例仅处理前 3 张图。测试覆盖如何验证这些实验性功能仓库在 test/contrib 下为这两类功能提供了配套测试可作为理解行为边界的参考test/contrib/nn/models/test_rbcd_attack.py覆盖 GRBCD/PRBCD 攻击的预算约束扰动边数不超过 budget、返回值形状等test/contrib/explain/test_pgm_explainer.py覆盖 PGM 解释器在不同perturbation_mode、不同任务层级下的输出结构。总结与实验路线本目录是理解 PyG 实验性功能的快速入口推荐按以下顺序动手运行 rbcd_attack.py对比 GAT 局部攻击与 GCN 全局攻击的输出观察置信度边界与准确率的下降调整lr、budget、block_size结合attack_statistics理解学习率-预算的关系运行 rbcd_attack_poisoning.py需先pip install higher观察双层优化下的投毒效果与诊断曲线依次运行两个 PGM 示例对比node_mask_type与task_level配置差异对解释输出的影响并尝试更换perturbation_mode观察显著性结果的变化。需要注意contrib 包内模块仍处于演进阶段其 API 可能随版本调整若在后续版本中遇到 API 变更请以当前仓库源码与 CHANGELOG 为准。【免费下载链接】pytorch_geometricGraph Neural Network Library for PyTorch项目地址: https://gitcode.com/GitHub_Trending/py/pytorch_geometric创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考