
简介一份以深度强化学习算法为核心的车辆行为决策研究文档面向自动驾驶、机器学习方向的研究人员和学生也可为智能驾驶决策模块开发提供理论参考。文档围绕DQN和DDPG两条技术路线展开先介绍DQN借助卷积神经网络拟合Q值在离散动作空间中的应用及其局限再重点讲解DDPG如何结合Actor-Critic与确定性策略梯度解决油门、刹车、转向等连续控制问题并覆盖马尔科夫决策过程建模、状态值函数与Q函数推导、经验回放与目标网络稳定训练等关键内容。文档还梳理了策略网络多输出改单输出、多子策略集成等改进思路便于读者理解算法演进逻辑。资源为docx格式整包共1个文件大小约664KB目前已有115人学习可支撑课程论文、课题调研或算法入门参考。1. 从 DQN 到 DDPG为什么车辆行为决策要换算法如果你做过连续控制类的强化学习项目应该对 DQN 的局限性深有体会。DQN 在 Atari 游戏里能打出职业玩家水平但把它搬到自动驾驶的车辆决策上问题立刻暴露油门、刹车、方向盘都是连续量离散化之后动作空间爆炸式增长状态-动作对数量大到 Q 表根本存不下训练效率也直线下降。这篇研究选择了深度确定性策略梯度算法DDPG作为主框架并在此基础上做了引导式学习和优选经验回放两处改进最终在 TORCS 仿真平台上的训练轮数减少了 375 轮有效行驶距离提升了 133%。这篇文章适合正在做强化学习控制、自动驾驶决策或连续动作空间项目的工程师尤其是想在仿真环境里快速验证算法改进方向的人。我会从算法原理、改进设计、实验配置到结果分析完整拆解。2. MDP 建模与 DDPG 的连续动作空间适配2.1 马尔科夫决策过程的状态、动作与回报设计车辆行为决策本质上是一个序贯决策问题。强化学习把它建模成马尔科夫决策过程MDP用五元组(S, A, P, R, γ)描述。状态集合S在 TORCS 场景里是车辆与车道的相对位置、车身速度、车身角度等信息动作集合A是转向、油门、刹车这三个连续变量P是状态转移概率控制车辆动力学模型R是回报函数决定了 Agent 学习的方向γ是折扣因子通常取 0.9 到 0.99 之间的值用来平衡当前回报和未来回报的权重。关键问题在于如何求解最优策略π。传统基于表的方法比如 Q-learning 和 Sarsa需要为每个状态-动作对维护一个 Q 值。假设车速量化成 100 个等级转向量化成 50 个等级距离车道线的偏移量化成 20 个等级那么状态空间就是100 × 20 2000再结合动作空间Q 表的规模是百万级。这还算能接受但如果换成高精度连续控制量化粒度一细维度灾难立刻出现。这也是为什么 DQN 虽然用神经网络逼近 Q 函数解决了状态空间的表示问题却依然卡在离散动作输出上。DDPG 走的路线完全不同。它用确定性策略网络直接输出连续动作值不需要对动作空间做任何离散化处理。策略网络的目标函数定义如下L(θ) E[G_t | π_θ(s, a)] E[Σ γ^k R_{tk1}]这里的θ是策略网络的参数。更新时使用确定性策略梯度定理目标函数对参数的梯度是状态-行为值函数对动作的梯度乘以动作对参数的梯度∂L(θ)/∂θ E[∂Q(s, a, w)/∂a · ∂a/∂θ]这个公式的核心意义在于不需要对动作空间采样求和只需要求两条梯度路径的乘积计算量大幅降低而且天然支持连续动作输出。2.2 Actor-Critic 框架与目标网络软更新DDPG 是 Actor-Critic 架构。Actor 网络负责产生动作输入是环境状态输出是具体的转向、油门、刹车值Critic 网络负责评价这个动作的好坏输入是状态和动作输出 Q 值。训练时 Critic 通过最小化 TD-error 来逼近真实的 Q 函数Actor 则朝着让 Critic 输出更大的方向调整参数。为了解决时序样本相关性导致的训练不稳定问题DDPG 引入了经验回放机制和目标网络。经验回放把每一步交互产生的(s, a, r, s)存进经验池训练时随机批量采样打乱样本之间的相关性。目标网络更新采用软更新方式θ_Q τ * θ_Q (1 - τ) * θ_Q θ_π τ * θ_π (1 - τ) * θ_π其中τ是软更新系数通常取 0.001 到 0.01 之间。软更新的意义是让目标网络的参数缓慢逼近当前网络避免目标值剧烈波动导致训练发散。你会发现这个设计和 DQN 里的硬拷贝更新每隔若干步直接复制参数完全不同它让整个训练过程平滑很多。2.3 原始 DDPG 在车辆控制中的两个直接问题把标准 DDPG 直接跑到 TORCS 里我的实践经验是会出现两个典型问题。第一个是训练前期 Agent 完全没有方向感随机探索撞墙、出赛道是常态大量低质量经验样本被存进经验池白白浪费计算资源。第二个是车辆容易学到高速直线行驶的策略因为直线行驶时回报很高但到了弯道就来不及刹车直接冲出赛道导致训练长期卡在某个局部最优。问题根源在于两处一是初始策略没有先验知识完全从零开始探索二是经验池均匀采样劣质样本和优质样本对网络更新的贡献一样大。这篇研究提出的 LS-DDPG 正是针对这两个问题做了改进。3. LS-DDPG引导式学习与优选经验回放的设计细节3.1 引导式学习用专家控制器做预训练引导式学习的思路很直接既然新手独自探索效率低那就找个老师带一段路。具体做法是引入一个专业控制器作为老师先在 TORCS 里采集一批高质量驾驶数据用这些数据对 Actor 网络和 Critic 网络进行监督式预训练。预训练阶段不涉及强化学习的回报信号只学习状态到动作的映射关系。比如给定当前车辆位置、速度、角度专家控制器的输出就是合理的转向和油门值Actor 网络用回归损失去拟合这些数据。预训练完成后进入正式强化学习阶段。这时候需要控制预训练权重和策略网络的主导比重。常见做法是加一个随时间衰减的系数λ每一步动作由预训练策略和当前策略混合产生a λ * a_pretrained (1 - λ) * a_currentλ初始值可以设为 0.8随着训练步数线性衰减到 0。这样前期 Agent 主要模仿老师的行为不会乱撞后期逐步摆脱老师的影响自主探索更多动作边界。注意λ的衰减速度很关键衰减太快会导致 Agent 过早进入盲目探索衰减太慢则会让策略网络过度依赖老师学不到超越老师的策略。我在实验中通常把衰减周期设置为总训练步数的三分之一。3.2 优选经验回放经验池分离与采样比例控制优选经验回放针对的是经验样本质量参差的问题。它的核心操作是设置一个阈值d_th (d - l) / d其中d是赛道宽度l是车身宽度。车辆行驶位置在阈值以内认为是优样本存进优势经验池B_s超出阈值、发生碰撞或者回报值为负的样本存进劣势经验池B_f。阈值公式的物理含义很清晰车道宽度减去车身宽度剩下的就是车辆可以安全偏移的最大距离超出这个范围就存在出赛道风险。采样时不再均匀随机而是按比例α从两个经验池分别抽取。比如批大小M 32如果α 0.75则从优势池抽 24 条从劣势池抽 8 条。这样做保证每个 batch 里都有足够的正面样本引导学习方向同时保留少量负面样本防止模型过拟合到单一驾驶风格。α也要随训练步数逐渐降低比如每 1000 步降低 0.01最低到 0.5。原因很简单训练后期 Agent 策略已经趋向稳定如果仍然大量抽优势样本网络会过拟合失去对边缘情况的泛化能力。在这里我一般会用代码来描述采样逻辑def sample_batch(bs, bf, alpha, batch_size): n_s int(alpha * batch_size) n_f batch_size - n_s batch_s bs.sample(n_s) batch_f bf.sample(n_f) return batch_s batch_f参数alpha的初始值取决于训练阶段。如果预训练质量好初始alpha可以设置较高比如 0.8如果预训练效果一般建议从 0.6 起步避免 Agent 过早陷入保守策略。3.3 降低策略网络的更新频率第三个改进是控制策略网络和目标网络的更新频率低于 Critic 网络。标准 DDPG 每一步都同时更新四个网络但 Critic 网络的误差在连续更新中会累积放大尤其是出现过估计时策略网络会朝着错误方向更新。这篇研究采用的策略是Critic 网络每个 Step 都更新Actor 网络每隔n个 Step 更新一次目标网络跟随 Actor 的更新节奏软更新。n一般取 2 或 3。在实际实现里可以用一个简单的计数器控制if train_step % actor_update_freq 0: update_actor_network() update_target_networks(tau0.001)注意目标网络的更新频率如果太低τ要适当调大否则目标值更新跟不上当前网络的变化训练会不稳定。3.4 LS-DDPG 的完整伪代码流程结合上述改进LS-DDPG 完整流程可以归纳为以下步骤1. 初始化 Actor 网络、Critic 网络、Target-Actor 网络、Target-Critic 网络 2. 初始化优势经验池 B_s 和劣势经验池 B_f设置阈值 d_th加载预训练权重 3. 每个 Episode 循环 初始化状态 s_t初始化 OU 噪声 每个 Step 循环 将 OU 噪声添加到动作策略Actor 网络输出动作 a_t 将 a_t 送入 TORCS 环境得到回报 r_t 和下一个状态 s_{t1} 根据 r_t 和车辆位置是否超过 d_th将 (s_t, a_t, r_t, s_{t1}) 存入对应经验池 根据比例 α 从 B_s 和 B_f 采样总量 M 用 Target-Critic 计算期望回报最小化 Loss 更新 Critic 每隔 N 步更新 Actor 参数和 Target 网络参数 结束 Step 循环 结束 Episode 循环这里的 OU 噪声是 Ornstein-Uhlenbeck 过程它产生的时序相关噪声比高斯噪声更平滑适合连续控制问题。注意 OU 噪声的标准差要随训练步数衰减比如从 0.2 线性衰减到 0.02这样前期探索充分后期动作更稳定。4. 基于 Keras TORCS 的实验复现与参数配置4.1 运行环境与依赖版本这篇研究的实验环境是 Ubuntu 16.04Python 3.6Keras 2.1.6Tensorflow 1.13.2CUDA 10.0.130CUDNN 7.5.0强化学习环境用到 gym 和 TORCS 仿真平台。如果你现在复现建议直接用 TensorFlow 2.x 加 TORCS 的 gym 接口但要注意 Keras 2.1.6 的 API 和现在有差异Dense层和Adam优化器的参数写法需要调整。下面给出网络模型定义这是基于全连接网络的标准配置from keras.models import Model, Sequential from keras.layers import Dense, Input, Concatenate def build_actor(state_dim, action_dim): inputs Input(shape(state_dim,)) x Dense(600, activationrelu)(inputs) x Dense(300, activationrelu)(x) outputs Dense(action_dim, activationtanh)(x) return Model(inputs, outputs) def build_critic(state_dim, action_dim): state_input Input(shape(state_dim,)) action_input Input(shape(action_dim,)) x Concatenate()([state_input, action_input]) x Dense(600, activationrelu)(x) x Dense(300, activationrelu)(x) outputs Dense(1)(x) return Model([state_input, action_input], outputs)Actor 网络输出层用tanh激活把转向限制在[-1, 1]对应左打死和右打死。油门的输出范围应该是[0, 1]所以需要对tanh输出做线性变换steer actor_output[:, 0] # [-1, 1] throttle (actor_output[:, 1] 1) / 2 # [0, 1] brake (actor_output[:, 2] 1) / 2 # [0, 1]4.2 奖励函数的设置逻辑奖励函数是整个系统的指挥棒。这篇研究采用的奖励函数如下r (1 - tracPos) * (Vx * cosθ - Vx * |sinθ| - Vx * |tracPos * sinθ| - Vy * cosθ)其中tracPos是车辆距离赛道中心的规范化距离Vx是纵向速度Vy是横向速度θ是车身与赛道方向的夹角。这个公式的含义是车辆越靠近赛道中心tracPos越小奖励越高速度越快奖励越高但过大的横向速度或车身夹角会扣分惩罚高速入弯。实际调试时你会发现这个奖励函数本身对速度没有上限约束所以论文里额外加了约束条件碰撞返回 -50出车道返回 -100 或 -200速度低于 5 km/h 或 100 步无进展则终止回合。这里给出一段训练循环的伪代码方便你把参数对应起来for episode in range(MAX_EPISODES): state env.reset() episode_reward 0 for step in range(MAX_STEPS): action actor.predict(state) ou_noise() next_state, reward, done, info env.step(action) if reward 0 or abs(info[tracPos]) d_th: bf.add((state, action, reward, next_state, done)) else: bs.add((state, action, reward, next_state, done)) batch sample_batch(bs, bf, alpha, batch_size) # 更新 Critic每隔 N 步更新 Actor state next_state episode_reward reward if done: break4.3 关键超参数一览我从论文实验描述和实际项目经验里整理了核心超参数方便直接对比调整参数名 取值或范围 说明 actor 隐藏层 [600, 300] 2 层全连接 critic 隐藏层 [600, 300] 2 层全连接 转向输出范围 [-1, 1] tanh 激活 油门/刹车输出范围 [0, 1] 线性缩放 学习率 1e-4 (Actor) 建议低于 Critic 1e-3 (Critic) 折扣因子 γ 0.99 长期回报权重 软更新系数 τ 0.001 目标网络平滑度 经验池容量 1e6 越大越稳定 批大小 M 64 按显存调整 优势采样比例 α 0.7 → 0.5 随步数衰减 Actor 更新频率 2 个 Step 降低误差累积 OU 噪声标准差 0.2 → 0.02 线性衰减 经验池阈值 d_th (d - l) / d 赛道宽与车宽关系注意学习率的设定Actor 的学习率通常比 Critic 低一个数量级因为策略网络的更新幅度过大会导致动作输出剧烈抖动。另外经验池容量如果太小训练中后期采样的样本大多来自旧的策略网络会出现灾难性遗忘。5. 训练效率对比结果与两个工程化调参技巧实验在 TORCS 的 A-Speedway 地图上进行训练目标为赛车跑完 10 圈。对比 DDPG 和 LS-DDPG 的指标最直观的两个维度是训练轮数和总训练步数。论文数据显示标准 DDPG 训练 567 轮、78 102 步LS-DDPG 训练 192 轮、61 942 步。训练轮数减少了 375 轮效率提升 66.14%总步数降低 16 160 步效率提升 20.07%。平均每轮行驶步数从 138 步提升到 322 步有效行驶距离提升 133%。前期 LS-DDPG 的优势非常明显因为预训练模型让 Agent 一开始就知道如何保持在赛道内减少了大量无效探索动作。回报曲线方面LS-DDPG 在 150 轮后总回报基本平稳上升DDPG 则要到 400 轮后才进入稳定上升通道。代价是 LS-DDPG 训练后期平均回报略低于 DDPG原因是 LS-DDPG 有意识地控制车速弯道前会提前减速虽然牺牲了一些速度回报但行为更接近人类驾驶。这一点在实车移植时很重要因为高速度高回报的策略在实际环境中往往是不安全的。最后一个工程化技巧如果你的项目复现后训练收敛速度不理想先检查三个位置。第一d_th的计算是否按赛道实时宽度进行有些 TORCS 地图的赛道宽度不是恒定值要用分段函数处理。第二α衰减曲线是否平滑我习惯用余弦退火而不是线性衰减后期采样比例变化更平缓策略更稳定。第三预训练数据量是否足够建议至少采集 10 万步专家控制器数据否则预训练模型学到的映射关系太粗糙引导效果有限。先调这三个参数再动网络结构不迟。本文还有配套的精品资源点击获取