Chris Leo commited on
Commit
c738694
·
verified ·
1 Parent(s): f6f164f

scorevision: push artifact

Browse files
detect_crime_ops/scripts/ab_compare.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import statistics
6
+ import time
7
+ from pathlib import Path
8
+
9
+ from ultralytics import YOLO
10
+
11
+
12
+ def load_images(images_file: Path) -> list[str]:
13
+ out: list[str] = []
14
+ for line in images_file.read_text().splitlines():
15
+ s = line.strip()
16
+ if not s or s.startswith("#"):
17
+ continue
18
+ out.append(s)
19
+ return out
20
+
21
+
22
+ def bench_model(model_path: Path, images: list[str], imgsz: int, device: str, conf: float, iou: float):
23
+ model = YOLO(str(model_path))
24
+ lat_ms = []
25
+ pred_counts = []
26
+ conf_means = []
27
+ for im in images:
28
+ t0 = time.perf_counter()
29
+ res = model.predict(source=im, imgsz=imgsz, device=device, conf=conf, iou=iou, verbose=False)
30
+ dt = (time.perf_counter() - t0) * 1000.0
31
+ lat_ms.append(dt)
32
+ boxes = res[0].boxes
33
+ n = 0 if boxes is None else len(boxes)
34
+ pred_counts.append(float(n))
35
+ if n > 0:
36
+ conf_means.append(float(boxes.conf.mean().item()))
37
+ else:
38
+ conf_means.append(0.0)
39
+ return {
40
+ "n_images": len(images),
41
+ "lat_p50": statistics.median(lat_ms) if lat_ms else 0.0,
42
+ "lat_p95": sorted(lat_ms)[max(0, int(0.95 * len(lat_ms)) - 1)] if lat_ms else 0.0,
43
+ "pred_avg": statistics.mean(pred_counts) if pred_counts else 0.0,
44
+ "conf_avg": statistics.mean(conf_means) if conf_means else 0.0,
45
+ }
46
+
47
+
48
+ def main() -> int:
49
+ ap = argparse.ArgumentParser()
50
+ ap.add_argument("--a", required=True, help="candidate model")
51
+ ap.add_argument("--b", required=True, help="baseline model (e.g. king)")
52
+ ap.add_argument("--images-file", required=True)
53
+ ap.add_argument("--imgsz", type=int, default=1280)
54
+ ap.add_argument("--device", default="0")
55
+ ap.add_argument("--conf", type=float, default=0.05)
56
+ ap.add_argument("--iou", type=float, default=0.45)
57
+ args = ap.parse_args()
58
+
59
+ imgs = load_images(Path(args.images_file))
60
+ if not imgs:
61
+ print("[error] no images in images file")
62
+ return 1
63
+
64
+ a = bench_model(Path(args.a), imgs, args.imgsz, args.device, args.conf, args.iou)
65
+ b = bench_model(Path(args.b), imgs, args.imgsz, args.device, args.conf, args.iou)
66
+
67
+ print("=== A/B Inference Compare (same frames) ===")
68
+ print(f"A: {args.a}")
69
+ print(f" n={a['n_images']} p50={a['lat_p50']:.1f}ms p95={a['lat_p95']:.1f}ms pred_avg={a['pred_avg']:.2f} conf_avg={a['conf_avg']:.3f}")
70
+ print(f"B: {args.b}")
71
+ print(f" n={b['n_images']} p50={b['lat_p50']:.1f}ms p95={b['lat_p95']:.1f}ms pred_avg={b['pred_avg']:.2f} conf_avg={b['conf_avg']:.3f}")
72
+ print("--- delta (A - B) ---")
73
+ print(f"d_p50_ms = {a['lat_p50'] - b['lat_p50']:+.1f}")
74
+ print(f"d_p95_ms = {a['lat_p95'] - b['lat_p95']:+.1f}")
75
+ print(f"d_pred_avg = {a['pred_avg'] - b['pred_avg']:+.2f}")
76
+ print(f"d_conf_avg = {a['conf_avg'] - b['conf_avg']:+.3f}")
77
+ return 0
78
+
79
+
80
+ if __name__ == "__main__":
81
+ raise SystemExit(main())