SaadH-077/TML-Watermark-Forging
GitHub: SaadH-077/TML-Watermark-Forging
该项目复现了 TML 2026 水印伪造任务的最佳参赛方案,通过识别八种水印方案并使用其原生编码器重新嵌入信息来实现跨图像水印移植。
Stars: 0 | Forks: 0
# TML 2026 · 任务 4,水印伪造,team_V
通过**方案识别和原生重新编码**伪造图像水印。本仓库是一个
自包含的软件包,它**重现了我们在排行榜上最佳的提交结果**,并记录了**我们的实现过程**。
它只提供必要的文件,没有虚拟环境,也没有庞大的模型库。
**最佳公开得分:`S_final = 0.8553`**(所有 8 种方案均通过原生重新编码进行伪造)。
## 任务说明
对于 8 种未知水印方案 `WM_1..WM_8`,我们分别获得了 25 张带有水印的*载体*图像,它们
都携带着**同一条**共享的隐藏信息。我们必须将该水印移植到 25 张指定的干净*目标*
图像上(不同的图像,真正的移植),以便隐藏的检测器能读取该信息,同时
保持每张图像在感知上与目标图像高度相近。`WM_k` 对应的目标是 `25(k−1)+1 .. 25k`。
分数计算公式为 `S_final = S_det · S_qlt`,其中 `S_det = max(0, 2·(bitacc − 0.5))` 且
`S_qlt = exp(−8·LPIPS)`。LPIPS 可以在本地测量;而 bit-accuracy 则不行(因为没有公开的检测器),
因此唯一的检测信号就是排行榜(每 60 分钟提交 1 次,保留最佳成绩,30% 公开可见)。
## 我们的一句话方案
**识别每种方案,然后使用该方案自身的真实编码器将恢复的信息重新嵌入**,这样
伪造的水印*就是*一个真正的水印(bit-accuracy 为 1.0,并且具有泛化能力)。盲加移植在
频域和内容自适应的水印上会失败。我们成功识别了**全部 8 种方案**;第八种(WM_3)耗时最长,
这是一种抵抗平均攻击的内容自适应学习水印,但它是 **ArtificialGANFingerprints**
(一个 StegaStamp 自动编码器),我们通过解码一致性识别了它,并使用匹配的编码器进行了重新嵌入。
### 我们针对每种水印的操作
| WM | 目标 | 方案(编码器) | 我们的伪造方式 | LPIPS / S_final |
|----|---------|------------------|------------------|-----------------|
| WM_1 | 1–25 | **dwtDct** (`invisible-watermark`), 30-bit | 从 25 个载体中解码出共享信息,并使用真实的 dwtDct 编码器将其重新嵌入到每个目标中,然后在 `s=1.5` 下对伪造水印进行残差放大(`clip(T + s·(F0−T))`),以扩大 QIM 量化边际,从而抵御服务器预检测变换。 | 0.006 / 0.89 |
| WM_2 | 26–50 | **RivaGAN** (`invisible-watermark`), 32-bit | 解码出 32-bit 信息,并使用真实的 RivaGAN 编码器将其重新嵌入。其 0.016 的 LPIPS 是编码器固有的,也是原生方案中的质量下限。 | 0.016 / 0.86 |
| WM_3 | 51–75 | **ArtificialGANFingerprints** (StegaStamp), 100-bit | 抵抗平均攻击的内容自适应学习水印;我们最初认为无法识别(排除了约 27 种解码器),直到在原生 256² 分辨率下进行的解码一致性扫描匹配到了公开的 AFHQ cat2dog checkpoint(载体一致性 0.9996,干净图像 ≈0.48)。我们对 100-bit 信息进行多数投票,并使用匹配的编码器进行重新嵌入(`clip(y+a·r)`),为每张图像选择强度 `a`,以最大化 AlexNet 和 VGG LPIPS 骨干网络的最差情况表现。 | 0.024 / 0.67–0.78 |
| WM_4 | 76–100 | **VINE-R** (ICLR 2025), 100-bit | 使用发布的 VINE 解码器解码出 100-bit 信息,并使用真实的 VINE-R 编码器(基于 SDXL-Turbo,单步;支持 GPU,带有 CPU 回退垫片)在原生 256² 分辨率下重新嵌入。 | 0.003 / 0.94 |
| WM_5 | 101–125 | **CIN** (ACM MM 2022), 30-bit | 解码出一致的 30-bit 信息,并使用真实的 CIN 编码器在原生 128² 分辨率下重新嵌入。 | 0.001 / 0.99 |
| WM_6 | 126–150 | **MBRS** (ACM MM 2021), 256-bit | 解码出一致的 256-bit 信息,并使用真实的 MBRS 编码器在原生 256² 分辨率下重新嵌入。 | 0.002 / 0.96 |
| WM_7 | 151–175 | **TrustMark-Q**, 61-bit | 使用 pip `trustmark` 变体 Q 解码出信息,并使用真实的 TrustMark-Q 编码器在原生 512² 分辨率下重新嵌入。 | 0.001 / 0.99 |
| WM_8 | 176–200 | **TrustMark-P** (`use_ECC=False`), 100-bit raw | 与 WM_7 属于同一家族但变体不同;直到我们尝试在禁用纠错的情况下使用变体 P 才匹配成功。解码出 100-bit 原始信息,并使用真实的 TrustMark-P 编码器在原生 512² 分辨率下重新嵌入。 | 0.001 / 0.99 |
所有八个伪造结果都是真正的原生重新编码,因此它们都能以极高的 bit-accuracy 解码(对于有公开解码器的七种方案为 1.0,WM_3 的平均值为 0.96),并且在公开/私密的划分上具有泛化能力。既然 WM_3 现在也是原生编码,距离排行榜榜首剩余的差距就在于公开编码器的质量和鲁棒性,而不是缺失了方案。
## 重现最佳提交(单条命令,离线执行)
```
pip install -r requirements.txt
python3 build_best.py
# -> submissions/candidate_best.zip (200 个扁平 PNG,1.png..200.png)
```
`build_best.py` 需要 `data/extracted/clean_targets/` 下的 200 个干净目标(用于 WM_1
残差放大和各方案的 LPIPS 表),以及 `forged_native_masked/` 下的八个原生伪造结果。
所有八个伪造结果(包括 WM_3)都已经固化在那里,因此脚本只需
加载它们,将 WM_1 以 `s=1.5` 放大,组装 200 张图像,验证 flat-zip 契约,并打印
各方案的 LPIPS / `S_qlt` 表格。要从头重新推导 WM_3 的伪造结果,请运行
`python3 encoders/afgf_wm3_encode.py`(自包含,自动下载 AFGF 权重;可逐字节
复现已固化的 `forged_native_masked/WM_3/`)。
## 提交
```
echo "TML_API_KEY=" > .env
python3 -m src.submit submissions/candidate_best.zip --yes
```
Endpoint `POST http://34.63.153.158/submit/22-forging-task`;每 60 分钟提交 1 次,保留最佳成绩。
Leaderboard: 。请提供您自己的 API key,本仓库不包含任何 key,并且
`.env` 文件已被 git-ignore。
如果不加 `--yes`,`src/submit.py` 将执行一次 dry run,验证 zip 和 key 但不会提交。
## 本仓库包含的内容
```
build_best.py # the reproduce script (one command, offline)
requirements.txt # pip dependencies (numpy, torch, torchvision, lpips, Pillow, ...)
fetch_data.py # optional: re-download the full course dataset from Hugging Face
report/report.pdf # the report (approach + results); report.tex is the LaTeX source
HOW_WE_GOT_HERE.md # readable narrative of the strategy, what worked, and what didn't
EXPERIMENT_LOG.md # full experiment & decision log: every submission, number, and lesson
src/wmforge.py # core forging library + the WM_1/2/7 encoders/decoders
src/submit.py # leaderboard submit + score reader (dry-run by default)
encoders/ # how each native forge was produced; afgf_wm3_encode.py is self-contained
forged_native_masked/ # the 8 native forge outputs (25 PNGs each), inputs to build_best.py
data/extracted/ # clean_targets (200) + watermarked_sources/WM_3 (25 carriers)
```
## 未包含的内容(大型 artifacts)
为了保持包的轻量化,我们省略了各方案的模型库(`*_repo`)、所有虚拟环境、
完整的 `data/Dataset.zip`、备选候选提交以及 AFGF checkpoints(由
`encoders/afgf_wm3_encode.py` 自动下载)。所有八个原生伪造结果都已经固化在 `forged_native_masked/` 下,因此
`build_best.py` 只需干净的目标图像即可离线运行。如果您想使用 `encoders/` 脚本从头重新推导原生伪造结果,请运行 `python3 fetch_data.py` 下载所有 8 种方案的载体图像。
请从 **`HOW_WE_GOT_HERE.md`** 阅读叙事过程,`EXPERIMENT_LOG.md` 查看完整日志,以及
`report/report.pdf` 查看书面报告。
标签:人工智能竞赛, 信息隐藏, 凭据扫描, 图像处理, 数字水印, 深度学习, 逆向工具