Download code/scripts/robust.py from changh95/hamer-p150: direct link, hf CLI and curl.
- Browser
- Download file 3.82 kB
-
https://huggingface.co/changh95/hamer-p150/resolve/main/code/scripts/robust.py
- Command line
-
hf download hf://changh95/hamer-p150/code/scripts/robust.py
-
curl -L -o robust.py https://huggingface.co/changh95/hamer-p150/resolve/main/code/scripts/robust.py
3.82 kB
| # SPDX-License-Identifier: Apache-2.0 | |
| """Round 9: robustness sweep -- device vs CPU fp32 reference on out-of-distribution versions of the 8 annotated | |
| hands (dark, bright, low contrast, gaussian noise, salt-and-pepper, blocky) plus pure random uint8 crops (what the | |
| server warm-up gate uses). Same served TtHamer path as acc.py; model knobs from the environment. | |
| usage: robust.py [--ref-cache PATH] prints per-group mean / min PCC and ``ROBUST {json}``""" | |
| from __future__ import annotations | |
| import argparse, json, os, sys | |
| from pathlib import Path | |
| _REPO = Path(__file__).resolve().parents[1] | |
| sys.path.insert(0, str(_REPO)) | |
| def inputs(): | |
| import torch | |
| from hamer.preprocess import preprocess_pil, normalize_raw | |
| from PIL import Image | |
| media = _REPO.parent / "media" | |
| boxes = json.loads((media / "bboxes.json").read_text()) | |
| g = torch.Generator().manual_seed(7) | |
| out = [] | |
| for name in sorted(boxes): | |
| img = Image.open(media / name).convert("RGB") | |
| for hi, e in enumerate(boxes[name]): | |
| u, _ = preprocess_pil(img, tuple(e["bbox"]), is_right=bool(e.get("is_right", 1)), raw=True) | |
| f = u.float() | |
| var = { | |
| "dark": f * 0.25, | |
| "bright": f * 1.8, | |
| "lowcon": 128 + (f - 128) * 0.3, | |
| "noise25": f + 25 * torch.randn(f.shape, generator=g), | |
| "saltpep": torch.where(torch.rand(f.shape, generator=g) < 0.05, | |
| 255 * (torch.rand(f.shape, generator=g) < 0.5).float(), f), | |
| "blocky": torch.nn.functional.interpolate(torch.nn.functional.avg_pool2d(f, 16), scale_factor=16), | |
| } | |
| for k, v in var.items(): | |
| out.append((f"{k}:{name}#{hi}", v.round().clamp(0, 255).to(torch.uint8))) | |
| for i in range(8): | |
| out.append((f"random:{i}", torch.randint(0, 256, (1, 3, 256, 192), generator=g, dtype=torch.uint8))) | |
| return [(n, u, normalize_raw(u)) for n, u in out] | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--ref-cache", default=str(Path(os.environ.get("TMPDIR", "/tmp")) / "hamer_robust_ref.pt")) | |
| a = ap.parse_args() | |
| os.environ.setdefault("TT_FUSED_HASH", "0") | |
| import torch | |
| from hamer import Hamer, build_from_reference, load_hamer_checkpoint | |
| hf = Path.home() / ".cache/huggingface/hub/models--changh95--hamer-weights/snapshots/e8217b46d54b4e8afaaf0dd6efb6b62341c97d32" | |
| ref = Hamer().eval() | |
| load_hamer_checkpoint(ref, hf / "hamer.ckpt", hf / "mano_mean_params.npz") | |
| xs = inputs() | |
| cache = Path(a.ref_cache) | |
| refs = None | |
| if cache.exists(): | |
| d = torch.load(cache) | |
| if d.get("names") == [n for n, _, _ in xs]: | |
| refs = d["out"] | |
| if refs is None: | |
| with torch.no_grad(): | |
| refs = [ref(x) for _, _, x in xs] | |
| torch.save({"names": [n for n, _, _ in xs], "out": refs}, cache) | |
| def pcc(u, v): | |
| u = u.reshape(-1).double(); v = v.reshape(-1).double() | |
| u = u - u.mean(); v = v - v.mean() | |
| return float((u @ v) / (u.norm() * v.norm()).clamp_min(1e-12)) | |
| tt = build_from_reference(ref, device_id=0, strict=True) | |
| raw = getattr(tt.fused_opts, "input", "norm") == "u8" | |
| try: | |
| with torch.no_grad(): | |
| tt(xs[0][1] if raw else xs[0][2]); tt(xs[0][1] if raw else xs[0][2]) | |
| res = {} | |
| for (n, u, x), r in zip(xs, refs): | |
| o = tt(u if raw else x) | |
| res.setdefault(n.split(":")[0], []).append(pcc(o, r)) | |
| finally: | |
| tt.close() | |
| summ = {k: {"mean": sum(v) / len(v), "min": min(v)} for k, v in res.items()} | |
| for k, v in summ.items(): | |
| print(f"[robust] {k:8s} mean {v['mean']:.6f} min {v['min']:.6f}") | |
| print("ROBUST " + json.dumps(summ)) | |
| if __name__ == "__main__": | |
| main() | |