判定:尚不确定
数据源与对照规模:CIFAR-10 测试集(每个「预算档 × 种子」组合抽 128 张,并过滤到代理模型与 4 个目标模型全部分类正确),6 个实验臂(3 种攻击 × 2 个梯度预算档 36/72)× 3 个种子,纯 CPU 234 秒
主要结论:判定 inconclusive:预测的第一步前提在缩小版设置里就没复现。预测原本是「相同迭代数下平坦极值攻击领先 MI-FGSM ≥5pp,改成相同梯度调用预算后缩到 ≤2pp 或反转」,实测第一段只有 +3.29pp,没过它自己设的 5pp 线,所以第二段那个更尖锐的问题这一轮答不了。
这些结果不支持:不支持「平坦极值攻击没有优势」,也不支持「优势是算力堆出来的」——两个方向本轮都没有证据。不支持任何 ImageNet 规模、防御模型或真实部署场景的结论。
代码 / 原始结果 / 日志:代码、原始 results.json、运行日志、图齐全;含第二版独立复核记录(更正了附件里一处抄写错误,并补做了此前缺失的空模型对照)。
提交方向: 对抗样本迁移性 交付时间: 2026-07-30 · 第二版更正 2026-07-31 这一轮真跑了: CIFAR-10 测试集(10000 张;每个「预算档 × 种子」组合抽 128 张,并过滤到代理模型与 4 个目标模型全部分类正确)· 6 个臂(3 种攻击 × 2 个梯度预算档 36 / 72)· 3 个种子(0 / 1 / 2)· 纯 CPU 总耗时 234 秒,代码、日志、图、原始 results.json 随附
我们对第一版做了一次独立复核,改了四处。均值、方向、inconclusive 判定全部不变,改的是附件里的一处抄写错误和三处口径没写透的地方。
NOTES.md 结果表里,平坦化臂的种子标准差抄错了两格:gb36 应为 4.16pp(写成了 4.3pp),gb72 应为 2.52pp(写成了 1.7pp);同一个 4.3pp 在该文件正文里还重复了一次,一并更正。主报告、results.json 和全部结论用的都是正确值,所以这是附件内部的数字冲突,不影响任何结论——但既然发现了就主动说明。fwd_bwd_calls 的准确含义(见第 1 节)。它只计攻击生成阶段,不含后置诊断梯度;同预算两臂依然严格对齐。我们的预测既没被证实、也没被推翻,判定是 inconclusive——原因是这个预测的第一步前提在我们的缩小版设置里就没复现出来。 预测原本是两段:(A) 按文献惯用的「相同迭代数」比,PGN 式平坦极值攻击应该领先 MI-FGSM ≥5 个百分点;(B) 改成「相同梯度调用预算」后这个优势会缩到 ≤2 个百分点或反转。跑出来 (A) 只有 +3.29pp(两个预算档 × 3 种子共 6 次运行池化),没过它自己设的 5pp 线——要被我们缩掉的那个优势本来就不大,所以 (B) 这个更尖锐的问题这一轮没法干净回答。
同预算(B 段)的实际数字是 +3.45pp,但 6 次运行里有 2 次为负(逐次差值 +5.27 / −5.66 / −1.37 / +10.4 / +4.69 / +7.42 pp),按预注册规则(≥5pp 且每个种子都为正)也够不上「预测被推翻」。它对预算敏感:grad_budget=72 时 PGN 迁移成功率 73.0% vs 同预算 MI-FGSM 65.5%(+7.49pp);grad_budget=36 时 PGN 65.6% vs 66.1%,方向都不一致。
一个我们没预期到的次要发现:平坦度指标朝反方向动了。 PGN 生成的对抗样本邻域梯度范数(越小越平坦)是 77.7 / 71.0,比两个 MI-FGSM 臂的 57.2–62.8 更大——按这个口径,它的样本落在更不平坦的地方。所以本轮在 gb=72 观察到的那点迁移优势,用「平坦极值」这套机制解释不了。
下一步该往哪拐:别把「同预算下优势消失」当结论去写,本轮不支持;把内层采样数 N 和梯度调用预算 B 一起当自变量扫成曲线(我们只跑了 N=3、B∈{36,72} 三个点),这才是这条线真正没被锁住的自由变量。详见第 3 节。
设计一句话:固定每张图允许的 fwd+bwd 次数(梯度调用预算),让 PGN 式平坦化攻击和 MI-FGSM 在完全相同的算力下比迁移成功率;同时保留文献惯用的「相同迭代数」对照,用来确认能不能复现出文献报的增益方向。代理模型 cifar10_resnet20,目标模型 cifar10_vgg11_bn / cifar10_mobilenetv2_x1_0 / cifar10_shufflenetv2_x1_0 / cifar10_repvgg_a0(权重全部来自 chenyaofo/pytorch-cifar-models)。ε = 0.0314(= 8/255,results.json.diagnostics.eps)。
两个 baseline,缺一个都不成立:
baseline-mi-equal-steps:MI-FGSM,迭代数与 PGN 臂相同,因此只花 PGN 六分之一的梯度调用(gb36 档 6 次、gb72 档 12 次)。这就是文献惯用的、对 PGN 有利的口径,故意保留。baseline-mi-equal-budget:MI-FGSM,迭代数拉到与预算相等,花掉和 PGN 完全一样的梯度调用(36 / 72 次)。这是真正的算力对齐对照。为什么这个对照公平:同一种子内三臂用同一批 128 张图(配对比较)、同一 ε、同一步长规则(α = 2.5ε/T,不给任何一臂额外调参空间)、同一动量衰减(decay=1.0,diagnostics.pgn_hyperparams),唯一区别是算力怎么花——花在「更多迭代」还是「每步更多邻域采样」。每臂实际消耗的梯度调用次数都写进了结果(fwd_bwd_calls),可以直接核对算力有没有真对齐。
fwd_bwd_calls 的准确口径(第二版更正):这个字段记的是攻击生成阶段的反向调用数,不含每臂跑完后固定的 5 次平坦度诊断梯度,也不含评测成功率的前向。用计数器包住 torch.autograd.grad 实测,含诊断的实际反向调用是:gb36 档 同迭代数 11 / 同预算 41 / 平坦化 41;gb72 档 17 / 77 / 77。同预算两臂依旧严格对齐(41 = 41、77 = 77),所以算力对齐这个结论不受影响;但原文「每臂实际消耗」这个措辞过宽,这里更正。字段名下一版会改成 attack_gradient_calls。
统计口径(第二版补全,这三条原文没写透): ① 表里的离散度是 np.std 默认的总体标准差(ddof=0),不是样本标准差;3 个种子下两者差别不小(例:平坦化臂 gb36,ddof=0 是 4.16pp,ddof=1 是 5.10pp),所以口径必须写明。 ② 「六个预算×种子单元」不是六批独立样本:同一个种子在 gb36 和 gb72 会重新抽到完全相同的 128 张图,所以是三批独立抽样 × 两个预算档的重复测量。本轮没有做任何显著性声明,结论不受影响,但下一版报里必须写清楚。 ③ 池化方式:单次迁移率 = 四个目标模型误分类率等权平均;档内均值 = 三种子等权平均;+3.29pp / +3.45pp = 六个「预算×种子」配对差值等权平均。
主结果表(数值全部抄自 work/results.json;离散度为 3 个种子的标准差,单位 pp):
| 臂 | 梯度调用数 | 指标 | 种子 0 / 1 / 2 原始值 | 均值 ± 离散度 |
|---|---|---|---|---|
baseline-mi-equal-steps gb36 | 6 | transfer_success_rate | 64.5% / 65.6% / 67.2% | 65.8% ± 1.12pp |
baseline-mi-equal-budget gb36 | 36 | transfer_success_rate | 65.6% / 66.4% / 66.4% | 66.1% ± 0.368pp |
pgn-flat-maxima gb36 | 36 | transfer_success_rate | 70.9% / 60.7% / 65.0% | 65.6% ± 4.16pp |
baseline-mi-equal-steps gb72 | 12 | transfer_success_rate | 66.4% / 66.0% / 66.2% | 66.2% ± 0.159pp |
baseline-mi-equal-budget gb72 | 72 | transfer_success_rate | 66.0% / 65.6% / 64.8% | 65.5% ± 0.487pp |
pgn-flat-maxima gb72 | 72 | transfer_success_rate | 76.4% / 70.3% / 72.3% | 73.0% ± 2.52pp |
完整性检查与中介变量(同一批对抗样本):
| 臂 | whitebox_success_rate 均值 | neighborhood_grad_norm 均值(越小越平坦) |
|---|---|---|
baseline-mi-equal-steps gb36 | 100% | 58.5 |
baseline-mi-equal-budget gb36 | 100% | 61.3 |
pgn-flat-maxima gb36 | 98.2%(种子 100% / 96.9% / 97.7%) | 77.7 |
baseline-mi-equal-steps gb72 | 100% | 57.2 |
baseline-mi-equal-budget gb72 | 100% | 62.8 |
pgn-flat-maxima gb72 | 99.2% | 71.0 |
neighborhood_grad_norm 的口径(采样半径与采样点数)见随附 SCOPE.md 第 4 节。
gb=72 档的分目标模型迁移成功率(均值;gb=36 档的分项在 results.json 里):
| 臂 | vgg11_bn | mobilenetv2_x1_0 | shufflenetv2_x1_0 | repvgg_a0 |
|---|---|---|---|---|
baseline-mi-equal-steps | 26.3% | 85.2% | 72.1% | 81.3% |
baseline-mi-equal-budget | 22.4% | 85.4% | 71.9% | 82.3% |
pgn-flat-maxima | 32.6% | 90.6% | 79.7% | 89.1% |
vgg11_bn 明显是四个目标里最难打的一个(22.4%–32.6%),另外三个都在 71.9%–90.6%。任何只报「平均迁移率」的表都会把这个差异抹掉——你自己的表建议保留分项。
空模型对照(第二版补做,原版缺这一环)。 上面那些 65%–73% 的迁移成功率,得先排除一个平凡解释:会不会样本本来就脆,随便加点噪声也能打掉?我们用同一批筛选后的图、同一个 ε=8/255 预算跑了两个对照:
| 对照臂 | 迁移成功率(三种子) | 均值 |
|---|---|---|
| 完全不攻击(原图直接送目标模型) | 0% / 0% / 0% | 0% |
| 均匀随机 L∞ 噪声(同 ε 预算,不看梯度) | 2.73% / 1.95% / 3.91% | 2.86% |
| 攻击臂(参考) | — | 65.5%–73.0% |
不攻击是 0%(样本筛选保证了这点:只收代理和四个目标全部分类正确的图),随机噪声只有 2.86%,和攻击臂差一个数量级以上。所以那些迁移率来自梯度信息,不是样本脆或者评测口径松。对照脚本随附(work/control_check.py),max_linf 实测 0.0314,确认噪声吃的是同一个预算。

