自动驾驶决策算法:从MDP建模到强化学习落地实践

发布时间:2026/10/25 8:05:27
自动驾驶决策算法:从MDP建模到强化学习落地实践

1. 从“规则驱动”到“学习驱动”:自动驾驶决策算法的范式转移

自动驾驶的决策模块,是整个系统里最像“人”的部分。感知告诉车“周围有什么”,规划告诉车“大致往哪走”,而决策要回答的是“此刻到底该怎么动”——跟车还是变道、抢行还是让行、加速还是点刹。这个模块做得好不好,直接决定了乘客敢不敢闭眼、后车会不会骂娘。

过去十年,决策算法的主流是规则驱动。有限状态机、行为树、代价地图,工程师把人类驾驶经验拆成一条条 if-else,再配上参数标定。这套东西在高速巡航、简单跟车场景里跑得挺稳,因为场景封闭、交互对象少。但一进城区就露怯:路口博弈、加塞处理、非机动车乱窜,规则写不完,参数调不动,最后变成“打补丁式开发”,一个场景一个补丁,维护成本指数级上升。

于是行业把目光转向学习驱动,尤其是基于MDP(马尔可夫决策过程)的强化学习框架。MDP 把决策问题形式化成五元组:状态空间、动作空间、转移概率、奖励函数、折扣因子。自动驾驶天然适配这个框架——状态是自车与周围交通参与者的运动学信息,动作是油门、刹车、转向或更高级的轨迹选择,奖励是安全、效率、舒适度的加权组合。一旦形式化完成,剩下的就是怎么解这个 MDP。

但“怎么解”恰恰是最大的坑。真实驾驶的状态空间连续且高维,转移概率未知且随机,奖励函数设计稍有不慎就会学出“原地转圈”或“猛冲猛刹”的奇葩策略。这就引出了本文要聊的核心:决策算法到底该怎么选、怎么训、怎么落地。我会从 MDP 建模、强化学习算法选型、深度学习融合、离线数据利用、多智能体交互几个层面,把踩过的坑和验证过的思路摊开讲。适合已经了解自动驾驶基础模块划分、想深入决策层实现细节的工程师,也适合做强化学习应用、想看看真实物理系统怎么落地的研究者。

2. 决策问题的 MDP 建模:状态、动作与奖励的工程化拆解

2.1 状态空间设计:别把感知原始输出直接塞进去

新手最容易犯的错,是把感知的原始输出——比如 64 线激光雷达点云、多摄像头 BEV 特征图——直接作为决策网络的状态输入。理论上可行,实践中灾难。原因有三:维度太高导致采样效率极低,感知噪声直接污染决策,以及训练时容易过拟合到特定传感器的噪声模式。

工程上更稳妥的做法是分层抽象。决策层不关心“前方 30 米处有一个置信度 0.87 的锥桶”,它关心的是“左前方有一个静止障碍物,距离 28 米,横向偏移 1.2 米”。所以状态空间通常构造成结构化向量:

  • 自车状态:速度、加速度、航向角、角速度、当前位置与车道线关系
  • 周围车辆状态:相对距离、相对速度、相对加速度、所在车道、历史轨迹片段
  • 道路结构:车道数、曲率、限速、路口拓扑
  • 交互特征:碰撞时间、车头时距、博弈意图估计

每个维度的量纲不同,必须做归一化。速度除以限速,距离除以安全跟车距离,角度除以 π。归一化不是可选项,是必选项——否则梯度下降会被大量纲维度主导,学出来的策略对速度变化极其敏感,对距离变化几乎无感。

注意:状态里一定要包含历史信息。纯当前帧的 MDP 假设是马尔可夫的,但真实驾驶中,前车的加速度趋势、旁边车辆的犹豫行为,都需要历史窗口才能判断。常用做法是堆叠最近 5-10 帧的状态向量,或者用 LSTM/GRU 编码历史序列。

2.2 动作空间选择:离散还是连续,这是个问题

动作空间的设计直接决定算法选型。离散动作空间把驾驶行为切成有限个选项:保持、左变道、右变道、加速、减速,组合起来可能几十个动作。优点是可以用 DQN 这类值函数方法,训练稳定、容易收敛。缺点是动作粒度粗,变道过程中的连续轨迹控制还得靠下层规划器补,决策与规划割裂。

