Download scripts/error_analysis.py from siddhant20/task1: direct link, hf CLI and curl.
- Browser
- Download file 2.42 kB
-
https://huggingface.co/siddhant20/task1/resolve/main/scripts/error_analysis.py
- Command line
-
hf download hf://siddhant20/task1/scripts/error_analysis.py
-
curl -L -o error_analysis.py https://huggingface.co/siddhant20/task1/resolve/main/scripts/error_analysis.py
2.42 kB
| """Break down out-of-fold errors by cause and by box size. | |
| This is the script that decided the current priority: it separates "the model | |
| never proposed this box" from "the model proposed it but the coordinates were | |
| too loose", and reports the recall ceiling that perfect box regression would | |
| reach. | |
| modal volume get pmdm-ckpt /oof/fold0_convnext_tiny.npz /tmp/oof.npz | |
| PMDM_DATA=Task1/PackagingMaterialDifferenceMiningDataset \ | |
| .venv/bin/python scripts/error_analysis.py /tmp/oof.npz | |
| """ | |
| from __future__ import annotations | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) | |
| import numpy as np # noqa: E402 | |
| from pmdm.dataset import load_gt # noqa: E402 | |
| from pmdm.metric import iou_matrix # noqa: E402 | |
| SIZE_BINS = [(0, 12, "<12px"), (12, 24, "12-24px"), (24, 10 ** 9, ">24px")] | |
| def main(npz_path: str) -> None: | |
| z = np.load(npz_path) | |
| gt = load_gt() | |
| keys = sorted({k.split("__")[0] for k in z.files}) | |
| best_iou, sizes = [], [] | |
| n_candidates = 0 | |
| for key in keys: | |
| idx = int(key.split("_")[-1]) | |
| boxes = z[f"{key}__boxes"] | |
| g = gt[idx] | |
| n_candidates += len(boxes) | |
| m = iou_matrix(boxes, g) if len(boxes) and len(g) else np.zeros((len(boxes), len(g))) | |
| for j in range(len(g)): | |
| best_iou.append(float(m[:, j].max()) if m.size else 0.0) | |
| sizes.append(max(g[j][2] - g[j][0], g[j][3] - g[j][1])) | |
| best_iou, sizes = np.array(best_iou), np.array(sizes) | |
| print(f"pairs: {len(keys)}, ground-truth boxes: {len(best_iou)}, " | |
| f"candidates per image: {n_candidates / max(1, len(keys)):.1f}") | |
| print(f"matched at IoU >= 0.5: {int((best_iou >= 0.5).sum())}") | |
| print(f"proposed but IoU < 0.5: {int(((best_iou > 0) & (best_iou < 0.5)).sum())}") | |
| print(f"never proposed (IoU == 0): {int((best_iou == 0).sum())}") | |
| print(f"recall ceiling with perfect boxes: {float((best_iou > 0).mean()):.4f}") | |
| print("\nby box size (longest side):") | |
| for lo, hi, name in SIZE_BINS: | |
| m = (sizes >= lo) & (sizes < hi) | |
| if not m.sum(): | |
| continue | |
| print(f" {name:9s} n={int(m.sum()):4d} " | |
| f"matched={float((best_iou[m] >= 0.5).mean()):.3f} " | |
| f"never_proposed={int((best_iou[m] == 0).sum())}") | |
| if __name__ == "__main__": | |
| main(sys.argv[1] if len(sys.argv) > 1 else "/tmp/oof.npz") | |