figs/ 目录。这些数支持的结论(三条)。
pgn gb72,73.0%)邻域梯度范数 71.0,而范数最小、也就是最「平坦」的臂(mi-equal-steps gb72,57.2)迁移只有 66.2%。6 个数据点,只能说方向和机制叙事相反,不能给相关强度。这些数不支持的结论(必须写清楚)。
inconclusive,negative_result = false——预测既没被证实也没被推翻。diagnostics.pgn_hyperparams.N = 3),原文用 20;这是 SCOPE 里事先声明的缩小,不是看到结果后改的。放大后可能变的地方。 最可能翻盘的是采样数:N 从 3 提到原文的 20,PGN 每迭代的算力代价×20/3,同预算下迭代数被压得更狠,「同预算优势消失」的假设反而更可能成立——但也可能相反,因为邻域梯度估计的方差会显著下降。我们没扫 N,所以这只是待验的猜想,不是结果。其次是图数(128 张)和种子数(3),把离散度打下来才能谈显著性。
偏离交代。 results.json.deviations 是空数组——本轮没有临场降规模的偏离,128 张图 / 3 个种子 / 两个预算档 / 3 个臂全量跑完了。但有四件事口径上必须说明,它们不在 deviations 字段里:
out_of_scope 事先声明过。这一条直接决定了本轮判定为 inconclusive,是最重要的一条。zeta=3.0、chi=0.0314、balance=0.5、decay=1.0(全部记在 diagnostics.pgn_hyperparams)。取 decay=1.0 与 MI-FGSM 一致,是为了让臂间唯一的结构差异是平坦化的梯度合成方式,而不是动量。results.json.dataset 记的是「torchvision-format via HF parquet mirror」,而 SCOPE 计划里写的是 torchvision.datasets.CIFAR10(download=True)。官方源实测太慢会吃掉大半算力预算,改用 HuggingFace 的 parquet 镜像;是同一份 CIFAR-10 测试集(10000 张)。env.extra_packages 里多出来的 pyarrow==25.0.0 就是为读它装的。这条没被记进 deviations,但口径变了,照说。还有一条完整性折扣:PGN 臂的白盒成功率没打满(98.2% / 99.2%),两个 MI-FGSM 臂在所有预算和种子上都是 100%。按 SCOPE 自己给这个指标写的解读规则,白盒没完全打透的臂,它的迁移数字要打折扣读。我们把它挑出来,而不是盖过去。
值得投的一步(最短路径):把「梯度调用预算」和「内层采样数」当成两个主自变量,扫成曲线,而不是报单点。 本轮最有信息量的不是任何单个数字,而是「换个预算档,结论就翻」这个现象——它正好说明文献里「相同迭代数、单一预算」的比法会遮住什么。这条路子和 SCOPE 第 2 节里那个「同梯度调用预算下还剩多少增益」的缺口是同一件事,但本轮告诉你它的正确形态是曲线,不是一张表:横轴梯度调用预算,每条线一个 N,同时画平坦化臂和同预算 MI-FGSM。有了曲线,「优势在哪个算力区间存在」就是一个可陈述的结论,而不是一场关于「你为什么选这个预算」的争论。
先别投的两步。 一是别提新的平坦性正则——SCOPE 第 1 节已经说明这条线方法数量饱和(公共基线库里同类方法几十个),涨点的路线会被「你和同类的 20 个方法比过了吗」直接卡住。二是别急着做鲁棒代理模型上的条件性地图(SCOPE 第 2 节缺口 3):它工作量最大、必须准备多个不同鲁棒强度的对抗训练代理,得先有 GPU;而缺口 1 的曲线版本才是能用你现有算力立住的部分,且做完之后正好是缺口 3 的方法学基础。
审稿人最可能打的三处(SCOPE 第 3 节已给出防法,这里只说本轮新增的三点具体证据)。
+3.29pp 恰好演示了自己实现的版本会离文献报的增益有多远,这个坑请不要重踩。另外一个顺手可捡的点:第 2 节那个「平坦度朝反方向动」的观察,正好是 SCOPE 第 2 节缺口 2(把平坦性当中介变量做定量分析)的入口。这类工作的加分项是把度量定义写死(邻域半径、采样点数、范数),让别人能复现——我们已经把定义和实现都放在随附代码里,可以直接拿去当起点或者拿去反驳。
| 文件 | 是什么 |
|---|---|
work/attack_experiment.py | 全部实验代码:三个臂的攻击实现、样本筛选、指标计算、预注册的推翻判定逻辑、画图 |
work/run.sh | 一条命令复现:bash run.sh。内含数据自动下载(data/ 缺失时拉 CIFAR-10 测试集 parquet)和固定参数 --grad-budgets 36,72 --seeds 0,1,2 --n-images 128 |
work/logs/run.log | 完整运行日志,带时间戳。18 次(臂 × 预算 × 种子)运行的逐次 whitebox / transfer / 分目标 / 邻域梯度范数 / 实际梯度调用数 / 耗时,以及末尾的推翻判定输出 |
work/results.json | 原始结果。本报告里每一个数字都能在这里查到 |
work/figs/transfer_and_flatness.png | 左:三臂在两个预算档的迁移成功率(带种子误差棒);右:邻域梯度范数 vs 迁移成功率散点 |
work/NOTES.md | 实验手记:遇到的问题、计划里没指定而由我们选定的超参、判定过程 |
work/control_check.py | 空模型对照(第二版补做):不攻击 / 同预算随机噪声两条基线,用来排除「样本本来就脆」这个平凡解释 |
SCOPE.md | 上一段交付的方向判断与文献查新(第 5 节要点摘录) |
环境与可复现性。 Python 3.12.3、torch 2.13.0+cpu(纯 CPU,无需 GPU)、额外依赖 pyarrow==25.0.0;种子固定为 0 / 1 / 2,种子同时控制抽图和内层采样噪声;OMP_NUM_THREADS=2。全流程 234 秒跑完,bash run.sh 可重跑。一处需要你改:run.sh 里的 PY= 是我们机器上的解释器绝对路径,换成你自己的 python 即可,其余不用动。
我们不要你的数据、代码或稿子。 上面所有证据都是用公开数据集(CIFAR-10 测试集)和公开预训练权重(chenyaofo/pytorch-cifar-models)自己造的,任何人都能独立复查,也能独立推翻。
参考来源(原样保留):
本文档由 JouleBeat · DeepGraph 出具。实验代码、日志与原始结果随附,结论可被复查与反驳。