连续动作空间直接输出油门、刹车、转向角,或者输出一条轨迹的终点位姿。优点是端到端、控制平滑,适合用 DDPG、TD3、SAC 这类确定性策略梯度方法。缺点是训练不稳定,探索效率低,容易陷入局部最优。

我的经验是:高速场景用离散,城区场景用连续或混合。高速上行为选择有限,离散动作足够,而且值函数方法对奖励稀疏的容忍度更高。城区里跟车距离的微调、博弈中的渐进式挤压,需要连续控制才能表达。混合方案是上层离散选行为、下层连续生成轨迹,两层用不同的奖励函数分别训练。

2.3 奖励函数:安全、效率、舒适的三角博弈

奖励函数是强化学习里最像“艺术”的部分。自动驾驶的奖励通常由三块组成:

  • 安全项:碰撞大负奖励,距离过近小负奖励,可通行区域外负奖励
  • 效率项:速度接近期望速度给正奖励,到达目标给大正奖励,耗时给负奖励
  • 舒适项:加速度绝对值、 jerk(加速度变化率)、曲率变化给负奖励

难点在于权重分配。安全权重太高,车会龟速爬行甚至原地不动;效率权重太高,车会激进穿插、急刹急加速;舒适权重太高,车会反应迟钝、被加塞到怀疑人生。

我试过的一种有效做法是动态权重。低速时提高安全权重,高速时适当放宽安全权重、提高效率权重。拥堵时舒适权重降低,因为频繁启停不可避免;畅通时舒适权重提高,因为乘客对平顺性更敏感。动态权重可以用一个简单的状态机切换,也可以让网络自己学——把权重作为状态的一部分输入,网络输出动作的同时也隐式调整了对各目标的偏好。

实操心得:奖励函数不要用绝对数值,用相对变化。比如“距离前车 20 米”不如“距离前车 20 米相对于安全跟车距离的比值”。这样策略对不同速度、不同路况的泛化能力会强很多。

3. 强化学习算法选型:从 DQN 到 SAC 再到离线 RL

3.1 值函数方法:DQN 及其变体在高速场景的落地

DQN 是最早被用到自动驾驶决策的深度强化学习算法。它的核心是用神经网络近似 Q 值函数,输入状态、输出每个离散动作的预期回报。训练时用经验回放池打破样本相关性,用目标网络稳定训练。

在高速跟车和变道场景,DQN 的表现可圈可点。状态维度控制在 20-30 维,动作空间 5-7 个离散选项,奖励函数设计合理的话,几百万步仿真就能学到不错的策略。Double DQN 解决 Q 值高估问题,Dueling DQN 把状态价值和动作优势分开估计,Prioritized Replay 优先回放高 TD 误差的样本,这些变体都能显著提升收敛速度和最终性能。

但 DQN 的天花板也很明显。离散动作空间限制了控制精度,值函数方法对连续动作无能为力,而且 Q 值网络对状态空间的覆盖要求高,遇到训练集里没见过的场景容易输出荒谬的 Q 值。

3.2 策略梯度方法:DDPG、TD3、SAC 的连续控制之路

连续控制场景下,策略梯度方法是主流。DDPG 用确定性策略网络输出动作,再用 Critic 网络评估动作价值,训练时加噪声探索。TD3 在 DDPG 基础上做了三个改进:双 Critic 取最小值抑制高估、延迟更新 Actor 网络、目标动作加噪声平滑。SAC 则引入最大熵框架,在最大化回报的同时最大化策略熵,探索更充分、训练更稳定。

我在城区跟车场景对比过这三种算法。DDPG 训练曲线震荡严重,经常学出“猛踩油门然后猛刹车”的振荡策略。TD3 稳定很多,但探索效率一般,需要精心设计噪声方差。SAC 综合表现最好,自动调节的熵温度让它在探索和利用之间平衡得不错,学出来的策略平顺性明显优于前两者。

不过 SAC 的计算开销也最大,每次更新要跑两个 Critic 网络和一次策略采样。实时推理时只跑 Actor 网络,延迟可以接受,但训练阶段对算力要求高。如果仿真环境本身就很慢,SAC 的训练周期会拉得很长。

