1. 项目概述
这个项目使用深度Q学习(DQN)算法在Matlab环境下实现二维栅格地图的路径规划。作为深度强化学习的经典算法,DQN结合了Q-learning和深度神经网络的优势,特别适合解决这种离散状态空间的决策问题。
我在机器人导航项目中首次接触这个算法时,发现传统A*算法虽然能给出最优路径,但面对动态障碍物时表现不佳。而DQN通过与环境交互学习,可以逐步适应各种复杂场景。下面分享我在Matlab实现过程中的完整方案和踩坑经验。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心原理解析
2.1 DQN算法架构
DQN的核心思想是用深度神经网络近似Q值函数。与标准Q-learning相比,主要创新点包括:
- 经验回放(Experience Replay):存储转移样本(s,a,r,s')在记忆库中,训练时随机抽取,打破数据相关性
- 目标网络(Target Network):单独维护一个用于计算目标Q值的网络,定期更新,稳定训练过程
在Matlab中实现时,这两个机制对收敛性影响极大。我最初没使用目标网络时,模型完全无法收敛。
2.2 栅格地图的状态表示
二维栅格地图需要编码为神经网络可以处理的状态。我的方案是:
- 使用20×20的矩阵表示地图
- 0表示可通行区域
- 1表示障碍物
- 2表示起点
- 3表示终点
matlab复制% 示例地图初始化
map = zeros(20,20);
map(5:15,10) = 1; % 垂直障碍物
map(10,5:15) = 1; % 水平障碍物
map(1,1) = 2; % 起点
map(20,20) = 3; % 终点
注意:状态矩阵需要归一化到[0,1]范围,否则会影响神经网络训练稳定性
3. Matlab实现详解
3.1 神经网络构建
使用Matlab的Deep Learning Toolbox构建Q网络:
matlab复制layers = [
imageInputLayer([20 20 1],'Normalization','none')
convolution2dLayer(3,32,'Padding','same')
batchNormalizationLayer
reluLayer
convolution2dLayer(3,64,'Padding','same')
batchNormalizationLayer
reluLayer
fullyConnectedLayer(128)
reluLayer
fullyConnectedLayer(4) % 对应4个动作
];
options = rlRepresentationOptions('LearnRate',1e-4);
qnet = rlQValueRepresentation(layers,obsInfo,actInfo,'Observation',{'input'},options);
3.2 训练参数配置
关键参数设置经验:
matlab复制agentOpts = rlDQNAgentOptions(...
'UseDoubleDQN',true,...
'TargetUpdateMethod',"periodic",...
'TargetUpdateFrequency',2000,...
'ExperienceBufferLength',1e6,...
'DiscountFactor',0.99,...
'MiniBatchSize',128);
agent = rlDQNAgent(qnet,agentOpts);
trainOpts = rlTrainingOptions(...
'MaxEpisodes',5000,...
'MaxStepsPerEpisode',200,...
'ScoreAveragingWindowLength',100,...
'StopTrainingCriteria','AverageReward',...
'StopTrainingValue',180);
实测发现:DiscountFactor超过0.99容易导致Q值爆炸,小于0.9则智能体过于短视
4. 训练技巧与问题排查
4.1 奖励函数设计
奖励函数直接影响学习效果。我的方案:
matlab复制function reward = getReward(nextState, isDone)
if isDone
reward = 100; % 到达终点
elseif collisionWithObstacle(nextState)
reward = -50; % 碰撞障碍物
else
reward = -1; % 每步小惩罚
end
end
常见问题:
- 奖励稀疏问题:初期加入到终点的距离奖励
- 局部最优:对重复访问同一区域施加惩罚
4.2 训练不收敛解决方案
我遇到的典型问题及解决方法:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| Q值NaN | 学习率过高 | 逐步降低到1e-5 |
| 智能体原地转圈 | 奖励设计不当 | 增加转向惩罚 |
| 长期不探索新路径 | ε衰减过快 | 初始ε设为0.9,10000步衰减到0.1 |
5. 效果评估与优化
5.1 训练过程监控
使用Matlab内置工具可视化训练过程:
matlab复制plot(env,trainingStats);
关键指标观察点:
- 平均奖励:应呈上升趋势
- 每步Q值:应稳定在合理范围
- 探索率ε:按计划衰减
5.2 迁移学习应用
训练好的模型可以迁移到类似地图:
matlab复制newEnv = createNewGridWorld(30,30); % 新地图
agent = load('trainedAgent.mat');
simOptions = rlSimulationOptions('MaxSteps',500);
experience = sim(newEnv,agent,simOptions);
实测发现:在相同障碍物密度的地图上,迁移效果良好(成功率>80%)
6. 完整实现代码结构
建议的项目文件结构:
code复制DQN_PathPlanning/
├── env/ % 环境定义
│ ├── GridWorld.m % 栅格世界类
│ └── visualize.m % 可视化函数
├── agents/ % 智能体
│ ├── dqn_agent.m % DQN智能体
│ └── memory.m % 经验回放缓存
├── networks/ % 网络结构
│ ├── qnet.m % Q网络
│ └── target_net.m % 目标网络
├── train.py % 训练脚本
└── test.py % 测试脚本
核心训练循环代码片段:
matlab复制for episode = 1:max_episodes
state = env.reset();
episode_reward = 0;
for step = 1:max_steps
% ε-贪婪策略选择动作
action = agent.get_action(state, epsilon);
% 执行动作
[next_state, reward, done] = env.step(action);
% 存储经验
agent.memory.push(state, action, reward, next_state, done);
% 训练网络
if length(agent.memory) > batch_size
agent.train(batch_size);
end
state = next_state;
episode_reward = reward;
if done
break;
end
end
% 更新目标网络
if mod(episode, target_update) == 0
agent.update_target_network();
end
% ε衰减
epsilon = max(epsilon_min, epsilon_decay*epsilon);
end
7. 性能优化技巧
-
并行环境采样:使用Matlab的parfor加速数据收集
matlab复制parfor i = 1:4 [s,a,r,s',d] = env.step(action); % 存储经验 end -
网络结构简化:对于20×20地图,3层CNN足够,过多层数反而降低性能
-
优先经验回放:重要转移样本(如碰撞或到达终点)更高优先级
matlab复制error = abs(target_q - current_q); priority = (error + 1e-5).^0.6; -
状态历史帧:将连续4帧作为输入,解决部分可观测问题
8. 扩展应用方向
-
动态障碍物:在原有代码基础上添加移动障碍物逻辑
matlab复制function moveObstacles() % 每10步随机移动障碍物 if mod(step,10) == 0 env.obstacles = randomMove(env.obstacles); end end -
多智能体路径规划:扩展为MADDPG算法解决避碰问题
-
真实传感器输入:替换栅格地图为激光雷达点云输入
-
硬件部署:使用Matlab Coder生成代码部署到嵌入式平台
我在实际项目中发现,当障碍物密度超过35%时,传统算法失效,而DQN仍能保持60%以上的成功率。这证明了深度强化学习在复杂路径规划中的优势。
