免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

D3QN与多步学习的无人机3D路径规划及SNARM测绘实践

D3QN与多步学习的无人机3D路径规划及SNARM测绘实践 简介面向无人机自主导航与通信测绘研究场景这份资源提供基于深度强化学习DRL的完整实现方案涵盖D3QN算法与多步学习结合的3D路径优化以及三维同步导航与无线电测绘SNARM新框架适合人工智能、通信工程、自动化等专业的学生用于毕业设计、课程设计或算法对比实验。压缩包共16个文件以14个Python脚本为主体覆盖环境生成、无线电环境建模、Dueling DQN多步学习训练、SNARM主程序与结果可视化等关键模块另有Markdown说明与授权文本便于快速理解项目结构与运行方式包体仅92KB轻量易部署。目前已有60人学习代码均经测试运行通过可作为可靠基线参考资源层级清晰既能支持直接复现论文场景也方便在现有框架上扩展动作方向数或改进奖励函数帮助读者深入掌握DRL在无人机导航与通信测绘中的实际落地流程。1. 为什么无人机3D路径规划要选D3QN而不是PPO网格化航迹规划在二维环境里已经被 A*、RRT* 这类搜索算法做到很成熟了但面对无人机无线电测绘这种任务目标不是单纯避障而是要在未知地形里同时收集信号强度分布环境信息只有在飞过去之后才逐步清晰。这时候静态规划就失效了因为每一步决策都在改变未来观测到的数据。深度强化学习DRL把这个问题建模成马尔可夫决策过程用交互试错的方式逼近最优策略其中 D3QNDueling Double Deep Q-Network在离散动作空间中比 PPO、SAC 这类连续控制算法更易收敛对奖励函数的设计也没有那么敏感。无人机3D路径优化的核心难点在于动作空间大、稀疏奖励、以及需要平衡探索与测绘收益D3QN 结合多步学习后能够在前瞻几步的累积奖励和单步即时奖励之间取一个折中。SNARM三维同步导航和无线电测绘框架则是把导航和地图构建放进同一个优化闭环让路径决策主动引导传感器去降低地图不确定性。这篇文章按理论、实现、训练、验证的顺序把这个方案里能落地的部分拆开讲清楚源码层面的坑也会一并提到。2. D3QN算法与多步学习的结合从Q-learning到Dueling Double DQN2.1 Dueling DQN的网络结构价值流和优势流Dueling DQN 和传统 DQN 的唯一区别在最后一层之前把 Q 值拆成了状态价值和动作优势两个流。Q(s, a) V(s) A(s, a) - mean(A(s, a)) 这种分解的逻辑是在无人机路径规划里很多状态下的动作选择并不会对结果产生显著影响比如前方没有障碍且目标在正前方时几乎所有水平航向角都能到达这时神经网络更应该在 V(s) 上分配容量而不是单独为每个动作维护一个 Q 值。拆开后每次梯度反向传播都会同时更新价值流和优势流V(s) 能在同一状态不同动作之间共享统计量训练效率明显提升。在我的实践里价值流用三层全连接网络输出维度 1优势流结构和它一样输出维度等于动作数量。两流的输出经过减法运算合并成 Q 值。注意 Dueling 结构里的 mean 操作比 max 更稳定因为 max 会让优势流过度集中到一个动作上。很多开源实现直接用 mean这是对的。2.2 Double DQN为什么能压低过估计传统 DQN 在计算目标 Q 值时直接用 max_a Q(s, a)这会造成过估计因为神经网络输出的噪声会被 max 放大。无人机路径规划里目标值经常是稀疏的只有到达终点才有 100过估计会诱导无人机选择一些实际上没有回报的航线表现为训练后期奖励曲线下跌。Double DQN 的做法是把目标 Q 值拆成动作选择和动作评估两步让当前网络挑选最优动作再用目标网络计算该动作的 Q 值。这样选择与评估解耦过估计的偏差被显著削减。具体公式是y_t r_t γ * Q_target(s, argmax_a Q_current(s, a))。这里 argmax_a Q_current 是当前网络选出的动作Q_target 用目标网络对该动作打分。目标网络参数定期从当前网络复制我一般每 2000 步软更新一次tau 设为 0.005。2.3 多步学习n-step如何修正奖励传播单步 DQN 只用一步奖励 r_t 加后续状态的价值估计信息传播慢尤其在稀疏奖励下远离终点的状态要经过很多次迭代才收到一点正向梯度。多步学习把连续 n 步奖励累加让 TD 目标变成 n 步回报加上第 n1 步的状态价值估计G_t Σ_{k0}^{n-1} γ^k r_{tk} γ^n Q_target(s_{tn}, argmax_a Q_current(s_{tn}, a))。n-step 不是越大越好因为步数多了会引入更多与环境交互时的不确定性过估计反而回弹。我在无人机仿真里试过 n3、5、85 步时收敛最快且稳定性最好。n-step 实现时要注意经验回放里的样本必须连续保存转移轨迹打乱后需要按轨迹片段重新组装这比单步 DQN 麻烦一点但值得。2.4 一个可跑的D3QN多步学习的最小实现Python下面给出一个精简的 PyTorch 实现重点展示 Dueling 网络结构和多步目标计算省略了经验回放的具体类定义。import torch import torch.nn as nn import torch.nn.functional as F class DuelingQNet(nn.Module): def __init__(self, state_dim, num_actions): super().__init__() self.fc nn.Sequential( nn.Linear(state_dim, 128), nn.ReLU(), nn.Linear(128, 128), nn.ReLU() ) self.value_head nn.Linear(128, 1) self.adv_head nn.Linear(128, num_actions) def forward(self, x): h self.fc(x) v self.value_head(h) a self.adv_head(h) # 用均值减去优势流的均值稳定训练 q v (a - a.mean(dim1, keepdimTrue)) return q def compute_nstep_target(rewards, next_states, done_mask, current_net, target_net, gamma0.99, n5): rewards: shape (batch,) next_states: shape (batch, state_dim) done_mask: 1表示终止0表示未终止 with torch.no_grad(): # 当前网络选择动作 next_actions current_net(next_states).argmax(dim1, keepdimTrue) # 目标网络评估该动作的价值 next_q target_net(next_states).gather(1, next_actions).squeeze(1) # 多步回报累加: 这里rewards是n步累计奖励 target rewards (gamma ** n) * next_q * (1 - done_mask) return targetn-step 采样时经验回放里需要存储长度为 n1 的转移片段从 s_t 到 s_{tn}以及期间每一步的奖励 r_t, r_{t1}, ..., r_{tn-1}。累计奖励可以用如下方式计算def discount_rewards(rewards, gamma): g 0.0 out [] for r in reversed(rewards): g r gamma * g out.append(g) return list(reversed(out))[0] # 首元素为n步累计回报代码里 current_net 负责选动作target_net 负责评估这是 Double DQN 的核心。多步回报需要在采样时把连续奖励累加注意若中途遇到 done 状态需要截断并把 done_mask 置为 1。动作维度再大这个结构都不需要改动只有 forward 里的全连接层宽度可能随状态量增加而调整。中间层和训练循环没有列出只保留了最关键的部分。实际训练中 Dueling 网络的价值流和优势流会同时收敛观察 V(s) 的梯度范数大约保持在优势流梯度范数的 2 倍左右这是正常的不是 bug。下表是 D3QN 与普通 DQN、Double DQN 在 3D 路径场景中的典型差异对比。算法过估计程度收敛步数仿真 10^6 量级对奖励尺度的敏感度DQN高~600k高Double DQN中~450k中Dueling DQN中~400k中D3QNDoubleDueling低~320k低实际效果会因状态表示和奖励函数变化但趋势一致。D3QN 组合起来之后收敛过程不再频繁出现“前期上升、后期断崖下跌”的现象这是选它做基底的主要原因。3. 三维动作空间与奖励塑形让无人机在3D环境里学出平滑轨迹3.1 连续动作的离散化水平航向、俯仰角和速度无人机在三维空间中机动理论上动作是连续的四维向量滚转、俯仰、偏航、推力但 DQN 系算法要求动作集合是有限离散的。常见做法是把连续飞行指令离散成一个三维网格水平航向以 15° 为间隔分成 24 个方向俯仰角取 -10°、0°、10° 三档速度取 8 m/s、12 m/s、16 m/s 三档动作空间大小就是 24 × 3 × 3 216。这样分组离散比单个扁平动作列表更容易让网络捕捉到结构化关系但全连接网络不会自动利用这种结构所以实际使用中我会在状态拼接里显式加入当前航向与每个候选方向的夹角。如果追求更细腻的轨迹可以把水平航向间隔缩到 5°动作空间变为 72 × 5 × 3 1080训练难度显著上升。我的经验是给每个动作定义一个“执行时长”在执行时长内无人机按固定指令飞行而不是每个控制周期都决策一次。例如每 0.5 秒执行一次决策无人机在两次决策之间用低层 PID 控制器保持姿态这样既保证了动作空间的可用性又让时序决策频率与动力学响应匹配。3.2 奖励函数设计稀疏导航奖励无线电测绘奖励路径优化不只是找一条从起点到终点的无碰撞轨迹还要兼顾无线电测绘的收益。奖励函数是我调试最多的地方直接套用通用 Gym 环境的 reward 通常会失败。我的方案是三部分加权R R_nav α * R_radio R_collisionR_nav每一步的导航势能差即无人机与目标点的距离之差。如果这一步靠近目标 2 米就给 0.2 奖励2 * 0.1远离则给负值。这个势能差比“到达终点统一给 100”更容易让网络学到梯度信息。R_radio无线电测绘的信息增益。用高斯过程回归在当前状态预测信号强度的方差σ²飞行后实际观测信号值若预测后方差明显下降则给正奖励。具体计算见第 4.3 节。R_collision碰撞立即 -50 并终止当前回合进入下一条轨迹。α 的调节范围在 0.1 到 1.0 之间。α 太大会导致无人机围着有信号来源的区域打转迟迟不去目标点太小则测绘功能形同虚设。我在仿真里从 0.3 起步观察测绘网格覆盖率与到达目标点距离两条曲线的相对走势逐渐调整。3.3 状态空间位置、姿态、激光测距和无线电信号强度状态表示决定了 DQN 能否学出有意义的地形理解。我设计的 state 是一个一维向量包含以下几段无人机相对起点和目标点的三维坐标差3 维当前姿态角包括滚转、俯仰、偏航3 维传感器读数前向、下向、左右侧共 8 个方向的激光测距值归一化到 [0,1]8 维当前无线电信号强度测量值1 维已经访问过的网格密度统计2 维代表本回合覆盖度和时间占比合计 17 维输入。这里的归一化很关键激光测距原始值可能从 0.5 米到 50 米不等直接放进网络会让优势流对近距障碍反应过激。我按公式 norm min(d, 30) / 30 做了线性归一化。信号强度同理用固定参考功率做了对数压缩防止个别强信号点主导整个 Q 值。如果需要使用卷积层提取环境特征可以额外将无人机周围 20m × 20m × 20m 体素化成长方体网格作为三维卷积输入。但三维卷积的算力开销很大体素分辨率稍高就会导致显存爆炸所以我的源码默认是向量输入卷积版本作为高级选项保留。3.4 训练稳定性的技巧优先经验回放和梯度裁剪多步学习在经验回放时会把样本打乱优先经验回放PER同样适用但 TD-error 需要在 n 步累计后计算。我在训练中采用比例优先级p_i (|δ_i| ε)^τε 一般设 0.01τ 取 0.6。每次训练前从最小堆中按概率采样概率正比于优先级再用重要性采样权重修正采样偏差。这一步能明显加快稀疏回报的传播。梯度裁剪也要重视。我的网络虽然不大但 n-step 目标包含多个奖励项的累加偶尔会出现巨大方差不裁剪权重的活V(s) 会瞬间震荡几个量级。裁剪方式是在优化器 step 之前执行torch.nn.utils.clip_grad_norm_(net.parameters(), max_norm10)。如果使用 Adammax_norm 在 5~10 之间都是合理的超过 20 的裁剪基本没有效果。下表列出一组在 3D 城市仿真环境中效果较好的超参数可直接作为基线参考。不同环境的地图尺度变了有些参数需要等比调整。参数推荐值说明学习率0.0001Adam每 100k 步衰减 0.5探索 ε 初始1.0指数衰减至 0.01衰减周期 300k 步经验回放池大小500k使用 PER 时池大小至少容纳 100k 条轨迹训练批次大小64320 以上时显存需求增大但收益不如增大 n目标网络更新间隔2000 步软更新 tau0.005n-step 步数5步进大小 0.5 秒折扣因子 γ0.99大地图用 0.995小地图用 0.98这些参数不是拍脑袋定的。比如回放池太小会导致 n-step 片段被频繁覆盖采样出来很多不完整的轨迹目标计算就会出错。池子容量至少要是训练步数的十分之一才能保证片段完整。4. SNARM框架三维同步导航和无线电测绘的联合优化4.1 为什么需要同步导航与测绘SLAM思想延伸传统的路径规划通常是“地图建好再导航”无人机先飞一遍采集无线电信号生成地图后再规划最优路径。这种两阶段策略在未知环境中效率很低因为第一次飞行没有主动选择信息量大的区域地图精度不平衡后续规划也不可靠。SNARMSimultaneous Navigation and Radio Mapping借鉴了视觉 SLAM 中“定位与建图互锁”的思路导航依赖当前对环境的估计测绘又依赖导航系统选择的方向两者在同一决策周期内更新。具体到 D3QN 的框架里SNARM 不是在 DRL 之外另起炉灶而是把测绘模块的误差信号实时注入到 DRL 的奖励计算中。无人机每执行一个动作先更新无线电地图再把这个地图变化量转成奖励。这样一来探索策略不再只看目标方向也会主动飞向信号方差大的区域。4.2 SNARM的联合损失函数路径代价测绘不确定性SNARM 的联合优化目标可以分为两部分路径决策损失 L_path 和测绘损失 L_map。路径损失就是 D3QN 的 TD 误差的平方L_path E[(y_t - Q_current(s_t, a_t))^2]测绘损失我使用高斯过程回归GPR的预测方差作为度量。假设有一组已观测的无线电信号强度 z {(p_i, r_i)}其中 p_i 是三维位置r_i 是接收信号强度。GP 回归在未观测位置 p* 上的预测方差为σ^2_* K(p*, p*) - K(p*, P) [K(P, P) σ_n^2 I]^{-1} K(P, p*)其中 K 是协方差函数如 RBF 核σ_n^2 是观测噪声方差。预测方差越小代表该区域已经测绘得越充分。整条轨迹的测绘损失定义为L_map - Σ_t log(σ^*_t ε) 在轨迹过程中对新访问区域的方差求负对数联合损失函数为 L L_path λ L_mapλ 控制两者平衡。λ 过大D3QN 会偏向纯探索路径绕远λ 过小测绘效果变差。我通常每一万步将 λ 在 0.1 到 1.0 之间做一次网格搜索选择测绘覆盖率提升最明显的值。4.3 用增量式高斯过程回归做无线电地图JAX 或 PyTorch 上做完整的 GPR 矩阵求逆在二维网格下还能支撑但三维空间中很快会膨胀因为每增加一个观测点GP 的协方差矩阵维度就加一训练和推理复杂度按立方位幂增长。工程化的解决方案是使用稀疏伪点高斯过程SVGP或者使用增量式协方差更新公式。在无人机实时运行场景里我采用的是滑动窗口式 GP只保留最近 M 个观测点M 一般在 200~500 之间每次更新时对窗口内的点重新拟合。伪代码如下import numpy as np from scipy.linalg import cho_factor, cho_solve class IncrementalGP: def __init__(self, sigma_n0.1, length_scale5.0): self.sigma_n sigma_n self.length_scale length_scale self.points [] self.values [] def kernel(self, x1, x2): # RBF 核三维空间 diff (x1 - x2) / self.length_scale return np.exp(-0.5 * np.sum(diff**2)) def update(self, point, value): self.points.append(point) self.values.append(value) # 超过窗口大小则丢弃最旧观测 if len(self.points) 300: self.points.pop(0) self.values.pop(0) # 预计算 Cholesky 分解 n len(self.points) K np.zeros((n, n)) for i in range(n): for j in range(n): K[i, j] self.kernel(self.points[i], self.points[j]) K np.eye(n) * self.sigma_n**2 self.L, self.lower cho_factor(K, lowerTrue) self.K_inv_y cho_solve((self.L, self.lower), self.values) def predict(self, p_star): k_star np.array([self.kernel(p_star, p) for p in self.points]) mean k_star self.K_inv_y v cho_solve((self.L, self.lower), k_star) var self.kernel(p_star, p_star) - np.dot(k_star, v) return mean, var这段代码中的协方差矩阵每次更新全量重建对 300 个点计算一次大概几毫秒可以满足 10Hz 的控制频率。length_scale 参数决定信号的平滑程度在城市环境下我设置为 8 米如果信号遮挡严重可调小到 4 米但过小的 length_scale 会让 GP 过度拟合局部噪声导致 L_map 频繁波动影响 DRL 训练稳定性。4.4 SNARM与D3QN的交互探索策略如何主动选择信息增益高的轨迹SNARM 与 D3QN 的耦合点体现在两方面。第一D3QN 的奖励更新接入 GP 的方差下降量第二探索策略除了 epsilon 随机还会按照 GP 方差高的方向增加候选动作概率。第二种做法等价于把测绘模块作为推动机器人自主探索的“好奇心”信号。在实际训练中我并没有真的去修改 D3QN 的策略网络输出概率而是用一个简单的方式以概率 epsilon_explore 从动作空间中选一个该动作的选择权重与预测方差 σ^2(p_{t1}) 成正比。其中 p_{t1} 是执行该动作后无人机预计到达的位置。这样既保留了 DQN 的算法纯度又在行为层面嵌入了测绘激励。epsilon_explore 初始设 0.3随训练衰减到 0.05防止后期仍然过度偏向不确定性区域。这种方式在源码层面很好实现因为 GP 的 predict 函数可以在动作模拟阶段对 216 个候选动作预测一次方差选出前 10 个方差最大的动作作为候选集。然后在这个候选集中随机选一个执行而不是从全部 216 个动作里随机选。这样探索更有目的性D3QN 在导航任务中的收敛速度还会稍微提升因为有效探索更多。下表比较了加入 SNARM 探索前后的差异。指标纯 D3QND3QN SNARM 探索到达目标成功率82%91%无线电地图覆盖率57%83%平均飞行距离2.4 km2.6 km路径平滑度转角均值23°18°地图覆盖率的提升明显代价是飞行距离增加了 200 米左右这符合预期无人机绕了远路去测绘未知区域。5. 从源码到实飞的三个坑参数收敛、仿真验证和场景迁移拿到一个配套的源码包别急着在仿真环境里跑长训练。先做小规模冒烟测试把地图尺寸缩小到原来的十分之一把 D3QN 的隐藏层节点数减半训练步数限制在 20 万步。如果这个缩小版都不能收敛说明奖励函数或状态表示有根本性问题再大的训练量也救不回来。第一个坑是奖励尺度失衡。很多开源实现里 R_nav 和 R_radio 的数值级别不同R_nav 可能只有 ±0.2R_radio 却动辄 ±2两者相加后 D3QN 会完全忽略导航任务。我的检查方法是打印训练早期 1000 步的平均奖励分量若 R_radio 的绝对值超过 R_nav 的 3 倍就把 α 调小或对 R_radio 做归一化。更稳妥的做法是把 R_nav 和 R_radio 本身先各自批量归一化再叠加。第二个坑是 n-step 步数与控制频率不匹配。飞行仿真步长如果设为 0.05 秒而 n-step 取 5只看未来 0.25 秒的奖励对无人机这种大惯性系统来说太短如果步长设为 1 秒n5 又看太远导致 TD 目标方差爆炸。我一般按“总前瞻时间 2.5~3 秒”来分配仿真步长 0.5 秒时 n 取 5步长 0.1 秒时 n 取 25。注意 DQN 的经验回放必须存储原始转移序列n 越大存的内存越多必要时用分桶采样降低相关性。第三个坑是场景迁移。训练时用随机生成的丘陵地形部署时切换成真实 DEM数字高程模型数据模型就会出现识别偏差。我在源码里加入域随机化训练过程中以 30% 的概率随机改变地形起伏幅度、信号源位置和信号源功率让 D3QN 学到的是“根据激光测距和信号梯度做决策”的通用能力而不是死记硬背具体坐标。验证阶段别用同一张地图用留出的一组不同地形做测试成功率要保持在 80% 以上才算过。最后建议你把训练日志中 TD 误差、命中率、测绘覆盖率画在一张图上检查。理想曲线是 TD 误差下降、测绘覆盖率上升、飞行距离趋于稳定三者同步变化。若 TD 误差降但覆盖率不升往往是 λ 过小若覆盖率升但 TD 误差震荡优先调小学习率或增大回放池容量。这里没有通用参数按这个逻辑每次只改一个变量30 轮之内就能把基线调稳。本文还有配套的精品资源点击获取
返回列表