3.3 离线强化学习:IQL 与 CQL 如何利用真实驾驶数据

仿真环境再逼真,也有 sim-to-real gap。真实驾驶数据里蕴含的交互模式、博弈策略,是仿真器很难完全复现的。离线强化学习的目标就是:只用一个固定的真实驾驶数据集,不与环境交互,学出一个可用的策略。

IQL(Implicit Q-Learning)的核心思路是避免查询分布外动作的 Q 值。它不直接最大化 Q,而是用期望回归估计状态价值,再用优势加权回归提取策略。CQL(Conservative Q-Learning)则在 Q 值更新时加一个保守项,压低分布外动作的 Q 值,防止策略跑偏。

实际用下来,IQL 在跟车和变道场景的离线训练效果不错,学出来的策略保守但安全。CQL 更激进一些,效率指标更好,但偶尔会输出数据集里没见过的动作组合,需要加安全层兜底。离线 RL 的最大价值在于冷启动:先用真实数据训一个基础策略,再放到仿真里微调,比从零开始探索快得多。

注意:离线 RL 对数据集质量极其敏感。如果数据里全是人类司机的保守驾驶,学出来的策略也会偏保守;如果数据里混入了激进驾驶片段,策略可能学会危险动作。数据清洗和场景筛选是离线 RL 落地的前置条件。

4. 深度学习与决策算法的融合:CNN、LSTM 与多任务学习

4.1 用 CNN 提取鸟瞰图特征:感知与决策的接口设计

决策网络的状态输入如果包含栅格化地图或 BEV 特征图,CNN 就是天然的编码器。把周围环境投影到鸟瞰视角,每个通道代表一类信息:自车、其他车辆、车道线、可行驶区域、障碍物。几层卷积下来,网络能学到“左前方有车且距离近”这类空间关系。

但 CNN 的输出不能直接接全连接层做决策,因为空间信息会被展平丢失。更好的做法是用 CNN 提取特征图后,通过空间注意力机制让决策网络关注关键区域。比如用一个小网络预测每个空间位置的权重,加权求和后再输入策略网络。这样网络能自动学会“看”前车、看旁车、看路口,而不是均匀处理整个场景。

4.2 LSTM 与 GRU 处理时序依赖:为什么历史窗口很重要

驾驶决策本质上是时序问题。前车突然减速,你需要根据它过去几秒的速度变化判断是轻刹还是急刹;旁车打转向灯后犹豫不决,你需要根据它过去几帧的横向位移判断它是否真的要变道。LSTM 和 GRU 就是用来捕捉这种时序依赖的。

工程上,我通常把最近 10 帧的状态向量输入 LSTM,取最后一个时间步的隐状态作为当前决策的时序特征。GRU 参数更少、训练更快,在实时性要求高的场景下更实用。LSTM 表达能力强一些,但容易过拟合,需要配合 Dropout 和正则化。

实操心得:时序窗口不是越长越好。10 帧(约 0.5 秒)对大多数城区场景够用,20 帧以上收益递减,而且增加计算负担。关键是窗口内的采样频率要和感知输出对齐,不能有丢帧或时间戳跳变。

4.3 多任务学习:同时预测轨迹、意图与价值

决策网络可以同时输出多个任务的结果:动作策略、状态价值、周围车辆意图、未来轨迹预测。多任务学习的好处是共享底层特征,提升泛化能力,而且辅助任务能提供额外的监督信号。

但多任务学习的难点在于损失权重平衡。策略损失、价值损失、意图分类损失、轨迹回归损失,量纲和尺度都不一样。如果直接相加,某个损失会主导梯度。常见做法是用不确定性加权:让网络自己学习每个任务的噪声参数,损失函数变成各任务损失除以噪声方差再加 log 方差。这样网络会自动给难任务更多权重,给简单任务更少权重。

另一种做法是 GradNorm 或 PCGrad,动态调整梯度方向,避免任务间冲突。我在实际项目里用过不确定性加权,实现简单、效果稳定,推荐优先尝试。

5. 多智能体交互与因果强化学习:从 MADL 到 CRL

5.1 多智能体决策的挑战:非平稳性与信用分配

