资讯动态

MATLAB深度强化学习案例详解:CreateAgent与训练全流程避坑指南

发布时间:2026/10/29 23:21:30 来源:尧图企业网站定制
简介这是一份面向深度强化学习入门者与MATLAB建模用户的案例程序包帮助读者从零搭建DRL实验理解智能体与环境交互、策略学习及奖励设计。包内共21个文件以MATLAB脚本和工程文件为核心包含7张PNG示意图、5个MathML数学公式文件、7个XML配置/元数据文件及2个关系定义文件压缩包整体仅1.18MB结构轻量便于快速下载与运行。已有754人学习下载适合希望动手实践DQN、PPO、DDPG等算法的读者。通过该案例可掌握环境构建、奖励函数构造、训练曲线分析与参数调整方法同时熟悉MATLAB中强化学习工具箱及调试排错流程为开展更复杂的DRL研究打下基础。1. CreateAgent 与深度强化学习 MATLAB 案例程序先看懂这个压缩包再谈训练很多人在课程设计或论文复现阶段会下载到一个名字很长的压缩包“CreateAgent_深度强化学习_深度强化_深度强化学习MATLAB案例程序_强化学习”。解压后一堆 .m 文件最显眼的是 createAgent.m。这个 CreateAgent 并不是底层算法名而是案例包习惯上用来封装“构造智能体”这步的入口脚本输入环境信息、观测信息、动作信息和超参数返回一个可训练的 agent。深度强化学习的五要素——环境、观测、动作、策略、训练信号在 MATLAB 里都绕着这个 agent 对象转。这篇笔记按这类案例包的组织方式把环境定义、obsInfo/actInfo 类型匹配、createAgent 内部结构和训练参数逐项拆开再列出调 RL 时的真实坑。适合正在做课程设计、论文复现或控制仿真的人。2. 为什么深度强化学习案例选 MATLAB 而不是 Python工具箱选型与边界2.1 强化学习算法在 MATLAB 里的表达方式Agent、环境、训练选项三件套如果你完整看过 David Silver 的强化学习课应该对 state、action、reward、policy、value 这五件事的闭环有印象。MATLAB 的 Reinforcement Learning Toolbox 把这五件事映射成了三个对象环境对象rlMDPEnv、rlFunctionEnv、rlSimulinkEnv、智能体对象rlDQNAgent、rlPPOAgent、rlDDPGAgent、rlTD3Agent、训练选项对象 rlTrainingOptions。观测规格 obsInfo 和动作规格 actInfo 不是独立存在的它们挂在环境对象上用 getObservationInfo 和 getActionInfo 取出来再交给智能体构造函数。案例包里的 createAgent.m本质就是把“从 obsInfo、actInfo 到 agent”的构造过程集中管理。我拿到这类文件后的第一件事不是读训练脚本而是先看 createAgent 开头怎么取规格对象rlNumericSpec 有 Dimension、LowerLimit、UpperLimit用于连续观测和连续动作rlFiniteSetSpec 有 Elements用于离散动作集合。这两个对象的取值直接决定了后面网络输入层写几个神经元、输出层写几个神经元。很多翻车现场不是算法写错而是 obsInfo.Dimension 是 [4 1]网络里却写了一个 2 维的 featureInputLayer。深度强化学习的“深度”体现在价值函数或策略函数是神经网络而不是查表。在这条链路里你不需要自己写前向反向和梯度更新工具箱会处理经验回放、目标网络软更新、探索策略。但不同算法的网络结构差异很大DQN 的 critic 是“状态到各离散动作 Q 值”的单输入网络DDPG/TD3 的 critic 是“状态动作”双输入PPO 要同时维护 actor 和 critic。createAgent 里最容易出错的从来不是算法公式而是网络输入层和规格对象不匹配。2.2 哪些场景值得用 MATLAB哪些场景要回 Python先把结论放在前面课程设计、毕业设计、控制系统仿真验证、论文里需要画奖励曲线时MATLAB 这套工具箱是省时间的做超参搜索、新算法原型、离线强化学习这类研究向内容Python 生态更合适。下面这张表是我自己选型的参照。关注点MATLAB 强化学习工具箱PythonPyTorch Gym/Stable-Baselines3环境搭建内置 rlMDPEnv / rlFunctionEnvSimulink 模型可直接当环境需要自己写 wrapper或用 Gym 现成环境算法覆盖DQN、PPO、DDPG、TD3、SAC 等基础算法齐全覆盖广社区更新快离线强化学习也有现成库超参搜索手动循环或并行训练日志管理弱有 wandb、Optuna 等成熟配合可视化训练曲线、Simulink 动画、agent 行为回放方便需要另外装库部署MATLAB Runtime 打包控制系统联动方便ONNX 导出或服务化部署灵活我一般建议这么判断如果你的环境本身就是一个 Simulink 模型或者你最终要在 MATLAB/Simulink 里做闭环仿真验证直接用工具箱如果你要跑几百组实验、比较不同随机种子下的方差Python 的可重复性和实验管理更好。这也是为什么很多深度强化学习 MATLAB 案例程序只适合做“可行性验证”而不是“大规模研究”的原因。2.3 工具箱没装对时案例包一步都跑不动下载回来的案例包经常在第一步就失败报错“未定义函数或变量 rlDQNAgent”。这时先别怀疑函数名拼写运行ver(reinforcement)看输出。如果显示没有 Reinforcement Learning Toolbox需要用 MATLAB 的 Add-On Explorer 安装对应工具包。装了之后还报错再看版本差异R2021 前后的 rlDQNAgent 构造函数签名不一样新版本统一成传 critic、obsInfo、actInfo、opts 的形式旧案例包的代码大概率是老的调用方式。另外较新版本比如 2026b下载安装完成后如果启动时报 MathWorks Licensing Error 8多半是 license.lic 里的 HostID 和当前机器网卡的 HostID 不一致。解决方法是重新生成与当前 HostID 匹配的 license 文件再放到 MATLAB 的 license 目录下。这个问题和强化学习算法无关但工具箱装不上后面所有案例都跑不了所以我把“确认工具箱可用”排在任何调参之前。3. 从环境定义到 createAgent 跑通第一个深度强化学习案例可复现的 DQN 代码3.1 先定观测和动作rlNumericSpec 与 rlFiniteSetSpec 的类型匹配我用一个极简单的一维环境做演示状态是一个整数取值范围在 -2 到 2 之间动作是 -1、0、1目标是让状态回到 0。这个环境小到可以口算最优策略但它能把环境、createAgent、训练、保存的完整链路跑通。先定义观测和动作规格。% 观测一个标量状态范围 [-2, 2] obsInfo rlNumericSpec([1 1], LowerLimit, -2, UpperLimit, 2); % 动作离散动作集 {-1, 0, 1} actInfo rlFiniteSetSpec([-1 0 1]);obsInfo.Dimension 是 [1 1]表示一个标量观测。如果换成 4 维连续状态这里就是 rlNumericSpec([4 1])。actInfo.Elements 是 [-1 0 1]表示离散动作空间后面 Q 网络输出层的神经元数量就是 numel(actInfo.Elements)这里等于 3。连续动作空间则不能用 rlFiniteSetSpec要用 rlNumericSpec 并设置合理的 LowerLimit 和 UpperLimit网络结构也会变成 actor 输出动作均值这是 DQN 和 DDPG 的关键区别。3.2 创建环境用 rlFunctionEnv 写一个最小可跑的交互环境有了规格对象下一步用 rlFunctionEnv 把 reset 函数和 step 函数包装成强化学习环境。reset 函数返回初始观测step 函数接收当前观测和动作返回下一个观测、奖励、是否结束、日志数据。% reset初始状态随机取 -2 到 2 之间的整数 resetFun (in) deal(randi([-2, 2]), in); % step状态加上动作作为新状态到达 0 给 1否则每步 -0.1 stepFun (obs, action, in) deal( ... obs action, ... -0.1 (abs(obs action) 0.5), ... abs(obs action) 0.5, ... in); env rlFunctionEnv(obsInfo, actInfo, resetFun, stepFun);这里 stepFun 的返回值顺序必须固定Observation、Reward、IsDone、LoggedSignals。奖励写成了 -0.1 加上一个逻辑值逻辑值在 MATLAB 里参与运算时 true 等于 1所以到达 0 时奖励是 0.9没到达时是 -0.1。终止条件用 abs(obs action) 0.5 而不是 0是为了兼容未来把状态改成连续值的情况。这个环境足够简单但能真实跑出“前期探索、后期收敛”的训练曲线。提示rlFunctionEnv 的 reset 和 step 函数签名在 R2021 之后基本稳定但旧版对 LoggedSignals 的传递要求略有差异。如果案例包代码报错优先用help rlFunctionEnv看当前版本签名。3.3 createAgent 函数内部做了什么DQN 智能体的构建参数现在写 createAgent 的核心部分。这个函数的任务是把 obsInfo、actInfo 和超参数转换成 rlDQNAgent 对象。我把网络层数、神经元数、是否用 Double DQN 都做成可配置项方便后面做对比实验。function agent createAgent(obsInfo, actInfo, opts) arguments obsInfo actInfo opts.UseDoubleDQN (1,1) logical true opts.Neurons (1,1) double 64 end % Q 网络输入观测输出每个离散动作的 Q 值 net [ featureInputLayer(prod(obsInfo.Dimension), Normalization, none, Name, obs) fullyConnectedLayer(opts.Neurons, Name, fc1) reluLayer(Name, relu1) fullyConnectedLayer(opts.Neurons, Name, fc2) reluLayer(Name, relu2) fullyConnectedLayer(numel(actInfo.Elements), Name, qout) ]; % 包装成 Q 函数表示 critic rlQValueFunction(net, obsInfo, actInfo, ObservationInputNames, obs); % DQN 专用选项 dqnOpts rlDQNAgentOptions( ... UseDoubleDQN, opts.UseDoubleDQN, ... TargetSmoothFactor, 1e-3, ... ExperienceBufferLength, 1e5); % epsilon 贪心探索策略 dqnOpts.EpsilonGreedyExploration.Epsilon 1.0; dqnOpts.EpsilonGreedyExploration.EpsilonDecay 0.005; dqnOpts.EpsilonGreedyExploration.EpsilonMin 0.01; agent rlDQNAgent(critic, obsInfo, actInfo, dqnOpts); end网络第一层用 prod(obsInfo.Dimension) 而不是直接写 1这样 obsInfo 维度改成 [4 1] 时不用改代码。Normalization 设为 none是因为这个例子里观测本来就很小后面做复杂环境时我习惯先手动把观测缩放到 [-1, 1]而不是依赖层里内置的归一化。rlQValueFunction 要求离散动作下网络输出每个动作的 Q 值连续动作下必须额外传入动作输入这是 DQN 迁移到 DDPG 时最容易踩的坑。Epsilon 三件套是训练初期的关键Epsilon 初始 1.0 表示完全随机探索EpsilonDecay 0.005 表示每个 episode 衰减EpsilonMin 0.01 保证后期还有 1% 的随机探索。这个环境状态空间小0.005 够用如果换成 CartPole 这类更复杂的环境衰减太快会导致还没探索完就进入贪心阶段训练直接停滞。3.4 训练与保存rlTrainingOptions 的 5 个必调参数训练前配置 rlTrainingOptions。我每次都会检查 5 个参数最大回合数、单回合最大步数、停止条件、自动保存条件、是否启用并行。其余参数保持默认跑出问题再针对性调。trainOpts rlTrainingOptions(); trainOpts.MaxEpisodes 800; trainOpts.MaxStepsPerEpisode 20; trainOpts.StopTrainingCriteria AverageReward; trainOpts.StopTrainingValue 0.8; trainOpts.SaveAgentDirectory agents; trainOpts.UseParallel false; stats rlTrainAgent(env, agent, trainOpts); save(agent.mat, agent); plot(stats.EpisodeReward);MaxEpisodes 是训练上限真正让训练提前停下来的通常是 StopTrainingCriteria 和 StopTrainingValue 这一对。这里设 AverageReward 达到 0.8 停止因为这个环境下最优平均奖励约 0.85。SaveAgentDirectory 指定自动保存目录配合默认的 SaveAgentCriteria 在奖励达到一定阈值时存下智能体相当于训练过程的“后悔药”。UseParallel 我默认关掉小案例下并行启动开销反而大而且并行训练会引入额外的不确定性后面排查问题更难。训练完不要直接关 MATLAB先用 sim 验证一次行为simOpts rlSimulationOptions(MaxSteps, 20); sim(env, agent, simOpts);sim 返回的是回合数据包含每一步的观测、动作、奖励。看到奖励接近 0.9 再保存才算真正跑通。save 保存的是 agent 变量下次使用时要先重新创建 env再 load(agent.mat)否则 agent 里的 obsInfo 和 actInfo 与现有环境对不上sim 会报类型不匹配。4. 深度强化学习 MATLAB 训练排查4 个踩过的坑与定位方法4.1 未定义函数或变量 rlDQNAgent工具箱没装对现象运行 createAgent 或训练脚本直接报“未定义函数或变量 rlDQNAgent”。原因最常见是 Reinforcement Learning Toolbox 没安装或 license 不完整。其次是版本问题老案例包用的是旧版构造函数新版 MATLAB 里函数签名已经变化。解决先跑ver(reinforcement)确认输出里有 Reinforcement Learning Toolbox 及版本号。如果没有用 Add-On Explorer 安装而不是手动下载文件夹放进来。如果已安装仍报错用help rlDQNAgent看当前版本支持的调用方式把 createAgent 里的构造方式改成新版签名。装完新版 MATLAB 后报 MathWorks Licensing Error 8 的情况先检查 license.lic 里的 HostID 是否和当前网卡一致不一致时重新生成对应 license。4.2 奖励曲线长期趴地板奖励设计、观测归一化与探索衰减现象训练了几百个 episodeEpisodeReward 一直贴着初始值波动完全看不到上升趋势。原因最常见是奖励信号太稀疏或量级不对其次是观测尺度差异过大网络输入层直接吃原始值梯度被个别大数值带偏还有 epsilon 衰减太快探索阶段还没覆盖有效动作策略就进入贪心阶段。解决先看奖励的绝对值量级。如果单步奖励在正负几百网络输出层和 loss 都会被放大先用环境函数里手动缩放把奖励压到 ±5 以内。再看观测可以直接在 rlFunctionEnv 的 step 和 reset 里把状态缩放到 [-1, 1] 区间而不是依赖网络输入层。最后把 EpsilonDecay 调小从 0.005 改成 0.001 甚至 0.0005给探索留足时间。排查时用平均奖励曲线判断趋势不要盯着单条 EpisodeReward太抖。4.3 自建 createAgent.m 与工具箱函数冲突函数重名和路径优先级现象把案例包里的 createAgent.m 放进当前文件夹运行别的脚本时突然报错或者 MATLAB 给出“同名函数冲突”的警告行为变得不可预测。原因MATLAB 按路径顺序解析函数名。虽然 createAgent 不是工具箱官方函数但案例包里的自定义脚本和工具箱的某些内部文件同名时当前文件夹的优先级会把工具箱里的同名文件覆盖掉导致工具箱内部调用出错。解决先用which -all createAgent看系统里到底有哪些同名文件。遇到冲突就把自定义脚本改成 createMyAgent.m并把调用处同步改掉不要和工具箱文件放在同一路径。这个坑在下载的案例包里尤其常见因为很多人习惯把脚本直接丢进 MATLAB 默认路径下而不是单独建项目文件夹用 addpath 管理。4.4 训练结果不可复现随机种子、并行与版本记录现象同样的代码跑两次奖励曲线差异明显论文里没法画对比图。原因深度强化学习本身就有随机性网络初始化、经验回放采样、epsilon 探索都是随机的。MATLAB 的并行训练还会引入线程层面的不确定不同版本的工具箱对同一算法的实现细节也有差异。解决训练脚本最开头加rng(0)固定全局随机种子训练选项里把 UseParallel 设为 false减少不确定来源每个训练脚本注释里记录 MATLAB 版本、工具箱版本和随机种子ver(reinforcement)的输出直接贴进实验记录。复现实验时用以下代码把平均奖励导出成 CSV方便后续画多条曲线writematrix(stats.AverageReward, reward_curve.csv);这个习惯一开始不养成后面做算法对比时根本分不清差异来自算法还是随机种子。5. 从 DQN 到 PPO把 createAgent 扩展成新算法的验证技巧5.1 迁移到 rlPPOAgentActor-Critic 需要完全不同的网络和超参DQN 只能处理离散动作而且对复杂的连续控制问题收敛偏慢。换到 PPO 时createAgent 里的网络结构要从单个 Q 网络变成 actor 和 critic 两个网络。actor 负责输出动作分布critic 负责估计状态价值。R2021 之后的工具箱里 PPO 智能体构造入口是 rlPPOAgent但具体传参要看当前版本help rlPPOAgent的输出。和 DQN 最大的不同是actor 网络输出层不是 Q 值而是要接概率分布参数离散动作下通常由工具箱包装 softmaxcritic 网络输出层只有 1 个神经元估的是状态价值rlPPOAgentOptions 里要关注 ClipFactor、EntropyLossWeight、NumEpoch 这几个参数和 DQN 的 EpsilonGreedyExploration 完全不是一回事不能直接把 dqnOpts 套过去。我迁移时的做法是先跑通 DQN 版本再复制 createAgent 函数改成 PPO 版本保持环境不变。这样如果训练异常能确认问题出在算法而不是环境代码。5.2 用 Origin 画多次训练的置信区间曲线别被单次曲线骗了单次训练的奖励曲线噪声很大论文里直接贴一条曲线很容易被审稿人质疑。我一般最少跑 5 次独立实验每次重新设置随机种子并重建 agent然后把每次的平均奖励存成一行最后在 MATLAB 里算好均值和标准差再导出给 OriginN 5; R zeros(N, length(stats.AverageReward)); for i 1:N rng(i); agent createAgent(obsInfo, actInfo); stats rlTrainAgent(env, agent, trainOpts); R(i, :) stats.AverageReward; end mu mean(R, 1); sd std(R, 0, 1); writematrix([mu(:), sd(:)], reward_ci.csv);在 Origin 里导入这个 CSV用 x 轴为 episode 序号、y 轴为均值、上下包络为均值加减标准差的方式画阴影曲线。画置信区间用标准差而不是标准误因为多次独立训练之间的差异用 std 描述更诚实。我最早做强化学习实验时也以为跑通一个例子就等于学会了后来发现真正值钱的是“能不能稳定复现”。现在拿到任何案例包第一件事永远是检查 obsInfo、actInfo 和网络维度是否匹配再去跑 20 个 episode 看奖励趋势而不是直接训满 500 个。这个习惯帮你省下的时间远比调参技巧多。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