拓冰建站拓冰建站
首页 / 资讯中心 / 正文

MATLAB深度强化学习实战:环境构建、奖励函数与部署技巧

简介面向人工智能和机器学习学习者的MATLAB深度强化学习案例程序涵盖DQN、PPO、DDPG、TD3等主流算法。包内21个文件包含7张示意图、7个XML配置、5个MathML公式和2个Rels关系文件共1.18MB便于快速获取与本地实验。内容分为环境构建、算法训练、算法分析三部分既有预设或自定义环境的搭建方式也有参数调整与模型训练流程还提供学习曲线、平均奖励等指标的可视化分析方法。通过对这些模块的逐项拆解读者可以掌握强化学习智能体与交互环境的实现细节理解状态空间处理、奖励函数设计以及策略优化思路。目前已有754人学习尤其适合刚接触DRL的MATLAB用户作为入门到进阶的实操参考。借助该案例可完成从实验配置到结果评估的完整闭环提升在人工智能与机器学习领域的建模和调试能力。1. 为什么拖到MATLAB里做深度强化学习深度强化学习的项目最常见的内耗不在算法本身而在“环境怎么建模、训练数据落在哪、策略怎么交还给控制链路”。如果目标场景是机械臂、过程控制、能源调度这类物理对象MATLAB 的强化学习工具箱把环境定义、Agent 构建、训练监控和 Simulink 部署收敛在同一套流程里调试成本会比 Python 侧低不少。案例包里这份 DRL 教程正是按这个思路组织的先自定义环境再切 DQN、PPO、DDPG、TD3 四类算法最后落回控制任务的闭环验证。适合已经跑过强化学习入门例子、现在想把 DRL 用到实物或仿真控制项目里的工程师即使你对算法细节不熟也能先按文件把训练流程跑通再反推超参含义。2. MATLAB强化学习环境构建与奖励函数设计2.1 环境接口reset与step是DRL的契约强化学习工具箱并不关心你的被控对象是机械臂还是热力系统它只认一个环境对象而这个对象的两个方法就是整个训练循环的契约reset负责把环境恢复到初始状态并返回观测step接收动作、推进环境动力学、返回新观测、奖励和终止标志。定义一个自定义环境通常从rl.env.MATLABEnvironment继承然后实现这两个方法初始代码可以踩的坑非常集中classdef SimpleNavEnv rl.env.MATLABEnvironment % 自定义环境状态为二维坐标动作为离散的“左/停/右” properties State double [0; 0]; % 当前观测 Reward double 0; IsDone logical false; end methods function env SimpleNavEnv() % 定义观测维度和动作空间Agent 创建时会依据这两项做检查 obsInfo rlNumericSpec([2 1]); actInfo rlFiniteSetSpec([-1 0 1]); env envrl.env.MATLABEnvironment(obsInfo, actInfo); end function [obs, reward, isdone] reset(env) % 每回合从随机位置出发 env.State [0.1; 0.9]; obs env.State; reward 0; isdone false; end function [obs, reward, isdone] step(env, action) % 这里是控对象的动态方程实际项目替换成你的被控模型 env.State env.State [0; double(action)]; % 为一个靠近目标位置设计的密集奖励 dist abs(env.State(2) - 0.5); reward -dist; isdone dist 0.02; obs env.State; env.Reward reward; env.IsDone isdone; end end end这个类里最关键的两个点obsInfo和actInfo必须在构造函数里先定义因为后续所有 Agent 创建、网络输入层推断、训练记录都要读取这两个对象step里返回的三个值顺序不能写反工具箱默认第一个是观测、第二个是即时奖励、第三个是否终止。很多人一开始会漏掉IsDone状态更新导致训练永远走不完一集从训练曲线上看就是回合长度恒等于MaxStepsPerEpisode。2.2 奖励函数构造从稀疏到密集案例环境通常给你一个能跑的奖励公式但换到自己的任务后奖励设计往往是第一道坎。常见做法是先给稀疏奖励比如只判断“最终是否到达目标点”跑几百集看不到任何反馈更建议先用密度奖励让 Agent 尽早学到梯度方向再逐步稀疏化。上一个例子里reward -dist就是在引导智能体往目标靠绝对值小、量纲与状态一致不会让 Q 值爆炸。需要注意四个容易出错的地方第一奖励量纲和网络输出层不匹配比如 state 的范围是 0~1奖励却给到几百Critic 的输出会一直跟不上下游第二在isdone里同时放“成功”和“失败”条件结果失败样本也被当成终止状态值函数会被污染第三奖励函数里写了if分支但没覆盖所有动作导致某些分支返回空值第四reward出现NaN时训练会静默发散建议在step末尾加一句assert(~isnan(reward), reward is NaN)来快速定位。2.3 案例包里的环境与文件对应关系解压案例包后第一眼会看到matlab、media、metadata、mathml这几个目录。简单对一下位置就知道资源是怎么组织的路径作用实操时重点看matlab/存放 .m 源码和可能的 .mlx 实时脚本Agent 构建、训练入口文件都在这里media/图像、结果截图、过程可视化用来对照训练曲线是否复现成功metadata/案例说明、依赖项信息确认当前 MATLAB 版本需要的工具箱mathml/数学公式的标记描述论文写作或公式推导时参考不影响运行document.xml主流程文档的 XML 导出用于找回案例整体的操作顺序这里要提醒不要把metadata当成训练结果目录它不产生任何模型文件。训练过程中真正需要关注的是你指定的保存目录比如agents/里面按训练轮次生成的.mat文件才是 Agent 本体。3. DQN与PPO在案例包中的复现和训练超参调整3.1 DQN代理创建输入维度、网络末端与回放缓冲区DQN 适合离散动作空间像前面的[-1 0 1]三动作导航问题就非常典型。创建 Agent 时需要先构造一个接受状态输入、输出每个离散动作 Q 值的网络。以状态维度 4、动作数量 3 为例obsInfo rlNumericSpec([4 1]); actInfo rlFiniteSetSpec([-1 0 1]); qNetwork [ featureInputLayer(4, Normalization, none, Name, state) fullyConnectedLayer(24, Name, fc1) reluLayer(Name, relu1) fullyConnectedLayer(24, Name, fc2) reluLayer(Name, relu2) fullyConnectedLayer(numel(actInfo.Elements), Name, output)]; critic rlQValueRepresentation(qNetwork, obsInfo, actInfo, ... ObservationInputNames, state); dqnOpts rlDQNAgentOptions(... MiniBatchSize, 64, ... ExperienceBufferLength, 100000, ... TargetSmoothFactor, 1e-3, ... DiscountFactor, 0.99); agent rlDQNAgent(critic, dqnOpts);rlQValueRepresentation的作用是告诉工具箱“网络的输入是 state、输出是各动作的 Q 值”这一步别省略。TargetSmoothFactor控制目标网络的软更新速度取 1e-3 意味着每步训练只向当前网络靠近千分之一能有效减缓 DQN 常见的 Q 值震荡如果你发现训练前期损失值上下跳动优先调大这个值而不是盲目改学习率。ExperienceBufferLength是经验回放池的上限池子越大越能减少样本相关性但占用内存也线性增长一般 10 万到 50 万之间比较常见。3.2 PPO代理创建Actor-Critic与剪辑目标PPO 是 Policy Gradient 家族里稳定性最好的算法之一在新版工具箱里创建 PPO Agent 的常规写法是把 Actor 和 Critic 两个网络分别包装成表示对象% 以连续状态、离散3动作为例创建随机策略与价值网络 [actorRep, criticRep] buildPPONetworks(obsInfo, actInfo); % ↑ 这里引用了案例包内 buildPPONetworks.m 辅助函数 % 内部会对离散动作末端加 softmax连续动作末端则输出均值和方差 ppoOpts rlPPOAgentOptions(... ExperienceHorizon, 2048, ... ClipFactor, 0.2, ... EntropyLossWeight, 0.001, ... MiniBatchSize, 64, ... NumEpoch, 3); agent rlPPOAgent(actorRep, criticRep, ppoOpts);ExperienceHorizon可以理解为 PPO 收集一条更新轨迹所用的步数相当于把很多样本攒起来算一个优势估计数值太小策略容易抖动太大会让旧策略与当前策略偏差变大2048 是个保守起点。ClipFactor是裁剪系数0.2 是论文默认值控制策略更新的最大幅度如果训练曲线出现台阶式下跌试着把它降到 0.1代价是收敛变慢。EntropyLossWeight是熵正则权重调大可以增强探索但设到 0.01 以上经常能看到奖励不涨。3.3 训练选项参数表与训练过程观测训练选项集中在rlTrainingOptions它决定了“跑多久、什么时候停、什么时候存模型”。参数含义经验取值/调整方向MaxEpisodes最大回合数先设 500观察曲线再决定是否加MaxStepsPerEpisode单回合最大步数与环境最大时间相关不宜过大StopTrainingCriteria提前停止条件常用AverageRewardStopTrainingValue提前停止阈值取你期望的平均奖励SaveAgentCriteria保存 Agent 的条件改成EpisodeReward就能按回合奖赏保存SaveAgentDirectory模型保存目录用fullfile(pwd,agents)更稳训练入口代码通常长这样trainOpts rlTrainingOptions(... MaxEpisodes, 2000, ... MaxStepsPerEpisode, 300, ... StopTrainingCriteria, AverageReward, ... StopTrainingValue, 30, ... SaveAgentCriteria, EpisodeReward, ... SaveAgentValue, 25, ... SaveAgentDirectory, fullfile(pwd, agents), ... Plots, training-progress); trainStats train(agent, env, trainOpts);训练开始后弹出的training-progress窗口里绿色方块是每回合总奖励深色曲线是滑动平均。这个图不是给你看个热闹的如果滑动平均长期不增长先检查奖励里是否全是负值看EpisodeReward的最小值如果一直在 -300 附近打转说明 Agent 完全没有接收到有效梯度信号优先怀疑奖励函数而不是网络结构。4. 连续动作空间的DDPG与TD3实现要点4.1 从离散到连续的动作输出前面 DQN 和 PPO 的例子用的是rlFiniteSetSpec也就是几个离散档位。但机械臂关节力矩、风机桨距角、车辆油门这些场景动作本身是连续值。连续动作空间下不能再用“对每个动作算 Q 值”的思路DDPG 改为 Actor 网络直接输出连续动作Critic 网络则接收“状态 动作”来评估该动作的好坏。案例包里的连续控制任务一般会给你两个辅助函数buildActorNet和buildCriticNet。Actor 的最后一层通常是tanhLayer把输出压缩到 [-1,1]再用rlContinuousDeterministicActor包装成一个确定性策略表示。4.2 DDPG代理创建与探索噪声DDPG 在训练初期靠给动作叠加随机噪声来探索。创建代理时NoiseOptions里的Variance决定初始噪声幅度VarianceDecayRate控制噪声衰减速度。这两个值直接影响探索与利用的平衡值得单独拿出来看[actorRep, criticRep] buildDDPGNetworks(obsInfo, actInfo); % buildDDPGNetworks 内部会把 Actor 输出层限定为连续值 ddpgOpts rlDDPGAgentOptions(... MiniBatchSize, 64, ... ExperienceBufferLength, 1e6, ... TargetSmoothFactor, 1e-3, ... NoiseOptions, struct(... Variance, 0.2, ... VarianceDecayRate, 1e-5)); agent rlDDPGAgent(actorRep, criticRep, ddpgOpts);Variance设成 0.2 表示初始动作会在策略输出上叠加约 ±20% 的随机扰动这样 Agent 前期会四处乱试VarianceDecayRate设成 1e-5噪声会随训练步数缓慢消失后期逐渐收敛到确定性策略。如果在连续控制任务里看到训练前期奖励涨得飞快、后面又断崖下跌基本可以判定噪声衰减太快导致后期彻底丧失探索能力合理做法是调低VarianceDecayRate一个数量级。TargetSmoothFactor的作用和 DQN 里的目标网络一致连续控制里建议从 1e-3 起步不要直接按默认值跑。4.3 TD3的延迟更新与目标平滑正则TD3 是对 DDPG 的高方差问题的修正核心差异有三个双 Q 网络取最小值、Actor 延迟更新、目标策略加平滑噪声。在 MATLAB 里创建 TD3 Agent 的代码与 DDPG 结构非常接近[actorRep, criticRep] buildTD3Networks(obsInfo, actInfo); td3Opts rlTD3AgentOptions(... MiniBatchSize, 100, ... ExperienceBufferLength, 1e6, ... TargetPolicySmoothVariance, 0.2, ... PolicyUpdateFrequency, 2); agent rlTD3Agent(actorRep, criticRep, td3Opts);TargetPolicySmoothVariance是在目标动作上叠加的平滑噪声方差它让 Q 值对动作的小扰动不敏感从而抑制值函数过估计。PolicyUpdateFrequency表示 Actor 每隔多少步更新一次设为 2 意味着 Critic 更新两次才动一次 Actor这是 TD3“延迟更新”的直接体现。调参经验是如果 DDPG 的 Q 值震荡到训练曲线无法稳定换 TD3 通常会好一截但 TD3 对MiniBatchSize更敏感尽量不低于 64。4.4 连续控制任务训练的常见崩溃模式连续控制任务的失败模式比离散动作更难观察。第一种是 Actor 输出饱和动作一直被tanh压在 ±1 附近奖励也停在固定值这时要检查网络初始化与奖励量纲。第二种是 Critic 发散表现为训练后半段平均奖励骤降为极大的负数通常是TargetSmoothFactor太小或奖励中有异常大值。第三种是噪声方差归零太早Agent 陷入局部最优表现是训练曲线走平后无论怎么加训练时间都不再提升此时重新设置NoiseOptions再续训往往比重头训练更有效。5. 学习曲线分析、模型保存与断点续训5.1 训练记录的提取与复盘train返回的trainStats是一个结构体记录了每一回合的EpisodeReward、EpisodeSteps、AverageReward等字段。很多人关掉绘图窗口就没什么数据可看了其实可以手动取出来做进一步分析episodeRewards trainStats.EpisodeReward; avgWindow 50; smoothRewards movmean(episodeRewards, avgWindow); figure; plot(episodeRewards, Color, [0.8 0.8 0.8], LineWidth, 0.5); hold on; plot(smoothRewards, b-, LineWidth, 2); xlabel(Episode); ylabel(Reward); legend(Raw, Moving Average, Location, best);滑动平均窗口取 50 或者 100主要看单回合奖励的噪声水平。噪声大就加大窗口否则平滑线会掩盖真实的趋势。复盘时盯着smoothRewards的斜率变化如果连续 200 回合没有明显上升趋势不一定是算法不行先去看EpisodeSteps是否一直在上限附近徘徊如果是说明 Agent 没有学会提前终止无效轨迹这时往奖励函数里加“每步小惩罚”比增加训练回合更有效。5.2 模型保存、加载与断点续训长训练任务最怕跑到一半停电或参数崩坏。工具箱支持的模型保存有两种触发方式按训练条件自动保存以及手动保存当前 Agent。自动保存在第 3 章的rlTrainingOptions里已经配置过。手动保存用于你已经判断当前策略不错、想停下来调整奖励函数再接着练的场景% 训练结束后保存完整 Agent 对象 save(fullfile(pwd, agents, finalAgent.mat), trainedAgent); % 新会话中恢复 s load(fullfile(pwd, agents, finalAgent.mat)); trainedAgent s.trainedAgent;续训时要特别区分“接着训练”和“从头训练”。直接调用train(trainedAgent, env, newOpts)会沿用原来的网络权重和经验回放缓冲区适合在原有策略基础上微调如果你想清掉旧经验而保留网络结构需要重新创建 Agent。一个常见错误是保存时只存网络对象而不存 Agent导致续训时/mdlInfo.TrainingOptions等内部状态全部丢失训练精度对不上前面的曲线。因此保存对象时只存trainedAgent这个完整变量即可不要试图把actor、critic拆开存。5.3 诊断案例平均奖励在平台上不动怎么办最典型的场景是跑了 300 回合平均奖励稳定在 -150不上不下。按优先级检查三件事。第一奖励是否过稀疏把step里的奖励改为“当前距离到目标距离的差”也就是每一步因靠近而获得的正向差值第二探索噪声是否饱和或消失离散动作检查EpsilonGreedyExploration的衰减率连续动作检查NoiseOptions的VarianceDecayRate第三网络容量不足把两层 24 神经元扩成两层 64 神经元再跑 100 回合如果曲线有变化说明是表达能力问题。记得每改一次只动一个变量否则无法定位是谁起的作用。6. 从Agent到Simulink策略评估与部署验证6.1 在原始环境中做闭环sim评估训练和评估不要共用同一段代码路径。正式评估时关掉探索噪声用确定性策略连续跑多个回合看最终奖励分布。MATLAB 中可以用rlSimulationOptions控制评估的回合数和步数simOpts rlSimulationOptions(NumSimulations, 10, MaxSteps, 500); totalRewards zeros(simOpts.NumSimulations, 1); for i 1:simOpts.NumSimulations exp sim(env, agent, simOpts); totalRewards(i) sum(exp.Reward); end fprintf(Mean reward: %.2f, Std: %.2f\n, ... mean(totalRewards), std(totalRewards));评估时看的不只是平均奖励更要看标准差。如果 10 次评估中有 1 次严重偏离说明策略还存在某些未覆盖的状态区域。标准差超过平均值的 20% 时回去补充这些失败案例到经验池再续训通常是最快的修法。6.2 Simulink中的智能体模块与代码生成技巧部署到 Simulink 时常见的做法是先用rlSimulinkEnv把你原来的 MATLAB 环境替换为 Simulink 模型从模型里替换出一个 Agent 模块并确保该模块的观测输入和动作输出维度与训练时一致。Simulink 环境下做验证最大的价值是能无缝对接已有的被控对象模型不需要把微分方程从 Simulink 再翻译回 MATLAB 的step函数。代码生成前有两件事值得做在模型配置里把求解器固定为定步长否则生成的代码在不同机器上的运行行为会有差异同时把训练时加的噪声模块从路径中删除否则生成代码里会残留随机数生成逻辑导致部署版本和训练版本策略不一致。最后用codegen生成 C 代码时要避免在评估函数里引入plot、figure等可视化指令MATLAB Coder 要求目标函数全部为可编译代码把训练诊断用的可视化单独放到一个脚本里与部署入口分离这一步做完策略从训练环境到实际控制链路的迁移才算真正闭合。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门