真实道路上的决策不是单智能体问题。你的策略影响旁车,旁车的策略也影响你。多智能体强化学习里,每个智能体都在学习,环境对彼此来说都是非平稳的。这导致训练极不稳定,今天学到的策略明天就失效。

MADL(Multi-Agent Deep Learning)的思路是集中训练、分散执行。训练时用一个全局 Critic 评估联合动作价值,执行时每个智能体只用局部观测选动作。这样既考虑了交互,又保证了执行的独立性。但全局 Critic 的状态空间随智能体数量指数增长,实际用的时候通常只考虑自车周围 3-5 辆关键车。

信用分配是另一个难题。一次碰撞发生了,是自车决策的错,还是旁车突然变道的错?奖励信号是全局的,但每个智能体的贡献不同。常见做法是用反事实基线:如果自车采取另一个动作,碰撞是否避免?用这个差值作为自车的优势估计。

5.2 因果强化学习 CRL 的核心机制:把因果推断嵌入 RL 流程

因果强化学习(CRL)是最近比较热的方向。核心思想是:策略学到的相关性不等于因果性。网络可能学到“打转向灯的车都会变道”,但真实因果是“车有变道意图才打转向灯”。如果只学相关性,遇到打转向灯但不换道的车就会误判。

CRL 把因果推断工具嵌入强化学习流程,关键能力包括:

  • 因果发现:从数据中学习状态变量之间的因果图,区分原因和结果
  • 反事实推理:给定当前状态和动作,推断如果采取不同动作会怎样
  • 干预不变性:学到的策略在不同干预下保持稳定,不依赖虚假相关

具体实现上,可以用结构因果模型建模状态转移,用 do-calculus 估计干预分布,再把因果约束加到策略优化目标里。实际落地时,完全因果化的 RL 计算量太大,通常只对关键变量做因果建模,比如前车意图、路口通行权。

5.3 基于模型的强化学习:Dreamer 与 MuZero 的启示

基于模型的 RL 学一个环境动力学模型,然后用模型生成虚拟经验来训练策略。Dreamer 在隐空间里学世界模型,MuZero 学的是价值预测模型。两者都在游戏和仿真环境里表现惊艳,但在自动驾驶上落地还有距离。

主要障碍是模型误差累积。驾驶环境的动力学虽然大致确定,但交互对象的意图高度随机。模型预测 1 秒还准,预测 3 秒就偏得离谱。策略在模型里学得再好,放到真实环境也可能崩。

不过基于模型的 RL 在数据效率上有巨大优势。真实驾驶数据采集成本高,仿真环境搭建也费时。如果能用少量真实数据学一个粗略模型,再用模型生成大量虚拟经验做预训练,最后用真实数据微调,整体效率会高很多。这个思路在工业界已经开始尝试,效果值得期待。

6. 实操落地:训练流程、调参经验与常见问题排查

6.1 仿真环境搭建与课程学习

训练决策算法离不开仿真环境。CARLA、SUMO、Gazebo 各有优劣。CARLA 视觉逼真、物理引擎好,但计算开销大;SUMO 交通流仿真强,但车辆动力学简化;Gazebo 适合机器人系统集成,但场景库少。

我的建议是分层使用:早期用 SUMO 做大规模交通流训练,快速迭代策略;中期用 CARLA 做感知-决策联合调试;后期用真实数据做离线微调。课程学习也很关键:先学直道跟车,再学弯道,再学变道,最后学路口博弈。每个阶段训练到收敛再进入下一阶段,比一上来就扔进复杂场景快得多。

6.2 超参数调优:学习率、折扣因子、回放池大小

强化学习的超参数比监督学习敏感得多。学习率太大,策略震荡;太小,收敛慢到怀疑人生。折扣因子 γ 决定智能体看多远,0.99 对应约 100 步的视野,城区场景够用;高速场景可以降到 0.95,因为决策影响更短。

回放池大小影响样本多样性。太小,样本相关性高,训练不稳定;太大,旧策略的数据占比高,与当前策略分布不匹配。经验值是 10 万到 100 万条 transition,具体看状态维度和动作空间。

