一、稳定性验证概述
什么是决策算法稳定性
先问大家一个问题:你写了一个决策算法,今天跑得好好的,明天换一组输入数据,结果就完全不一样了——这种情况你遇到过吗?
我遇到过,而且不止一次。
所谓决策算法稳定性,说白了就是:算法在相同条件下,能不能给出可重复、可预期的结果。它不是一个「有」或「没有」的属性,而是一个程度问题。
我个人习惯把稳定性拆成三个维度来看:
- 时间维度:今天跑和明天跑,结果一致吗?
- 环境维度:换台机器、换个编译器,结果还一样吗?
- 输入维度:输入数据稍微变一点点,输出会不会剧烈抖动?
你想想看,如果一个自动驾驶的决策算法不稳定,同样的路口昨天能过,今天就不能过了——这谁敢用?
核心观点:稳定性是决策算法从「能用」到「可靠」之间的那道门槛。
为什么需要仿真验证
有人可能会问:「我直接上真机测试不就行了?干嘛费劲做仿真?」
嗯,这个问题我当年也问过我的导师。他的回答让我记到现在:「你愿意用真机去试错,但用户不愿意用命去试。」
仿真验证的必要性,我总结为三点:
- 成本问题:一次真机测试的成本,够你做几百次仿真了。我在项目中遇到过,一个无人机飞控算法的真机测试,炸机一次就是几万块。仿真环境下,你随便炸,炸完改代码再来。
- 覆盖问题:真机测试能覆盖的边界条件太有限了。极端天气、传感器故障、通信延迟——这些场景在仿真里可以批量生成,真机上你等一年都不一定碰得到。
- 可复现问题:真机测试最大的坑是什么?是不可复现。同样的代码,今天跑和明天跑,因为光照、温度、风力不一样,结果可能完全不同。仿真环境可以精确控制每一个变量,这才是验证稳定性的前提。
我的经验:仿真验证不是为了替代真机测试,而是为了在真机测试之前,把那些「明显不靠谱」的问题先筛掉。我曾经有一个项目,仿真阶段发现了200多个稳定性问题,真机测试时只出了3个——这效率,你品品。
验证的核心指标
好了,既然要做仿真验证,那总得有个标准吧?我一般看三个核心指标:收敛性、鲁棒性、一致性。
1. 收敛性
收敛性,说白了就是:算法能不能稳定地到达目标状态。
举个例子,一个路径规划算法,给它起点和终点,它能不能找到一条路径?如果能,那它收敛了。但如果它来回震荡、原地打转、或者干脆发散到天边去了——那就是不收敛。
我在项目中遇到过一种情况:算法在90%的场景下都能收敛,但遇到某个特定的障碍物布局时,就开始「鬼打墙」。后来查了三个月才发现,是某个参数在边界条件下出现了数值溢出。
注意:收敛性不是「有」或「没有」,而是「快」和「慢」、「稳」和「抖」的区别。一个收敛慢但稳定的算法,往往比一个收敛快但偶尔发散的要实用得多。
2. 鲁棒性
鲁棒性,我更喜欢叫它「抗造能力」。算法在遇到异常情况时,能不能保持基本的功能。
常见的鲁棒性测试场景包括:
- 输入数据有噪声(比如传感器读数跳变)
- 部分传感器失效(比如GPS信号丢失)
- 计算资源受限(比如CPU负载过高)
- 通信延迟或丢包
我曾经做过一个实验:给一个决策算法注入5%的随机噪声,结果它的决策正确率从98%直接掉到了63%。这就是典型的鲁棒性不足。后来加了滤波和冗余校验,同样的噪声下正确率还能保持在92%以上。
3. 一致性
一致性,我把它叫做「不抽风」能力。同样的输入,任何时候跑都应该得到同样的输出。
你可能会说:「这不是理所当然的吗?」
还真不一定。我记得有一次排查一个bug,发现同一个算法在Windows上跑和Linux上跑,结果不一样。查到最后,是浮点数运算的精度差异导致的。还有一次,是因为随机数种子没固定,每次跑出来的蒙特卡洛采样都不一样。
| 指标 | 关注点 | 常见问题 | 我的建议 |
|---|---|---|---|
| 收敛性 | 能否到达目标 | 震荡、发散、局部最优 | 先保证收敛,再优化速度 |
| 鲁棒性 | 能否抗干扰 | 噪声敏感、边界失效 | 注入噪声测试,逐步加码 |
| 一致性 | 能否可重复 | 平台差异、随机种子 | 固定随机种子,跨平台验证 |
知识体系总览
下面这张图,是我自己梳理的稳定性验证知识体系。你可以把它当作本章的「地图」——后面讲的所有内容,都能在这张图上找到位置。
一个小建议:刚开始做稳定性验证的时候,别贪多。先把收敛性搞定,再考虑鲁棒性,最后才是一致性。这三个指标是有依赖关系的——一个不收敛的算法,谈鲁棒性和一致性没有意义。
好了,这一章的内容就到这里。记住一句话:稳定性不是测出来的,是设计出来的。仿真验证只是帮你发现问题的工具,真正解决问题的,还是你对算法本身的理解。