veil-pgd / scripts /build_eval_data.py
Klaus Clawd
Release v0.2.1: recover attack strength, cross-arch judges, uncapped frontier eval
255b4a8
Raw
History Blame Contribute Delete
2.78 kB
"""Build the v0.2 evaluation data from Imagenette (permissive, no auth):
1. An EXEMPLAR pool -> examples/exemplars/<class_word>/*.jpg (for M4 centroids)
2. An ATTACK set -> examples/testset60/ + examples/testset60.csv
The two splits are disjoint per class (exemplars taken first, attack images taken
after), so decoy/truth feature centroids are never computed from an attacked image.
Usage (run on a box with `datasets`):
python scripts/build_eval_data.py --exemplars 24 --attack 6 --split validation
"""
from __future__ import annotations
import argparse
import csv
from pathlib import Path
IMAGENETTE_TRUTH = {
0: "tench", 1: "english springer", 2: "cassette player", 3: "chainsaw",
4: "church", 5: "french horn", 6: "garbage truck", 7: "gas pump",
8: "golf ball", 9: "parachute",
}
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("--exemplars", type=int, default=24, help="imgs/class for centroid pool")
ap.add_argument("--attack", type=int, default=6, help="imgs/class for the attack set")
ap.add_argument("--split", default="validation")
ap.add_argument("--exemplar-dir", default="examples/exemplars")
ap.add_argument("--attack-dir", default="examples/testset60")
ap.add_argument("--manifest", default="examples/testset60.csv")
args = ap.parse_args()
from datasets import load_dataset
ds = load_dataset("frgfm/imagenette", "320px", split=args.split)
ex_root = Path(args.exemplar_dir)
at_root = Path(args.attack_dir)
at_root.mkdir(parents=True, exist_ok=True)
seen: dict[int, int] = {}
rows: list[tuple[str, str]] = []
need = args.exemplars + args.attack
for ex in ds:
lbl = int(ex["label"])
k = seen.get(lbl, 0)
if k >= need:
continue
truth = IMAGENETTE_TRUTH[lbl]
img = ex["image"].convert("RGB")
if k < args.exemplars:
d = ex_root / truth.replace(" ", "_")
d.mkdir(parents=True, exist_ok=True)
img.save(d / f"{k:02d}.jpg", quality=95)
else:
j = k - args.exemplars
fp = at_root / f"{lbl:02d}_{j:02d}.jpg"
img.save(fp, quality=95)
rows.append((str(fp), truth))
seen[lbl] = k + 1
if all(seen.get(i, 0) >= need for i in IMAGENETTE_TRUTH):
break
with Path(args.manifest).open("w", newline="") as f:
w = csv.writer(f)
for path, truth in rows:
w.writerow([path, truth])
ex_total = sum(min(v, args.exemplars) for v in seen.values())
print(f"exemplars: {ex_total} imgs across {len(IMAGENETTE_TRUTH)} classes -> {ex_root}")
print(f"attack set: {len(rows)} imgs -> {at_root} + {args.manifest}")
if __name__ == "__main__":
main()