ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

机器人评测:别只信成功率——从二元指标到多维评估

机器人评测:别只信成功率——从二元指标到多维评估 上一周我在 RoboLab 里跑完 500 次仿真评测看着终端打印出Success Rate: 0.94的时候脑子里闪过的第一个念头不是“策略已经可以了”而是“这行输出到底骗了多少人”。做机器人策略评测的人应该都有这种直觉二元成功率太容易制造安全感也太容易把真实问题藏起来。一个机械臂抓取策略只要在“是否抓起来”这个二值判定上做点手脚成功率能轻松刷到 95% 以上一个导航策略只要把目标区域的判定半径放大半米成功率数字也能肉眼可见地变好看。可机器人是要放到真实环境里干活的不是用来在评测报告里表演“百分百到达”的。这篇东西我就围绕 RoboLab 里机器人策略评测这件事聊聊为什么不能只看二元成功率。我会先拆解二元成功率的假设和盲区再给出替代或补充的度量方法最后用一组我自己跑过的仿真数据说明同一个日志文件在不同评测指标下能得出完全相反的结论。无论你是做机器人导航、机械臂操作还是强化学习策略调优这篇应该都能帮你重新审视手上那份评测报告。1. 成功率的“假象”是怎么造出来的1.1 二元成功率的定义与“不可动摇”的地位先把术语对齐。在 RoboLab 这类评测框架里二元成功率Binary Success Rate的定义非常简单设置一个任务级判定规则评测时记录智能体每一次 episode 的出口如果满足判定条件就打 1否则打 0最后对所有 episode 取平均。公式写出来长这样success_rate (1 / N) * Σ I(episode_i succeeds)其中I()是指示函数成功为 1失败为 0。这个指标几乎成了机器人论文和项目验收的默认关卡。原因也很现实它好算、好懂、好比较。两个策略一个 90%一个 85%审稿人和领导都能在一秒钟内判断谁更“强”。但问题恰恰出在这个“好懂”上——一个经过极端简化的数字是不可能承载真实世界复杂性的。1.2 二元成功率的三个致命假设我习惯把二元成功率的适用条件拆成三个假设。只要有一个不成立这个数字就会开始撒谎。假设一成功与失败之间存在清晰可分的事件边界。比如“机械臂是否把方块放到指定区域”判定逻辑好像是明确的。但实际仿真里方块可能只进去了一半或者末端的夹具碰到了区域边缘又弹开这时候算成功还是失败RoboLab 里常见做法是给一个容器碰撞检测或者中心点距离阈值这个阈值本身就会制造假成功和假失败。我用过一个抓取场景把“物体中心点距离目标位置小于 2cm”判定为成功。评测结果非常好成功率 97%。后来我把判定阈值改成“物体整体在目标区域内”成功率直接掉到 61%。同一个策略同一个仿真环境仅仅因为判定边界的宽度不同结论天差地别。这种脆弱性本身就说明指标设计有问题。假设二所有成功的价值相同所有失败的代价相同。任何实际任务都不是这样。导航到目标点旁 5cm 和导航到目标点旁 49cm判定阈值 50cm在二元指标里同样被记为“成功”但落地部署的意义完全不同一个在任务早期就撞墙翻车的 episode和一个在最后 0.1 秒因为微小抖动失败的 episode在二元指标里也同样是“失败”但这个信息被完全丢掉了。假设三任务是单阶段、不可拆分、无中间过程的。现实中的机器人任务几乎都是分层和时序的移动机器人先出库、再经过走廊、再避障、最后到达目标点。机械臂任务往往是“抓取—抬升—移动—放置”。二元成功率等于把整个时间序列压缩成一个 0/1 标签中间任何子目标是否完成、完成到什么程度全部不可见。这三个假设叠在一起导致一个结果在 RoboLab 里跑完评测你得到的不是“这个策略有多好”而是“这个策略在这个判定函数下运气有多好”。评测者和策略之间的信息通道被一个布尔值堵死了。2. 信息损在哪里二元结果回答不了的三件事2.1 失败的位置与模式完全暗区做机器人策略优化的第一步是分析失败模式但二元成功率恰恰把失败模式的细节全抹掉了。我举个例子。在 RoboLab 里评测一个室内导航策略50 次 episode 里失败了 8 次。二元指标只告诉你“失败率 16%”但你无从判断这 8 次失败是集中在某一类起点还是某个特定角度的障碍物附近是发生在任务初期定位漂移还是后期目标点附近振荡是不同的失败原因还是同一个原因反复出现没有这些信息你连下一步该优化什么都决定不了。我经常说评测报告如果只有成功率一行字那它本质上是一个“黑盒验收单”而不是“策略诊断单”。2.2 部分成功与进度被抹掉的中间地带更隐蔽的信息损失是“部分成功”。机器人任务很少是“要么全有、要么全无”的尤其在长时域任务里。设想一个搜索救援场景机器人在未知环境里搜索目标预算时间是 10 分钟。策略 A 在第 9 分 30 秒找到了目标策略 B 在第 4 分钟就搜索了 80% 区域但没找到目标两者在二元成功率下都是 0。但作为评测者你心里很清楚B 比 A 更值得继续调优——它的探索效率和覆盖率明显更好差的只是最后的临门一脚而 A 虽然成功但时间余量太少换个场景可能就完不成。RoboLab 里如果只存成功/失败标签而不存轨迹和过程状态这些信息就永久丢失了。这也是为什么我建议任何人做评测之前先问自己一个问题如果这个 episode 失败我希望从日志里看到什么如果答案是“看到它完成了多少、在哪里卡住、用了多长时间”那成功率指标根本不够用。2.3 代价衡量不同失败不能相提并论把“路径稍微偏离但最终到达”和“碰撞障碍物导致任务中止”都记成 0或都记成 1等于默认它们代价相同。真实系统完全不是这样。移动机器人评测里最常见的情形策略 C 为了追求高成功率把速度压得很低几乎每个 episode 都能到达目标但平均耗时是策略 D 的三倍策略 D 速度快偶尔会因为避障不及时撞上障碍物而失败。只看二元成功率C 胜出但部署到实际仓库环境里C 的吞吐效率无法接受。这个问题背后是评测指标里没有“时间/效率”维度不是策略本身优劣可以仅凭成功率判断的。我建议在评测日志里至少同时记录任务完成状态、任务耗时、总路径长度/总能量消耗、安全违规次数碰撞/急停/越过边界。只有这些维度放一起才能评价一个策略在“成功的同时付出了什么代价”。3. 从“成没成”到“做得多好”RoboLab 里可落地的替代指标3.1 任务进度分数Progress Score把连续过程变成数值最简单的替代思路是不再只用 0/1 标记整个任务而是给任务的每个子目标分配权重按完成比例给出 0 到 1 之间的进度分数。这个思路在 RoboLab 里实现起来并不复杂。假设一个任务被拆成 K 个子阶段每个阶段权重是 w_k那么一次 episode 的进度分数就是progress_score Σ w_k * completion_level_k其中 completion_level_k 是第 k 个子阶段的完成程度可以是 0 或 1子目标完成与否也可以是一个连续值比如目标区域覆盖率、物体被抬升的高度比例。拿导航来说子阶段可以是“离开起点区”“通过第一个门”“通过走廊”“到达目标区域”。如果策略跑到第三个子阶段失败进度分数就是前两个阶段的权重之和而不是简单的 0。这样的指标能区分“一开始就失败”和“差一点就成功”信息量大得多。3.2 距离度量与 SPL效率和成功率联动学术界其实很早就意识到二元成功率的局限。在视觉导航领域有一个常用的指标叫SPLSuccess weighted by Path Length公式是SPL (1 / N) * Σ (success_i * L_i / max(P_i, L_i))其中 L_i 是第 i 个 episode 的最短路径长度或专家路径长度P_i 是智能体实际走的路径长度success_i 是 0/1。SPL 的思想很巧妙它用最短路径和实际路径的比值惩罚那些虽然成功但绕远路的策略。如果一个策略每次都成功但总是绕路三倍才到目标SPL 会明显低于成功率数字。RoboLab 的评测模块里完全可以直接按这个公式计算我建议把 SPL 和成功率一起打印出来对比着看。类似的思路还有LSRLong-term Success Rate或者在长时域任务里加入时间惩罚项的成功率本质上都是把“成功”和“效率”做联合评估。3.3 鲁棒性衰减曲线评测指标对扰动的弹性另一个值得加入评测体系的是“鲁棒性衰减曲线”。做法是在 RoboLab 里给同一个策略设置多个扰动等级比如传感器噪声从 0.0 增大到 0.5、目标位置偏移从 0cm 增大到 30cm、环境布局做不同程度变更分别测出每个扰动等级下的成功率。画出来的曲线会很有信息量。有的策略在零扰动下成功率 98%但噪声一加就开始断崖下跌有的策略零扰动只有 88%但曲线非常平缓高噪声下依然能保持 75%。如果你只看默认场景下的成功率会觉得前者远好于后者但要做真实部署后者可能才是更稳的选择。我用一个简单的表格概括二元成功率与多维评估之间的差别评估问题二元成功率多维评估进度效率鲁棒安全任务完成没有能回答能回答完成到什么程度不能能成功代价多大耗时/能耗不能能失败在什么阶段发生不能能扰动下表现如何衰退不能需重复多次才能看能一次性画出衰减曲线不同策略的差异可解释性弱强3.4 指标选型的“结果导向”判断法不少人来问我“到底应该用几个指标、用哪些指标”我的回答是工具的复杂度取决于你要做什么决策。如果你是做算法 baseline 对比准备投论文至少要上报成功率、SPL或等价效率指标、任务进度分数、安全违规次数。如果你是做工程项目验收要把“真实部署最关心的失败”单列出来比如“碰撞率”“超时率”“目标丢失后恢复率”。如果你是做策略迭代调优建议在训练过程中把进度分数和耗时指标也写进日志原因很简单成功率相同的时候这些指标能告诉你哪个 checkpoint 是更优的。不要为了指标全面而全面。每多一个指标评测后要分析的工作量就多一分所以选指标必须围绕决策场景。4. 同一份仿真日志两种评测结论4.1 实验设置与数据采集这一节我给出一组我在 RoboLab 里跑过的真实仿真数据略作调整不影响结论。任务是移动机器人在室内环境从随机起点导航到固定目标点环境内随机分布 6 个障碍物评测 50 个 episode固定种子保证两次评测使用的是同一批起点和障碍物布局。两个策略策略 A高避障权重速度上限 0.5 m/s倾向于绕远路但几乎不会撞上障碍物。策略 B激进行驶策略速度上限 1.2 m/s路径更直接但靠近障碍物时更容易触发碰撞。两种策略各跑 50 次记录日志如下指标策略 A策略 B二元成功率0.940.86平均任务进度分数0-10.970.92平均耗时秒14872平均路径长度米5834碰撞违规次数09到达失败但探索覆盖率60% 的 episode 数134.2 二元指标视角下的结论如果只看成功率结论非常清晰策略 A 完胜。0.94 对 0.86高出 8 个百分点一般人到这里直接就选了策略 A然后开始写评测报告结项。但这个结论回避了以下事实A 的平均耗时是 B 的两倍多路径长度接近 B 的 1.7 倍。在需要长时间运行、电池容量有限、任务有实时性要求的真实场景里A 的可用性是存在严重疑问的。它的高成功率本质上是靠“开慢车、绕远路”堆出来的效率维度完全缺失。4.3 进度视角下的互补结论再来看进度分数。B 的 7 次失败里有 3 次探索覆盖率超过了 60% 才失败比如在目标点周围打转如果任务允许“可解释的失败恢复”或“分步上报进度”B 的这些 episode 并不是完全白跑A 的失败虽然少但 3 次失败里有 1 次是出门不久就方向错乱探索覆盖率不到 20%这种失败模式在真实部署中更致命——因为它意味着全局定位或初始导航策略有问题而不是局部避障问题。换句话说从策略诊断的角度看A 暴露出的问题反而比 B 更严重。如果这个项目还需要迭代A 要修的是上层规划逻辑B 要修的只是局部避障参数——前者改动成本高得多。4.4 这个例子对评测设计的三点启发第一评测结论必须和使用场景绑定。离线的成功率对比只能说明“在这个仿真判定下谁更容易成功”不能说明“谁更值得部署”。把这个前提写进评测报告比指标本身更重要。第二同一个日志文件应该能回答多种问题。这也是我强调“日志要存过程量”的原因。成功率、进度分数、路径长度、碰撞次数都是对同一份原始轨迹数据的不同投影评测系统不应该只保存投影结果而应该保存原始轨迹否则后续想换一个角度分析时只能重跑实验。第三评测指标的“玄学”在于分布而非均值。策略 A 成功率均值高但如果你把 50 个 episode 分成五组每组 10 个可能有一组的成功率只有 70%策略 B 可能相对更稳定。只看整体均值组间方差带来的风险就被隐藏了。RoboLab 这类框架最好支持按 episode 分桶统计和可视化方便检查评测结果的稳定性。5. 评测体系的工程化落地跳出“成功与否”的框架5.1 先把任务拆成可度量的层次结构不需要推翻现有流程只要在 RoboLab 的任务定义里把二元判定替换成一个“任务树”就行。每个叶子节点对应一个可独立判定的子目标比如“机械臂末端到达抓取点上方”“物体被抬离桌面 5cm”“物体中心进入目标区域”。树干节点是叶子节点的加权组合。然后每个 episode 记录三份输出叶子完成列表、树加权进度分数、整体 0/1 成功标签。我当初改造 RoboLab 的评测模块时是在任务配置 JSON 里加了一个subgoals数组每个子目标带权重和判定函数。改造之后的好处立竿见影原来的评测报告只有一行 success_rate现在能直接看到每个子目标的通过率矩阵一眼定位瓶颈在哪个阶段。5.2 聚合方式均值不是唯一选择评测的 N 个 episode 结果怎么聚合成一个数也大有讲究。均值mean适合整体性能对比但会被极端值带偏。最差情况worst-case比如最慢的 10% episode 的平均耗时。对安全敏感场景特别重要。分位数P50/P90比均值更稳健地反映分布形状。成功率-时间权衡曲线把成功率当作时间预算的函数来画非常直观。我最常用的是 P90RoboLab 里跑完 50 个 episode 后我把 P90 作为“这个策略在最差情况下的表现”来观察。两个策略的成功率相同但一个 P90 耗时 90 秒、另一个 P90 耗时 300 秒背后反映的是尾部分布的稳定性差距。5.3 仿真与实机评测的口径对齐仿真里用 2cm 阈值当成功实机里也最好用一样的阈值。我在实际项目里吃过亏仿真评测判定“物体进入目标区域”用的是 AABB 包围盒的中心点实机验收时改用视觉检测的轮廓 Intersection-over-Union结果仿真表现优秀的策略在实机上一塌糊涂。问题不在策略在评测口径不对齐。建议在 RoboLab 的任务配置里把判定函数做成可移植的接口仿真和实机共用同一套判定代码。哪怕实机上的感知精度不够至少你要做一次“感知差异分析”——把判定函数的输入从真值换成实测值重新跑一遍离线数据看看成功率会掉多少。这一步能提前暴露一大半的 sim-to-real gap。5.4 评测结果的有效性检查清单最后我把在 RoboLab 里做策略评测的经验浓缩成一份自查清单。每次出评测报告之前我都会快速过一遍[ ] 成功率之外是否记录了进度、耗时、效率指标[ ] 成功判定是单一阈值还是多阶段组合“阈值只差一点”会不会导致结论反转[ ] 失败是否做了模式聚类失败发生在哪个阶段、哪种状态[ ] 结果按种子分组后组间方差大不大结论是否稳定[ ] 指标是否覆盖部署时的核心约束时间、能耗、碰撞安全[ ] 评测代码和任务配置是否可复现、可检索这套清单不是限制你做多元指标的自由而是确保你无论用几个指标都不会漏掉“决策所需的关键信息”。我自己在做评测的时候现在几乎不看单一数字。RobinLab 打印出Success Rate: 0.94的同时我已经在盯着旁边的Progress Score和P90 Time了。评测的价值不在于给策略贴一个“94分”的标签而在于告诉你在这个环境、这个任务、这批扰动下策略把力气花在了哪里、代价是什么、还有多少余量。这才是做机器人策略评测真正该回答的问题。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进