Spaces:
Sleeping
Sleeping
Download train/evaluate.py from chicelli/atrium-sim-webviz: direct link, hf CLI and curl.
- Browser
- Download file 2.86 kB
-
https://huggingface.co/spaces/chicelli/atrium-sim-webviz/resolve/main/train/evaluate.py
- Command line
-
hf download hf://spaces/chicelli/atrium-sim-webviz/train/evaluate.py
-
curl -L -o evaluate.py https://huggingface.co/spaces/chicelli/atrium-sim-webviz/resolve/main/train/evaluate.py
2.86 kB
| """Evaluation: run a policy over a held-out spec suite on fixed seeds. | |
| Seeds are enumerated from a fixed base so every checkpoint and baseline sees | |
| IDENTICAL walls - eval numbers are comparable across the whole project. | |
| uv run python -m train.evaluate --policy oracle --suite interp --episodes 20 | |
| uv run python -m train.evaluate --checkpoint runs/x/ckpt.pt --suite interp | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import statistics | |
| import gymnasium as gym | |
| import atrium_sim # noqa: F401 | |
| from atrium_sim.blueprint import _SUITES | |
| BASE_SEED = 10000 | |
| METRIC_KEYS = ("episode_return", "frac_in_tol", "frac_filled", "waste_frac", | |
| "completed", "score", "mean_abs_dev_mm") | |
| def evaluate(env, policy, suite: str, episodes: int) -> dict: | |
| """Round-robin the suite's specs on fixed seeds; aggregate terminal metrics.""" | |
| specs = _SUITES[suite] | |
| per_episode: list[dict] = [] | |
| for i in range(episodes): | |
| spec = specs[i % len(specs)] | |
| obs, info = env.reset(seed=BASE_SEED + i, options={"spec": spec}) | |
| done = False | |
| while not done: | |
| obs, r, terminated, truncated, info = env.step(policy.act(obs)) | |
| done = terminated or truncated | |
| per_episode.append(info["metrics"]) | |
| summary = { | |
| k: { | |
| "mean": statistics.fmean(ep[k] for ep in per_episode), | |
| "std": statistics.pstdev([ep[k] for ep in per_episode]), | |
| } | |
| for k in METRIC_KEYS | |
| } | |
| return {"suite": suite, "episodes": episodes, "metrics": summary} | |
| def load_policy(args, env): | |
| if args.checkpoint: | |
| from train.agent import CheckpointPolicy | |
| return CheckpointPolicy(args.checkpoint) | |
| from baselines.policy import make_policy | |
| return make_policy(args.policy, env, seed=0) | |
| def main() -> None: | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--policy", default="random", help="oracle | greedy | random") | |
| parser.add_argument("--checkpoint", default=None, help="trained agent checkpoint (.pt)") | |
| parser.add_argument("--suite", default="interp", choices=list(_SUITES)) | |
| parser.add_argument("--episodes", type=int, default=100) | |
| parser.add_argument("--gif", default=None, help="also record one episode to this path") | |
| args = parser.parse_args() | |
| env = gym.make("atrium_sim/BrickLayer-v0", | |
| render_mode="rgb_array" if args.gif else None) | |
| policy = load_policy(args, env) | |
| result = evaluate(env, policy, args.suite, args.episodes) | |
| result["policy"] = args.checkpoint or args.policy | |
| if args.gif: | |
| from atrium_sim.render.recorder import record_episode | |
| record_episode(env, policy, args.gif, seed=BASE_SEED) | |
| result["gif"] = args.gif | |
| env.close() | |
| print(json.dumps(result, indent=2)) | |
| if __name__ == "__main__": | |
| main() | |