CARLA 深度强化学习实战:从零构建自动驾驶决策模型

1次阅读
没有评论

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

image.webp

CARLA 深度强化学习实战:从零构建自动驾驶决策模型

背景介绍

CARLA 是一款开源的自动驾驶仿真平台,它提供了高度可配置的虚拟环境,支持多种传感器模拟(如摄像头、LiDAR、雷达等),并且可以模拟复杂的交通场景和天气条件。对于自动驾驶研发来说,CARLA 是一个理想的测试平台,因为它可以快速迭代算法,而无需承担真实道路测试的高成本和风险。

CARLA 深度强化学习实战:从零构建自动驾驶决策模型

传统规则式驾驶算法(如基于有限状态机的方法)虽然在特定场景下表现良好,但在复杂、动态的环境中往往显得力不从心。它们缺乏灵活性和适应性,难以处理未见的场景。相比之下,深度强化学习(DRL)通过与环境交互学习最优策略,能够更好地应对复杂多变的驾驶环境。

技术选型

在连续控制任务中,常见的 DRL 算法包括 DQN、PPO 和 SAC。

  • DQN(Deep Q-Network):适用于离散动作空间,但在连续控制任务中表现不佳,因为它需要对动作空间进行离散化,这会导致维度灾难。
  • PPO(Proximal Policy Optimization):一种 on-policy 算法,样本效率较高,训练稳定,适合连续动作空间。
  • SAC(Soft Actor-Critic):一种 off-policy 算法,结合了最大熵强化学习的优点,在探索和利用之间取得了良好的平衡,适合高维状态空间和连续动作空间。

考虑到自动驾驶任务的高维状态空间和连续动作空间,我们选择 SAC 作为基础算法,因为它具有更好的样本效率和稳定性。

实现细节

CARLA 环境封装

为了与标准的 DRL 框架兼容,我们将 CARLA 环境封装为 gym 接口。具体实现包括:

import gym
from gym import spaces
import carla

class CarlaEnv(gym.Env):
    def __init__(self):
        super(CarlaEnv, self).__init__()
        # 定义动作空间和状态空间
        self.action_space = spaces.Box(low=-1.0, high=1.0, shape=(2,), dtype=np.float32)
        self.observation_space = spaces.Dict({"camera": spaces.Box(low=0, high=255, shape=(84, 84, 3), dtype=np.uint8),
            "lidar": spaces.Box(low=0, high=100, shape=(360,), dtype=np.float32)
        })

        # 初始化 CARLA 客户端
        self.client = carla.Client("localhost", 2000)
        self.client.set_timeout(10.0)
        self.world = self.client.get_world()

    def reset(self):
        # 重置环境
        pass

    def step(self, action):
        # 执行动作并返回新的状态、奖励、是否终止、额外信息
        pass

状态空间设计

自动驾驶任务的状态通常包括多模态传感器数据:

  • 摄像头图像 :用于感知周围环境,如车道线、交通标志、其他车辆等。我们通常将图像缩放到 84×84 像素,并转换为灰度图以降低计算复杂度。
  • LiDAR 点云 :用于测量障碍物的距离和方向。我们将 LiDAR 数据转换为 360 维的向量,每个维度代表一个方向的最近障碍物距离。

奖励函数工程

奖励函数的设计是 DRL 成功的关键。一个好的奖励函数应该平衡安全性、效率和舒适度:

  • 安全性 :碰撞惩罚、车道偏离惩罚。
  • 效率 :速度奖励、到达目标点的进度奖励。
  • 舒适度 :急刹车或急转弯惩罚。
def compute_reward(self, state, action):
    # 安全性
    collision_penalty = -10.0 if self.collision_detected else 0.0
    lane_penalty = -1.0 if self.lane_departure else 0.0

    # 效率
    speed_reward = 0.1 * self.current_speed
    progress_reward = 1.0 if self.reached_waypoint else 0.0

    # 舒适度
    jerk_penalty = -0.5 * np.abs(action[1])  # 刹车 / 油门
    steer_penalty = -0.2 * np.abs(action[0])  # 方向盘

    total_reward = speed_reward + progress_reward + collision_penalty + lane_penalty + jerk_penalty + steer_penalty
    return total_reward

完整代码示例

以下是基于 PyTorch 的 SAC 实现,包含关键超参数和经验回放:

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.tensorboard import SummaryWriter
from collections import deque
import random

class ReplayBuffer:
    def __init__(self, capacity):
        self.buffer = deque(maxlen=capacity)

    def push(self, state, action, reward, next_state, done):
        self.buffer.append((state, action, reward, next_state, done))

    def sample(self, batch_size):
        return random.sample(self.buffer, batch_size)

    def __len__(self):
        return len(self.buffer)

class SAC:
    def __init__(self, state_dim, action_dim):
        # 初始化网络和优化器
        self.actor = ActorNetwork(state_dim, action_dim)
        self.critic = CriticNetwork(state_dim, action_dim)
        self.target_critic = CriticNetwork(state_dim, action_dim)

        self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=3e-4)
        self.critic_optimizer = optim.Adam(self.critic.parameters(), lr=3e-4)

        # 复制参数到目标网络
        self.target_critic.load_state_dict(self.critic.state_dict())

        # 经验回放
        self.replay_buffer = ReplayBuffer(100000)

        # TensorBoard 日志
        self.writer = SummaryWriter()

    def update(self, batch_size):
        # 从经验回放中采样
        batch = self.replay_buffer.sample(batch_size)

        # 更新 critic
        # ...

        # 更新 actor
        # ...

        # 更新目标网络
        # ...

        # 记录日志
        self.writer.add_scalar("Loss/critic", critic_loss, self.steps)
        self.writer.add_scalar("Loss/actor", actor_loss, self.steps)

性能优化

在训练过程中,常见的问题包括稀疏奖励和探索效率低。以下是解决方案:

  • 稀疏奖励 :可以通过设计更密集的奖励函数(如增量奖励)或使用内在好奇心模块(ICM)来鼓励探索。
  • 探索效率低 :可以结合课程学习(Curriculum Learning),从简单任务开始逐步增加难度。

避坑指南

以下是新手常见的错误及解决方法:

  1. 环境重置逻辑错误 :确保每次重置环境时,车辆和周围环境都回到初始状态。
  2. 观测归一化不当 :确保传感器数据在输入网络前进行了适当的归一化(如将图像像素值缩放到 [0,1])。
  3. 奖励函数设计不合理 :避免奖励函数过于稀疏或存在冲突,可以通过可视化奖励分布来调试。
  4. 超参数设置不当 :学习率、批大小等超参数对训练效果影响很大,建议参考相关论文或开源实现。
  5. 忽略随机种子设置 :为了结果可复现,应该固定随机种子。

进阶建议

为了进一步提升模型性能,可以考虑以下改进方向:

  • 集成模仿学习(IL)+ 强化学习(RL):先用 IL 预训练策略网络,再用 RL 微调。
  • 使用注意力机制处理视觉输入 :如 Transformer 或 Squeeze-and-Excitation 网络,以更好地捕捉重要特征。
  • 多任务学习 :同时学习车道保持、跟车、变道等任务,提升模型的泛化能力。

结尾

通过本文的介绍,你应该已经掌握了在 CARLA 平台上实现深度强化学习的基本流程。不过,DRL 在自动驾驶中的应用仍然面临许多挑战:

  1. 如何缩小仿真环境与真实世界之间的差距?
  2. 如何处理多智能体交互(如其他车辆和行人)?
  3. 如何保证模型的安全性和可解释性?

希望这些问题能激发你的思考,并推动你在自动驾驶领域的进一步探索。

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