Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """Đánh giá MỘT model bất kỳ trên PositionPlayEnv với mẫu lớn. | |
| Dùng để chốt câu hỏi thống kê (Q có tăng thật không) sau smoke test — | |
| eval 200 cú chỉ có ~27 cú pot, SE của Q|pot ~±0.05, cần n lớn hơn. | |
| Chạy từ gốc repo: | |
| # model stage 2 (obs đủ 6 chiều): | |
| python scripts/eval_position.py models/ppo_pos_20260714_204549/best_model.zip --episodes 1000 | |
| # model stage 1 (position-blind, cắt obs 4 chiều): | |
| python scripts/eval_position.py models/ppo_20260711_210650/final_model.zip --episodes 1000 --obs-slice 4 | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import sys | |
| from pathlib import Path | |
| sys.stdout.reconfigure(encoding="utf-8") | |
| sys.stderr.reconfigure(encoding="utf-8") | |
| ROOT = Path(__file__).resolve().parents[1] | |
| sys.path.insert(0, str(ROOT / "src")) | |
| sys.path.insert(0, str(ROOT / "scripts")) | |
| def main(): | |
| p = argparse.ArgumentParser() | |
| p.add_argument("model_path", help="đường dẫn model (.zip)") | |
| p.add_argument("--algo", choices=["ppo", "sac"], default="ppo") | |
| p.add_argument("--episodes", type=int, default=1000) | |
| p.add_argument("--obs-slice", type=int, default=None, | |
| help="cắt obs còn N chiều đầu (model stage 1: 4)") | |
| p.add_argument("--pos-coef", type=float, default=None, | |
| help="khớp với run cần chấm (chỉ ảnh hưởng reward mean)") | |
| p.add_argument("--aim-mode", choices=["best_cut", "any"], default=None, | |
| help="khớp env lúc train (ảnh hưởng aim_cos/reward mean, " | |
| "không ảnh hưởng pot/Q)") | |
| args = p.parse_args() | |
| import numpy as np | |
| from stable_baselines3 import PPO, SAC | |
| from train_position import evaluate, print_stats | |
| cls = PPO if args.algo == "ppo" else SAC | |
| model = cls.load(args.model_path) | |
| print(f"== {args.model_path} trên PositionPlayEnv ==") | |
| print(f" (deterministic, {args.episodes} cú" | |
| + (f", obs cắt {args.obs_slice} chiều" if args.obs_slice else "") + ")\n") | |
| stats = evaluate(model, n_episodes=args.episodes, | |
| pos_coef=args.pos_coef, obs_slice=args.obs_slice, | |
| aim_mode=args.aim_mode) | |
| print_stats(stats) | |
| # SE xấp xỉ cho Q|pot để đọc kết quả cho đúng | |
| n_pot = round(stats["pot_rate"] * args.episodes) | |
| if n_pot > 1: | |
| # Q ∈ [0,1], std thô ~0.25 (ước lượng bảo thủ) | |
| se = 0.25 / np.sqrt(n_pot) | |
| print(f"\n n cú pot ≈ {n_pot} → SE(Q|pot) ≈ ±{se:.3f}" | |
| f" (Q|pot ± 2·SE = [{stats['q_mean_on_pot']-2*se:.3f}, " | |
| f"{stats['q_mean_on_pot']+2*se:.3f}])") | |
| if __name__ == "__main__": | |
| main() | |