SQuaDE ViT-g

冻结 DINOv2 ViT-g + 两组各三个专家头。干净图在第 27 个 block 提前退出, 省约 18% 前向深度。为 NTIRE 2026 Robust AIGI Detection 训练。

骨干不在本仓库内,运行时从 facebook/dinov2-giant 加载。本仓库只有专家头与门。

当前推荐 v3/。


快速推理

git clone https://github.com/kelvinchua1099-alt/SQuaDE && cd SQuaDE
pip install -r requirements.txt

huggingface-cli download kelvinchua/squade-vitg --local-dir ckpt

python Inference.py --dir /path/to/images \
  --shallow ckpt/v3/mix2_shallow \
  --deep    ckpt/v3/mix2_deep \
  --gate    ckpt/v3/mix2_gate.pt \
  --out preds.csv

单张图把 --dir 换成 --image a.jpg。

输出

image                   score     label  route    experts       votes              ms_per_img
002d7df53e3ae55af5.jpg  1.000000  1      deep     L26/L33/L37   1.000|1.000|0.955  684
0053097bfa680600.jpg    0.000000  0      shallow  L14/L21/L27   1.000|0.000|0.000  684
列 含义
score 0~1,越大越可能是 AI 生成
label score > 0.5 时为 1(假)
route 走了哪一组专家
experts 该组的三个抽头层
votes 组内三个专家各自的概率
vote_spread 三票最大差。大 = 这张图在决策边界上,最值得人工复核
depth_used 实际跑了多少个 block(27 或 37)
gate_logit 门的输出,≤0 判「干净」走浅组
ms_per_img 每张图耗时

常用参数

--batch-size 8        # 24 GB 显存下可到 16
--no-early-exit       # 两组都算完再按门选。精度相同,用来核对提前退出没改变结果
--device cpu          # 慢很多,应急用

成绩

只报 held-out。官方 val 的 70% 与 val_hard 的 70% 参与了训练,划分文件 (val_split_70_30.json / valhard_split_70_30.json)随权重一起发布,可自行核验。

v3(当前)

数据 方案 全量 clean robust
官方 val held-out (3,000) shallow-only 0.9922 0.9978 0.9833
±SE 0.23 gated route 0.9911 0.9977 0.9809
官方 val_hard held-out (750) shallow-only 0.9430 0.9904 0.8674
±SE 1.8 gated route 0.9423 0.9857 0.8781

三个版本

口径 v1 v2 v3
val_hard held-out robust — 0.8068 0.8674
val_hard held-out 全量 — 0.9111 0.9430
val held-out robust 0.9629 0.9830 0.9833
门 AUC(val_hard) 0.7684 0.9072 0.9464

v1 训练时 val_hard 尚未划分,无对应的 held-out 数。

改动

  • v1 → v2:训练集配比(NTIRE 从 11.4% 提到 37.9%)、退化强度(我们的档位掺入一半 官方 distortion_range)、并入官方 val 的 70%。三者贡献未拆分。
  • v2 → v3:并入官方 val_hard 的 70%(1,750 行),从 v2 权重热启动 8 轮 @ lr 1e-4。 val_hard held-out 上 robust +6.06,同时 val held-out 未退化(+0.03)。

robust = 只在退化图上算,是竞赛主指标。gated route 相对全深度省约 18% 前向深度。


输入尺寸怎么处理

推理与训练用同一套规则。不一致等于给测试集加一层没记录在案的域偏移,且不会报错。

短边 >= 512   中心裁 512x512,一次重采样都不做
短边 <  512   先裁成正方,再用随机挑的一个内核上采样到 512
              内核池 [BILINEAR, BICUBIC, BOX, LANCZOS],按图名确定性挑

之后送进骨干时中心裁到 504(patch=14 的整数倍),同样不 resize。 Inference.py 自动完成。


已知局限

  1. 两份官方评测集都已被部分用于训练。 只剩 3,000 + 750 张 held-out, 而 750 张的 SE 是 ±1.8 点 —— 小于 3~4 点的差异读不出来。唯一完全干净的是官方 test。
  2. 抽头层是在官方 val / val_hard 上选的。 从 41 层里选 3 层,信息量小但不是零。
  3. 门在原生低分辨率来源上会失效。 它学到的偏向「图糊不糊」而非「有没有施加过 退化算子」;实测 200×200 上采样的图里 82% 被判成退化,省下的算力掉到 5.8%。
  4. 训练集的真图缺少「手机随手拍 + 多次转发重压缩」这一类。 真图来自图库与 OpenImages,偏专业摄影;对低画质真实照片的表现未经检验。
  5. 一部分训练数据的「干净档」并不真干净 —— 源图本身是 JPEG,自带未记录的压缩。

被本项目否定的假设

原始主张是「不同退化杀死不同深度的取证线索,所以最优读取深度是退化状态的函数」。 经 13 项独立测量全部不成立。最干净的一次(val_hard 内部折外交叉拟合、完整桶尺寸、 无分布偏移)净增益 +0.117 点,置换检验 p = 0.323。

站得住的是多深度均匀融合(集成方差缩减:在官方数据上比最强单专家高 1.67~5.89 点) 与干净/退化二元门控提前退出(省约 18% 算力)。

退化与标签在训练集里严格独立(交叉表核验:干净/退化两侧的假图占比均为 50.07%, 只用「是否退化」这一位去猜真假的 AUC = 0.5000),不存在「退化痕迹 → 假」的构造性泄漏。


文件

v3/mix2_shallow/stage1.pt   浅组 L14/L21/L27 + 标准化统计量   ← 推荐
v3/mix2_deep/stage1.pt      深组 L26/L33/L37 + 标准化统计量
v3/mix2_gate.pt             二元门,读浅组特征
v3/val_split_70_30.json     官方 val 的固定划分(held 永不参与训练)
v3/valhard_split_70_30.json 官方 val_hard 的固定划分
v2/, v1/                    更早两版,保留对照

MIT。DINOv2 权重另有其许可条款。

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support