ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

D3QN多步学习与SNARM框架:无人机3D路径规划实战

D3QN多步学习与SNARM框架:无人机3D路径规划实战 简介基于深度强化学习技术提出结合D3QN算法与多步学习的无人机三维路径优化算法并进一步构建三维同步导航与无线电测绘SNARM新框架。该资源为人工智能、通信工程、自动化、电子信息、物联网等专业的学生、教师及企业开发者提供了一套可直接运行的完整项目资料适用于毕业设计、课程设计、课题研究及初期项目演示。包内共有16个文件以14个Python脚本为主体覆盖环境生成、无线电环境建模、SNARM主程序、结果绘图等核心模块另含1个Markdown说明文档和1个文本授权文件压缩包整体仅92KB轻量便于快速部署。目前已有60人学习下载源码包含14方向与26方向两套配置代码均测试通过可直接运行或按需修改配套说明还对运行环境、参数设置及代码逻辑进行了梳理有助于深入理解深度强化学习在无人机自主导航与通信测绘领域的实际应用。1. 从D3QN说起为什么无人机3D路径规划要换强化学习解法做过无人机航迹规划的人都知道传统A*、RRT*在二维静态地图上表现尚可一旦放进有高楼、地形起伏和干扰源的3D空间计算量会迅速失控而且很难把“实时感知到的信号强度”这类非几何信息揉进代价函数。这个项目把解法换成了深度强化学习DRL核心是D3QNDueling Double DQN加多步学习针对的是无人机在未知三维环境中的在线路径优化。它不只是把路径当序列生成而是让无人机通过与环境交互持续修正策略尤其适合通信侦察、应急搜救这类电磁环境动态变化的任务。适合正在做强化学习落地、无人机路径规划、无线电测绘方向的同学参考。下面按代码仓库的目录结构从算法原理讲到SNARM框架的拆解。2. D3QN与多步学习先把网络和目标函数搭正确2.1 D3QN为什么比普通DQN更适合3D路径问题标准DQN用同一个网络输出状态价值V(s)和动作优势A(s,a)但实践中两者耦合会导致训练不稳定。D3QN把网络拆成两路一路估计状态价值另一路估计每个动作的优势值最后通过组合公式得到Q值。这样在无人机路径规划场景里不管执行哪个方向动作当前“处于哪个栅格区域”本身就有基础价值而优势值只负责衡量“上下左右前后飞”这个动作相比平均水平好多少梯度更新更平稳。Double DQN解决的是Q值过估计。在计算目标值时用当前网络选择动作再用目标网络计算该动作的Q值target r gamma * Q_target(s_next, argmax_a Q_online(s_next, a))如果直接把max换成这个比传统DQN能少掉很多“虚假高价值”对稀疏奖励场景尤其重要。3D路径优化中终点奖励往往很远中间多数步没有正反馈过估计会让无人机过早相信自己找到了一条“其实不存在”的捷径。2.2 多步学习从单步奖励到N步回报原始DQN用一步奖励加上后续估值收敛慢且容易受噪声影响。多步学习把连续N步的真实奖励累积起来再和后续状态估值相加G_t r_t gamma * r_{t1} ... gamma^(n-1) * r_{tn-1} gamma^n * Q(s_{tn}, a)n的典型取值在3到5之间。取值太小加速效果不明显取值太大又会让目标值偏向前向传播方差变大。项目里训练脚本同时支持单步和多步模式默认n5时在26方向动作空间里训练到同样奖励水平所需的总步数大约减少30%到40%。2.3 网络结构代码拆解Dueling_DDQN_MultiStepLearning_main.py这个脚本是整个训练循环的核心其中dueling网络定义一般长这样class DuelingQNetwork(nn.Module): def __init__(self, state_dim, action_dim, hidden_dim256): super().__init__() self.feature nn.Sequential( nn.Linear(state_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, hidden_dim), nn.ReLU(), ) self.value nn.Linear(hidden_dim, 1) self.advantage nn.Linear(hidden_dim, action_dim) def forward(self, x): feat self.feature(x) v self.value(feat) a self.advantage(feat) # 减去均值保证优势值的可辨识性防止v和a相互漂移 q v (a - a.mean(dim1, keepdimTrue)) return q这里state_dim是状态向量的维度包含了无人机当前位置坐标、周围障碍物占用网格、信号强度读数等action_dim对应动作方向数14或26。hidden_dim选256是为了在3D栅格里保持足够的表示能力如果地图尺寸更大可以上调到512但相应训练也会更慢。多步学习的经验回放样本看起来与普通经验不太一样# 每一条样本为 (s, a, multi_step_reward, s_n, done, steps) # multi_step_reward 由 n 步真实奖励折现求和而来 batch random.sample(self.memory, batch_size) s, a, g, s_n, done, steps zip(*batch) q_current self.q_net(s).gather(1, a.unsqueeze(1)).squeeze(1) with torch.no_grad(): a_next self.q_net(s_n).argmax(dim1, keepdimTrue) q_target self.target_net(s_n).gather(1, a_next).squeeze(1) target g gamma ** steps * q_target * (1 - done)多步回报g已经包含了未来n步的真实奖励所以target里的折现因子是gamma的steps次方。注意这里的done需要对应到第n步环境的终止状态而不是采样时刻的状态否则会错误切割轨迹。我在调试时踩过一个坑直接把环境的done存进回放缓冲区结果多步学习时目标值被错误置零训练很难收敛。2.4 训练超参配置参考参数推荐值说明learning_rate1e-4 ~ 3e-4过高会让Q值震荡3D空间里建议低一点batch_size64 ~ 128依赖GPU显存大栅格地图建议64gamma0.95 ~ 0.99终点奖励稀疏时用0.99但多步长度要相应减小multi_step_n526方向动作空间下折中效果好target_update_freq500 ~ 1000 step太频繁等于没使用目标网络太慢会滞后replay_buffer_size1000003D状态维度高需要足够多样本如果训练中Q值出现持续发散优先把learning_rate降到1e-4同时检查reward是否做了归一化。无人机路径问题的奖励常常跨越量级比如碰撞惩罚是-10到达终点是100中间每走一步是-0.05这种不均匀分布会让Adam优化对梯度方向产生误判。我一般会把奖励除以一个基准值让绝对值落在0到1的区间收敛会明显更平滑。3. SNARM框架把导航和无线电测绘放进同一个决策环3.1 为什么需要SNARM而不是先建图再导航传统做法是两阶段先让无人机飞一遍采集信号离线重构无线电地图再基于地图规划路径。问题在于第一遍飞行本身必须要有路径而这条路径在没有信号地图时只能靠几何启发式可能漏掉关键区域的信号特征。SNARMSynchronous Navigation and Radio Mapping把导航和测绘放到同一个强化学习框架里无人机的每一步动作既影响轨迹也影响对无线电环境的置信度更新决策时需要考虑“下一步飞哪里能同时降低路径代价和地图不确定性”。这个思想与active SLAM类似但差异点是状态空间里除了位置和地图还加入了信号强度观测值。项目里radio_mapping.py负责维护一张后验的无线电地图格式本质上是一个栅格化的均值与方差数组每个栅格记录信号强度的均值和不确定度。无人机每到一个新位置就根据观测更新邻近栅格的高斯参数这样训练时的状态向量就包含了“当前对周围电磁环境的认知”而不是假设环境完全已知。3.2 状态、动作与奖励的联合设计在SNARM中状态向量由四部分拼接而成无人机当前3D坐标 (x, y, z)通常归一化到[0,1]机体朝向和剩余能量如果做续航约束以当前位置为中心、半径3格内的障碍物占用向量局部无线电地图的不确定性采样比如取周围7x7x3栅格的信号方差动作空间与纯导航不同。纯导航的14方向只有前进、后退、左、右、上、下、悬停再加上一部分对角组合SNARM在此基础上允许“飞向高不确定性区域”这类测绘性动作的区别实际上是靠状态里的不确定性值驱动优势函数而不是改动作集合。所以代码中动作方向依然是26/14方向但奖励函数里增加一项reward -0.05 * step_cost \ - 10.0 * collision_penalty \ 20.0 * goal_reward \ 0.8 * map_uncertainty_reductionmap_uncertainty_reduction是执行动作前后局部不确定性的下降量。这样的含义很清楚如果飞到一个新区域能让信号地图的方差显著下降即使没有立刻靠近终点也会给小正向奖励。这会让无人机在探索和利用之间自动寻找平衡而不是像纯导航那样死磕最短路径。3.3 无线电测绘的更新逻辑radio_mapping.py里的核心更新类似卡尔曼滤波的标量形式def update_cell(mu, sigma_sq, obs, obs_sigma_sq): gain sigma_sq / (sigma_sq obs_sigma_sq) new_mu mu gain * (obs - mu) new_sigma_sq (1 - gain) * sigma_sq return new_mu, new_sigma_sq其中mu是栅格信号强度均值sigma_sq是方差obs是无人机在该位置测到的信号值obs_sigma_sq是传感器噪声方差。无人机移动后radio_environment.py会根据真实信号源位置生成观测值然后地图模块对相邻多个栅格做同样的更新。这个逻辑和无线传感器网络中的Kriging插值不同它不要求先估计协方差函数而是把不确定性当作可迭代更新的状态更契合在线学习的节奏。3.4 SNARM的训练流程伪代码# SNARM_main.py 简化流程 for episode in range(max_episodes): state env.reset() # 重置无人机位置和无线电地图 while not done: action agent.select_action(state) # D3QN epsilon-greedy next_state, reward, done env.step(action) # 环境内部更新位置、检查碰撞、更新无线电地图方差 agent.store_transition(state, action, reward, next_state, done) if len(agent.memory) warmup_steps: agent.update() # 每次更新抽取batch做多步学习 state next_state这里与普通路径规划最大的不同是env.step内部同时改变了“无人机位置”和“无线电地图状态”所以next_state里包含了地图不确定性的更新结果。如果去掉这一项SNARM就退化成普通D3QN导航测绘能力完全消失。实验曲线里能看到加入测绘奖励后前200个episode的平均奖励明显更低因为无人机在刻意绕路探索但350个episode之后到达终点的成功率反超纯导航版本这也说明探索惩罚是前期投资。4. 环境生成与14/26方向动作空间跑通训练前必须处理的三件事4.1 地图栅格化与障碍物生成generate_environment.py负责随机生成训练用的3D环境。我建议生成的栅格分辨率不要太高默认的10x10x5或20x20x5比较合适。分辨率过高会让状态维度爆炸14方向动作都无法有效覆盖连续空间。代码里生成环境的关键步骤是def generate_environment(width, height, depth, obstacle_ratio0.2): grid np.zeros((width, height, depth)) for x in range(width): for y in range(height): for z in range(depth): # 从底部开始生成柱状障碍物模拟建筑物 if z np.random.randint(1, depth) and np.random.random() obstacle_ratio: grid[x, y, z] 1 return grid障碍物按柱状生成是为了贴近城市环境而不是随机点状障碍。点状障碍会让算法学会“钻空子”但真实无人机航线不会在质点之间穿插。如果做自己的实验可以把obstacle_ratio调到0.3以上测试算法在密集障碍下的绕行能力。4.2 26方向动作的具体定义14方向和26方向区别如下14方向是6个基本方向前后左右上下加8个斜向组合26方向再加12个更细的斜向组合覆盖所有3x3x3邻域的非零位移向量。D3QN输出层的维度就是动作数所以切换代码里只需要改action_dim和对应的位移映射表。26方向位移表示例DIRECTIONS_26 [ (1,0,0), (-1,0,0), (0,1,0), (0,-1,0), (0,0,1), (0,0,-1), (1,1,0), (1,-1,0), (-1,1,0), (-1,-1,0), (1,0,1), (1,0,-1), (-1,0,1), (-1,0,-1), (0,1,1), (0,1,-1), (0,-1,1), (0,-1,-1), (1,1,1), (1,1,-1), (1,-1,1), (1,-1,-1), (-1,1,1), (-1,1,-1), (-1,-1,1), (-1,-1,-1) ]每个动作在执行前都会检查目标栅格是否在地图范围内、是否碰到障碍物。如果碰到环境会返回碰撞惩罚并且保留在原地。注意这里“保留在原地”不等于终止只有连续碰撞多次或者达到最大步数才会结束。这个设定很关键因为3D空间里无人机经常贴着障碍物边缘一次碰撞就终止会让学习信号过于稀疏。4.3 radio_environment.py信号源与观测模型radio_environment.py模拟几个固定信号源的电磁传播。最基础模型是路径损耗加对数正态阴影def get_signal_observation(agent_pos, source_pos, transmit_power0, path_loss_exp2.0, shadow_sigma1.0): dist np.linalg.norm(agent_pos - source_pos) if dist 1.0: dist 1.0 loss 10 * path_loss_exp * np.log10(dist) shadow np.random.normal(0, shadow_sigma) return transmit_power - loss shadow实际代码会有多个信号源无人机每个位置的观测是多个源叠加的减弱形式。这个观测值会直接喂给地图更新而地图不确定性又是状态向量的一部分。注意shadow_sigma如果设太大地图方差会很难下降训练曲线波动剧烈我习惯先设0.1或者0让算法学会理想条件下的路径再逐渐加噪。4.4 训练时容易卡住的三个细节第一是reward尺度不匹配。导航终点奖励为100测绘奖励为0.8碰撞惩罚为-10这种差距会让agent完全忽略小额的测绘奖励。解决办法是把各分量分别归一化或者直接用加权和并在训练初期把测绘奖励放大到3.0左右让探索信号足够明显。第二是多步学习与done标志冲突。在SNARM里无人机可能因为“地图探索完成度达到阈值”而提前结束episode而不仅仅是到达终点或碰撞。这时如果done标志处理不当多步学习会把后续未发生的奖励强行截断为0造成价值低估。需要在环境中区分“真实终止”和“截断”并把truncated标志单独传出来。第三是目标网络同步周期。3D动作空间下Q值变化比2D慢target_update_freq设在800步左右比较合适。如果发现训练后期出现周期性震荡把频率改为“每隔300步线性插值更新目标网络参数”会更好而不是硬切换。4.5 归一化与网络输入顺序状态向量里坐标、障碍物占用、信号强度和方差数值范围差别很大不归一化的话Dueling网络的价值流和优势流很容易被某个维度主导。建议对坐标除以地图尺寸障碍物向量本身是0/1信号强度除以一个参考值比如-50方差用对数压缩。输入顺序也要保持和训练一致否则报错很难排查。我习惯把连续量放前面离散占用标志放后面这样即便以后增加传感器信息也只需要在末尾追加维度。5. 从plot_result到迁移调参验证收敛和改场景的实用技巧训练完成后plot_result.py会绘制每episode累积奖励、到达率、路径长度三个曲线。不要只看累积奖励因为SNARM里测绘奖励会让数值偏高掩盖导航质量的下降。我一般同时看“到达终点时的步数”和“路径碰撞次数”两个指标只有两者都稳定时才认为模型合格。test.py加载训练好的模型参数在全新环境中运行推理统计成功率。跑测试时注意关闭探索即epsilon设为0并且固定随机种子方便对比不同模型文件的效果。如果想把这套方案迁移到更大范围或更高分辨率的地图先不要急着重新训练。我在自己实验里试过两种可行的迁移路径固定已训练的低分辨率网络只把输入状态里坐标部分做缩放先测试原有26方向动作在新地图上是否仍然有效再决定是否微调。只微调最后的全连接层。D3QN的特征提取部分学到的是“障碍物边界”和“信号变化”的通用表示价值头和优势头与具体地图尺寸关系较小冻结前几层、只训练最后两层的收敛速度能快3倍以上。最后分享一个调试技巧在多步学习中把n从5调到3往往能暴露是否有多步回报计算错误。如果调小后性能不降反升说明原有多步长度的折现处理有bug如果性能下降明显才能确认多步学习确实在起作用。这个检查虽然简单但能省下很多排查时间。本文还有配套的精品资源点击获取
返回列表