diff --git a/ml/eval/eval_cl.py b/ml/eval/eval_cl.py index 69133fc..695b363 100644 --- a/ml/eval/eval_cl.py +++ b/ml/eval/eval_cl.py @@ -54,9 +54,17 @@ def run(model, kin, tasks, device, bs=256, **kw): out.update({'reverse_p50': median(rr), 'reverse_mean': rr.mean().item(), 'reverse_moving_p50': median(flat['reverse_rate_moving']), # 只在动了的步上算,不被刹停稀释 'moving_share_p50': median(flat['moving_share'])}) # 活动窗内动了的步占比(=1−站住比例) - if 'brake_rate' in flat: # §9.2 判据是"刹停 <2% 推理周期",所以要按规划次数归一,不能只报绝对次数 - out.update({'brake_rate_mean': flat['brake_rate'].mean().item(), 'brake_rate_p50': median(flat['brake_rate']), + if 'brake_rate' in flat: # §9.2 要"刹停 <2% 推理周期"。均值会被长尾拖着(实测 p50=0.5% 而 mean=10%), + rr = flat['brake_rate'] # 所以必须分层报:p90 与"卡住题占比"才是能区分杠杆的读数。 + out.update({'brake_rate_mean': rr.mean().item(), 'brake_rate_p50': median(rr), 'brake_rate_p90': rr.quantile(0.9).item(), + 'stuck_share': (rr > 0.2).float().mean().item(), 'n_plans_mean': flat['n_plans'].mean().item()}) + cats = [t.get('cat') for t in tasks] # 分层读数:D 类按定义不可达,混在分母里会让"可达任务到达率"失真 + reach = torch.tensor([c != 'D' for c in cats]) + if reach.any(): + out['success_reachable'] = (ok[reach].float().mean().item()) + out['by_cat'] = {c: [int(sum(1 for x in cats if x == c)), int(sum(1 for i, x in enumerate(cats) if x == c and ok[i]))] + for c in sorted({c for c in cats if c})} if 'backoff' in flat and flat['backoff'].any(): # backoff=缩步顶上的次数;brakes 现在只记连最小档都不安全的 out['backoff_mean'] = flat['backoff'].mean().item() # ⇒ 原来的"全拒"事件数 = 两者之和 out['reject_all_mean'] = (flat['backoff'] + flat['brakes']).mean().item()