3. 驾驶工程背景
要理解 DAgger 在自动驾驶中的价值,必须先回到驾驶工程本身:一辆自动驾驶汽车从“看见世界”到“转动方向盘”,中间到底经过了哪些环节?这些环节如何组织成系统?不同组织方式又会给模仿学习带来怎样截然不同的数据需求与训练难度?本章围绕系统架构、感知—决策—控制模块以及端到端与模块化两种范式展开,为后续 DAgger 的交互式数据聚合建立工程语境。
一、自动驾驶系统的分层架构
主流自动驾驶系统通常按“感知—定位—预测—决策—规划—控制”分层组织。传感器层提供摄像头、激光雷达、毫米波雷达、IMU、GNSS 等原始数据;感知层完成目标检测、车道线识别、可行驶区域分割与障碍物跟踪;定位与建图层把车辆放到高精地图的绝对坐标中;预测层推断其他交通参与者的未来轨迹;决策与规划层生成行为决策和局部轨迹;控制层把轨迹转化为油门、刹车、转向的底层指令。
这种分层架构的核心价值在于可解释、可分工、可验证:每个模块有明确输入输出,便于独立测试与责任界定。但它也带来接口误差累积——感知的小偏差会经预测、规划逐级放大,最终表现为控制层的抖动或犹豫。
二、感知、决策、控制三大模块的职责与接口
感知模块回答“周围有什么、在哪里、往哪动”;决策规划模块回答“我该怎么做”;控制模块回答“如何精确执行”。三者之间通过明确定义的数据结构耦合,例如感知输出障碍物列表(位置、速度、朝向、置信度),规划输出带时间戳的轨迹点序列,控制输出转向角与加速度。
在模仿学习中,这种接口划分决定了监督信号的选择:若学习目标是规划层,标签是专家轨迹;若目标是控制层,标签是转向与油门序列;若目标是端到端,标签直接是底层指令,输入则是原始传感器数据。DAgger 的关键在于:当学习器偏离专家轨迹后,由专家对学习器当前所处状态重新标注动作,从而纠正分布偏移。
三、端到端驾驶与模块化驾驶的对比
模块化驾驶把系统拆成多个可独立优化的子模块,优点是可解释、可调试、可局部替换,缺点是接口误差累积、模块间目标不一致、整体调优困难。端到端驾驶用一个神经网络直接从传感器映射到控制指令,优点是信息无损、联合优化、结构简洁,缺点是黑盒、难验证、对长尾场景数据需求极大。
| 对比维度 | 模块化驾驶 | 端到端驾驶 |
|---|---|---|
| 系统结构 | 感知/预测/规划/控制分层 | 单一或少量网络直接映射 |
| 可解释性 | 高,每层可单独检查 | 低,中间表示难解释 |
| 误差传播 | 逐级累积,接口损失大 | 无显式接口,但误差隐式耦合 |
| 数据需求 | 各模块可分别采集与标注 | 需大量覆盖长尾的驾驶数据 |
| DAgger 适用性 | 可在规划/控制层做交互纠正 | 需在原始输入空间做交互纠正 |
| 典型风险 | 模块目标冲突、调参复杂 | 分布偏移、因果混淆、难验证 |
四、案例场景:一个“犹豫不决”的换道决策
假设车辆在高速上准备向左换道。模块化系统中,感知检测到左后方有快速接近的车辆,预测层判断其 2 秒后到达本车位置,规划层因此放弃换道;若感知漏检或预测偏差,规划层可能做出错误换道决策。端到端系统则直接从图像序列输出转向指令,若训练数据中缺少“左后方快速来车”的样本,模型可能因分布偏移而输出危险动作。
DAgger 在此场景中的价值是:让学习器先自主行驶,当它进入“犹豫或错误”的状态时,由专家接管并标注正确动作,把这些学习器访问到的状态加入训练集。这样,模型不仅学会专家走过的状态,也学会自己可能走到的状态,从而缓解分布偏移。
五、常见误区与复盘
- 误区一:端到端一定优于模块化。端到端在数据充足、场景封闭时表现亮眼,但在安全验证、责任界定和长尾处理上仍面临巨大挑战。
- 误区二:模块化没有分布偏移问题。模块化同样存在分布偏移,只是被分散到各层;DAgger 在规划层和控制层同样有效。
- 误区三:DAgger 只是“多采数据”。DAgger 的核心是让专家对学习器访问到的状态进行标注,而不是简单增加专家演示数量。
- 误区四:忽略接口定义。无论端到端还是模块化,输入输出接口的定义直接决定模仿学习的监督信号质量。
# 模块化驾驶中 DAgger 数据聚合的伪代码示意
for episode in range(N):
state = env.reset()
learner_trajectory = []
while not done:
action = learner_policy(state) # 学习器自主决策
learner_trajectory.append((state, action))
state, done = env.step(action)
if expert_intervenes(state): # 专家判断是否需要纠正
expert_action = expert_policy(state) # 专家对当前状态标注
dataset.append((state, expert_action))
train(learner_policy, dataset) # 用聚合数据重新训练
理解自动驾驶的系统架构与两种范式,是后续设计 DAgger 交互式模仿学习方案的前提。只有明确“纠正发生在哪一层、监督信号是什么、状态空间如何定义”,才能让 DAgger 在驾驶工程中真正发挥作用。