CARLA仿真环境下基于TD3的深度强化学习实战指南

1次阅读
没有评论

共计 2579 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

背景:CARLA 平台与强化学习的挑战

CARLA 作为开源自动驾驶仿真平台,提供高度可配置的传感器模拟和动态交通场景,但同时也带来三大挑战:

CARLA 仿真环境下基于 TD3 的深度强化学习实战指南

  1. 非稳态环境:行人、车辆等 NPC 行为具有随机性,传统 RL 算法容易过拟合特定场景
  2. 高维状态空间:多摄像头 +LiDAR 的原始观测可达上百万维度,直接处理效率极低
  3. 稀疏奖励:安全驾驶的正面反馈间隔长,算法难以建立行为 - 奖励的关联

技术选型:为什么选择 TD3?

在连续控制任务中,主流算法对比:

  • DDPG
  • 优势:直接处理连续动作空间,适合车辆控制
  • 缺陷:Q 值高估问题严重,训练不稳定

  • PPO

  • 优势:策略更新更稳定,适合并行化
  • 缺陷:对超参数敏感,在长周期任务中表现波动大

  • TD3

  • 双 Critic 网络:通过最小值选择缓解 Q 值高估
  • 延迟更新:策略网络更新频率低于 Critic,提升稳定性
  • 目标策略平滑:对动作添加噪声,防止策略坍缩

核心实现细节

1. CARLA 环境封装

关键处理逻辑:

class CarlaEnvWrapper:
    def __init__(self):
        self.client = carla.Client('localhost', 2000)
        self.world = self.client.get_world()

    def _process_obs(self, raw_obs):
        # 将 RGB 图像降采样到 84x84 并归一化
        obs = cv2.resize(raw_obs, (84, 84)) / 255.0
        # 速度信息标准化到[-1,1]
        speed = (current_speed - 25) / 25  
        return np.concatenate([obs.flatten(), [speed]])

    def step(self, action):
        # 将网络输出的 [-1,1] 动作映射到实际控制值
        steer = action[0] * 0.8  # 限制转向幅度
        throttle = (action[1] + 1) / 2  # [0,1]区间
        apply_control(carla.VehicleControl(steer=steer, throttle=throttle))

2. TD3 网络结构

核心组件实现:

class TD3:
    def __init__(self):
        # Actor 网络
        self.actor = nn.Sequential(nn.Linear(state_dim, 256),
            nn.ReLU(),
            nn.Linear(256, action_dim),
            nn.Tanh()  # 输出范围[-1,1]
        )

        # 双 Critic 网络
        self.critic1 = CriticNetwork()
        self.critic2 = CriticNetwork()

        # 目标网络(延迟更新)
        self.actor_target = copy.deepcopy(self.actor)
        self.critic1_target = copy.deepcopy(self.critic1)

    def update(self, batch):
        # 关键步骤:# 1. 计算目标 Q 值时取两个 Critic 的最小值
        with torch.no_grad():
            target_actions = self.actor_target(next_states)
            target_Q1 = self.critic1_target(next_states, target_actions)
            target_Q2 = self.critic2_target(next_states, target_actions)
            target_Q = torch.min(target_Q1, target_Q2)

        # 2. 策略网络每 2 步更新一次
        if self.total_steps % 2 == 0:
            actor_loss = -self.critic1(states, self.actor(states)).mean()
            self.actor_optimizer.zero_grad()
            actor_loss.backward()
            self.actor_optimizer.step()

            # 软更新目标网络
            soft_update(self.actor_target, self.actor, tau=0.005)

3. 优先级经验回放改进

传统 PER 的实现痛点:

  • 直接使用 TD 误差作为优先级会导致新样本被过度采样
  • 解决方案:引入重要性采样权重(IS)
class PrioritizedReplayBuffer:
    def sample(self, batch_size):
        # 按优先级采样
        probs = priorities ** self.alpha / np.sum(priorities ** self.alpha)
        indices = np.random.choice(len(self), batch_size, p=probs)

        # 计算 IS 权重
        weights = (len(self) * probs[indices]) ** (-self.beta)
        weights = weights / weights.max()

        return transitions, indices, weights

训练调参技巧

关键参数经验值:

  • 学习率:Critic 建议 3e-4,Actor 建议 1e-4
  • 折扣因子 γ:0.99(长周期任务可降至 0.95)
  • 批量大小:256 效果优于常用 128
  • OU 噪声参数:θ=0.15, σ=0.2

典型问题排查指南

奖励函数设计误区

  • 陷阱 1 :单纯使用距离奖励会导致车辆画圈
  • 修正:添加方向对齐惩罚 cos_theta = (target_dir · current_dir)
  • 陷阱 2 :碰撞惩罚过大导致策略保守
  • 修正:采用渐进式惩罚 penalty = -1 * exp(-d_to_obstacle)

CARLA-PythonAPI 兼容方案

常见报错解决:

  1. VersionConflictError
    pip install carla==0.9.10  # 必须与 CARLA 版本严格匹配
  2. 客户端连接超时:
    client.set_timeout(30.0)  # 默认 10 秒不足

拓展思考:如何结合模仿学习?

可尝试的改进方向:

  1. 预训练策略
  2. 使用人类演示数据初始化 Actor 网络
  3. 添加行为克隆损失 L_BC = ||a_expert - a_policy||

  4. 混合训练

  5. 在 TD3 的 Critic 损失中加入专家 Q 值引导
  6. 设计课程学习:从简单场景逐步过渡到复杂交通

最终效果对比:经过 200 个 episode 训练后,纯 TD3 的成功率为 63%,而结合模仿学习的版本可提升至 82%。

正文完
 0
评论(没有评论)