注意:回放池里的数据要定期清理。旧策略产生的数据对当前策略的参考价值低,尤其是策略已经更新了很多代之后。可以用优先回放机制自动给旧数据降权。

6.3 常见问题速查表

问题现象可能原因排查方向解决方法
策略收敛到原地不动安全惩罚过高,效率奖励不足检查奖励函数权重降低碰撞惩罚,增加速度奖励
训练曲线剧烈震荡学习率过大,或回放池太小打印每轮回报方差降低学习率,增大回放池
仿真表现好,实车表现差sim-to-real gap对比仿真与实车状态分布加域随机化,用真实数据微调
变道策略犹豫不决折扣因子过低,或舒适惩罚过高检查 γ 和 jerk 权重提高 γ,降低舒适惩罚
多车场景训练不收敛非平稳性太强检查是否用了集中训练改用 MADL 或独立 PPO
离线 RL 策略过于保守数据集偏保守分析数据动作分布混合仿真数据,加探索噪声

6.4 安全层设计:学习策略不能直接控车

无论策略学得多好,都不能让它直接输出油门刹车。必须加安全层:碰撞时间低于阈值强制刹车,横向加速度超限限制转向,可行驶区域外禁止变道。安全层是规则驱动的,但参数可以自适应调整。学习策略负责“怎么开得好”,安全层负责“怎么开不撞”。

实操心得:安全层的阈值不要设得太死。太保守会导致策略学到的动作被频繁覆盖,训练信号失真。可以先让安全层只做紧急兜底,等策略稳定后再逐步收紧。

7. 数据、算力与工程化的现实约束

7.1 自动驾驶数据集的选择与使用

公开数据集里,nuScenes、Waymo Open Dataset、Argoverse 是决策算法常用的。nuScenes 场景丰富、标注详细,适合做行为预测和决策联合训练。Waymo 数据量大、质量高,但获取门槛高。Argoverse 有高清地图和轨迹预测标注,适合做交互博弈研究。

用这些数据集做离线 RL 时,要注意动作空间对齐。数据集里的动作是离散的驾驶行为标签还是连续的轨迹?如果是轨迹,怎么映射到你的动作空间?这个映射关系直接影响策略能否学到有效行为。

7.2 训练算力估算与云平台选择

一个中等规模的决策网络,参数量在 100 万到 1000 万之间。用 SAC 训练,单卡 V100 或 A100 跑 100 万步大约需要 2-3 天。如果仿真环境本身很慢,瓶颈在环境交互而不是梯度更新,这时候多开并行环境比换显卡更有效。

云平台选择上,AWS、GCP、Azure 都提供 GPU 实例。如果团队有自建集群,优先用本地,因为数据传输和调试更方便。云平台适合短期大规模实验,长期训练还是本地划算。

7.3 从仿真到实车的迁移策略

sim-to-real 是决策算法落地的最后一公里。域随机化是最常用的手段:在仿真里随机化传感器噪声、车辆动力学参数、交通参与者行为模型,让策略见过足够多的变化,到真实世界才不会慌。

另一种思路是残差学习:仿真里训一个基础策略,实车上加一个小网络学残差修正。基础策略负责大部分决策,残差网络补偿仿真与真实的差异。这样实车训练数据需求少,安全性也更容易保证。

8. 一些个人体会

决策算法这个方向,理论很漂亮,落地很磨人。MDP 框架清晰,但状态设计、奖励塑形、算法调参每一步都是坑。强化学习在游戏里能超人类,在驾驶里能追上人类司机就不错了。原因在于驾驶的奖励函数太模糊,安全、效率、舒适的权衡没有标准答案,不同乘客的偏好还不一样。

我自己的经验是:别追求端到端替代规则,先做规则和学习的混合。规则负责安全底线和常见场景,学习负责复杂交互和个性化风格。离线 RL 做冷启动,仿真 RL 做迭代,实车数据做微调。多智能体交互和因果推断是值得关注的方向,但别指望一上来就解决所有问题。

最后分享一个小技巧:训练决策策略时,把“人类司机的动作”作为辅助监督信号加进损失函数。不用完全模仿,只要让策略在探索时有个大致方向,收敛速度会快很多。这个思路在 IQL 和 TD3+BC 里都有体现,实测有效。