ATA / src /accident /evaluate.py
vishanth11
Deploy AI Traffic Adaptation System with Git LFS binaries to Hugging Face Spaces
f234112
Raw History Blame Contribute Delete
2.95 kB
"""Evaluation helpers for validation and test splits."""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
import torch
from torch.utils.data import DataLoader
from .dataset import AccidentParquetDataset, collate_detection
from .metrics import evaluate_coco, threshold_analysis
from .model import build_detector
from .train import gather_predictions
from .utils import FIGURE_DIR, MODEL_DIR, REPORT_DIR, get_device
def evaluate_split_from_checkpoint(
split: str,
checkpoint_path: Path,
config: dict[str, Any],
dataset_dir: Path | None = None,
score_threshold: float = 0.05,
) -> dict[str, Any]:
"""Evaluate a split using a saved checkpoint.
Returns ground-truth records, prediction records, COCO metrics, and
threshold analysis.
"""
device = get_device()
image_size = tuple(config["image_size"])
ds = AccidentParquetDataset(
split=split, target_size=image_size, dataset_dir=dataset_dir
)
loader = DataLoader(
ds,
batch_size=config["batch_size"],
shuffle=False,
num_workers=config.get("num_workers", 0),
collate_fn=collate_detection,
)
model = build_detector(num_classes=config["num_classes"], pretrained=False)
model.load_state_dict(torch.load(checkpoint_path, map_location=device, weights_only=True))
model.to(device)
gt_records, pred_records = gather_predictions(model, loader, device, score_threshold)
metrics = evaluate_coco(gt_records, pred_records, image_size)
thresholds = threshold_analysis(gt_records, pred_records, image_size=image_size)
return {
"split": split,
"metrics": metrics,
"threshold_analysis": thresholds,
"num_images": len(ds),
"num_ground_truth_objects": sum(len(rec["boxes"]) for rec in gt_records),
"num_predictions": sum(len(rec["boxes"]) for rec in pred_records),
}
def run_test_evaluation(
config: dict[str, Any],
checkpoint_path: Path = MODEL_DIR / "best_detector.pth",
dataset_dir: Path | None = None,
report_dir: Path = REPORT_DIR,
) -> dict[str, Any]:
"""Run the ONE final test evaluation after validation-based selection."""
print("Running final test evaluation with best validation checkpoint...")
result = evaluate_split_from_checkpoint(
split="test",
checkpoint_path=checkpoint_path,
config=config,
dataset_dir=dataset_dir,
)
report_dir.mkdir(parents=True, exist_ok=True)
test_path = report_dir / "test_results.json"
with open(test_path, "w", encoding="utf-8") as f:
json.dump(result, f, indent=2)
print(
f"Test mAP@50={result['metrics']['overall']['mAP_50']:.4f} — "
f"accident AP={result['metrics']['per_class']['accident']['AP_50']:.4f} — "
f"accident recall={result['metrics']['per_class']['accident']['recall']:.4f}"
)
return result