ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MATLAB深度强化学习实战:CreateAgent系列函数与训练调参指南

MATLAB深度强化学习实战:CreateAgent系列函数与训练调参指南 简介一套以MATLAB为载体的深度强化学习案例程序面向希望掌握DQN、PPO、DDPG、TD3等主流算法的算法工程师、科研人员及高年级本科生解决从理论到仿真落地的衔接难题。压缩包共21个文件大小仅1.18MB包含7个png图示、7个xml元数据/关系文件、5个mml数学公式及2个rels关联配置目录区分matlab代码、media图像、metadata信息等模块便于直接查看算法流程与公式定义同时也方便初学者快速定位关键脚本与说明文件。目前已有754人学习下载。内容围绕环境构建、算法训练、算法分析三大环节展开既能了解Atari游戏与连续控制任务的MATLAB实现也能借助DQN/PPO/DDPG等算法亲手调整参数并观察学习曲线配套图像与公式文件可辅助理解状态空间、奖励函数和策略更新机制非常适合快速搭建DRL实验、完成调参对比与结果复现。1. 在 MATLAB 里用 CreateAgent 之前先搞清楚它到底返回了什么在 MATLAB 里敲下 CreateAgent 这一系列入口函数rlDQNAgent、rlDDPGAgent、rlPPOAgent之前你大概率已经从网上下载过不少深度强化学习案例程序。真正打开工具箱跑第一个案例时才会发现环境定义、观测空间、动作空间、奖励函数、网络结构这些环节一个比一个像黑匣子报错往往发生在你以为已经写对的那一行。CreateAgent 不是一个孤立命令它是 MATLAB 深度强化学习对象体系的门口只有把“智能体对象”理解成网络、优化器与探索策略的集合后面的案例程序才能照着业务场景去改。这篇笔记从入口开始用 CartPole 跑通最小命令再做自定义环境与算法选型最后给出训练不收敛时的排查手法。适合打算用 MATLAB 出仿真结果的研究生也适合需要把强化学习接进 Simulink 做机器人或控制验证的工程师。2. 用 CreateAgent 跑通第一个深度强化学习案例CartPole 最小命令到 DQN 网络2.1 CreateAgent 是“创建智能体”这一类入口函数的统称MATLAB 强化学习工具箱里其实没有一个叫 createAgent 的单一函数。你在案例程序里看到的 createAgent通常指的是以 rlQAgent、rlDQNAgent、rlDDPGAgent、rlTD3Agent、rlPPOAgent、rlSACAgent、rlA2CAgent 为代表的一整组“创建智能体”入口函数。这个命名习惯和 Python 里model DQN(...)很像不同算法有各自的构造函数但都返回一个智能体对象。这个对象不是单纯一个神经网络。它内部至少绑定三样东西策略网络或 Q 网络、优化器配置、探索策略。比如 rlDQNAgent 返回的对象自带 epsilon-greedy 探索rlDDPGAgent 里则包含动作噪声。理解了这一点很多报错就能说通你改了网络结构却没有同步更新 obsInfo 时工具箱往往在你调用 train 之后才校验网络输入维度报错信息隔了好几个函数层新手很容易当场懵掉。我一般建议按“环境 → obsInfo / actInfo → 网络 → CreateAgent 入口 → rlTrainingOptions → train”的顺序写脚本。这个顺序几乎适用所有 MATLAB 深度强化学习案例程序后面所有代码都沿这条线走。2.2 从环境取 obsInfo 和 actInfo一切 CreateAgent 的前置条件工具箱自带几个预定义环境CartPole 是其中最简单的一个也是各种深度强化学习算法列表对比里出场率最高的基准。Python 里的 Gymnasium CartPole 和 MATLAB 这里的 CartPole-Discrete 结构几乎一样观测是小车位置、速度、杆的角度、角速度动作是向左或向右施加推力目标是不让杆倒下。下面这段代码是跑通 CartPole 的最小命令也是我见过所有 MATLAB 深度强化学习案例程序里最短的闭环% 第1步加载预定义环境CartPole-Discrete 是离散动作版本 env rlPredefinedEnv(CartPole-Discrete); % 第2步从环境对象里读取观测空间与动作空间 obsInfo getObservationInfo(env); actInfo getActionInfo(env); % 第3步用查表方式创建 Q 表再包一层 Q 值函数 qTable rlTable(obsInfo, actInfo); critic rlQValueFunction(qTable, obsInfo, actInfo); % 第4步创建智能体这就是 CreateAgent 系列入口 agent rlQAgent(critic); % 第5步配置训练选项并开始训练 trainOpts rlTrainingOptions(... MaxEpisodes, 500, ... MaxStepsPerEpisode, 500, ... ScoreAveragingWindowLength, 50); stats train(agent, env, trainOpts);第 2 步的getObservationInfo和getActionInfo是后面所有 CreateAgent 系列函数的固定前置工作。obsInfo 里保存的是观测维度、范围、名称actInfo 里保存的是动作取值范围离散动作会有枚举列表。后续构造网络时输入层维度必须和obsInfo.Dimension对得上输出层维度必须和actInfo.Dimension对得上否则 train 一启动就会报错。第 3 步里的rlQAgent对应的是经典查表 Q-learning不是深度网络。它适合用来验证环境接口通不通也适合第一次接触强化学习时理解“状态-动作-奖励”的循环。第 4 步创建的 agent 对象内部已经绑定了策略和更新规则不需要手写贝尔曼方程更新。第 5 步的ScoreAveragingWindowLength是用来平滑 episode 奖励的窗口长度判断收敛别只看最后一条 episode要看最近 50 条的平均值。MaxEpisodes设 500 对 CartPole 来说偏宽裕一般 200 个 episode 内平均奖励就能顶到 500 的上限。MaxStepsPerEpisode设 500 是 CartPole 的终止步数上限环境在杆倒下之前不会主动结束这个上限决定了一个 episode 最多能撑多久。2.3 换成语义相近的深度网络rlDQNAgent 的输入输出规范从rlQAgent换成rlDQNAgent只多了一步把查表函数换成深度网络。这一步是真正进入深度强化学习的分水岭。Q 表适合离散状态CartPole 的 4 维连续观测塞不进查表结构换成神经网络后就能处理任意维度的连续输入。% 用 prod 取维度乘积避免手动数数出错 obsDim prod(obsInfo.Dimension); actDim prod(actInfo.Dimension); % 构建 Q 网络输入 4 维观测输出 2 个离散动作的 Q 值 criticNet [ featureInputLayer(obsDim, Normalization, none, Name, obs) fullyConnectedLayer(64, Name, fc1) reluLayer(Name, relu1) fullyConnectedLayer(32, Name, fc2) reluLayer(Name, relu2) fullyConnectedLayer(actDim, Name, out)]; critic rlQValueFunction(criticNet, obsInfo, actInfo); % epsilon-greedy初始探索率 0.9最小 0.051000 步衰减完成 agent rlDQNAgent(critic, ... UseEpsilonGreedyExploration, true, ... EpsilonGreedyExploration, ... rl.option.EpsilonGreedyExploration(0.9, 0.05, 1000));featureInputLayer的Normalization参数设成 none这是强化学习里常见的做法。监督学习通常做批量归一化但强化学习的数据分布随策略变化而漂移归一化参数很难稳定不如把 raw 观测直接交给网络自己学省掉很多和观测范围相关的坑。网络结构用 64→32 的两层全连接对 CartPole 已经够用。不要盲目堆神经元深度强化学习的网络容量不是越大越好容量过大容易发生过估计训练曲线会在大约 200 个 episode 后出现先涨后崩的情况。激活函数全部用 relu输出层不加激活因为这里输出的是 Q 值而不是概率。EpsilonGreedyExploration(0.9, 0.05, 1000)的三个参数分别是初始探索率、最小探索率、衰减步数。初始探索率 0.9 意味着开头 90% 的时间在随机动作帮助环境被充分探索1000 步不是 episode 数是动作步数跑几轮 episode 就衰减完了。如果你的环境没有 CartPole 这么好探索把这个数调到 5000 甚至 10000让智能体多随机翻滚一阵再开始利用。3. 深度强化学习算法列表对比按动作空间与场景选 DDPG、PPO 还是 SAC3.1 选型第一刀动作空间是离散还是连续在 MATLAB 里选深度强化学习算法不要按名气选第一刀永远先看动作空间。离散动作比如交通信号灯控制里相位切换、游戏里的按键组合首选 DQN 家族连续动作比如机械臂关节力矩、移动机器人室内自主导航里的速度指令就要走 DDPG、TD3、SAC 或 PPO。常见反面教材是拿着 DQN 去跑连续控制环境然后在 rlQValueFunction 输出层放一个很大的全连接层试图用离散化网格覆盖连续动作。动作维度一旦超过 2离散化的组合数就会爆炸训练根本收敛不了。反过来拿 DDPG 跑离散动作也会遇到问题Actor 输出的是连续值需要再手动 round 成离散整数梯度在 round 这一步断掉训练效果大打折扣。我一般把动作空间判断放在项目最前面甚至先于数据预处理。机械臂这种关节多的对象动作空间天然连续直接上 DDPG 或 SAC交通信号灯这种逻辑决策为主的对象相位本身是枚举值DQN 或 PPO 更顺手移动机器人导航如果同时涉及连续速度和离散避障切换常见做法是拆成两层底层连续速度用 DDPG顶层行为切换用规则或独立策略。3.2 深度强化学习算法列表对比一张表看懂六种常见算法网上各种深度强化学习算法列表对比很多工程选型真正有用的信息是动作空间、是否 off-policy、是否自带探索机制。整理成一张表放在案头比反复翻论文高效得多算法动作空间核心思想MATLAB 入口函数典型场景DQN离散深度网络拟合 Q 值 经验回放rlDQNAgentCartPole、离散决策DDPG连续Actor-Critic 经验回放rlDDPGAgent机械臂、连续控制TD3连续DDPG 双 Q 网络 目标策略平滑rlTD3AgentDDPG 的稳定替代PPO离散/连续裁剪目标函数实现简单rlPPOAgent复杂策略、多智能体协调SAC连续最大熵 随机策略rlSACAgent高维连续控制A2C离散/连续同步多路采样 AdvantagerlA2CAgent快速原型验证DQN 的改良版本 Double DQN、Dueling DQN 在 MATLAB 工具箱里没有现成开关需要自己改网络结构或参考官方案例。离线强化学习比如 IQL 也没有现成入口需要自己维护经验回放数据集再额外实现训练循环。这些工作放到 Python 生态里做更省力MATLAB 的强项是 Simulink 联合仿真和后续代码生成部署两条技术路线各管一段。拿 PSO 这类启发式算法和深度强化学习做对比实验时收敛曲线横轴要统一要么两边都按评估次数算要么两边都按训练步数算。常见翻车现场是 PSO 按函数评估次数画强化学习按 episode 画两条曲线横轴物理意义根本不一致放在一张图里没有可比性。3.3 网络结构怎么给全连接、卷积与动作输出层的边界确定算法之后网络结构是下一个容易踩坑的地方。低维向量观测比如位置、速度、角度全连接网络足够图像观测比如车端摄像头画面必须用卷积层提取特征全连接层直接拉平像素在强化学习里几乎学不出来。连续动作的 Actor 网络输出层常用 tanh 激活把输出限制在 [-1, 1]再由工具箱内部映射到动作空间的实际范围。下面这段 DDPG Actor 的写法是常见做法值得直接抄% 假设 obsInfo 是 [4 1] 的连续观测actInfo 是 [1 1] 的连续动作 actorNet [ featureInputLayer(obsInfo.Dimension, Normalization, none, Name, state) fullyConnectedLayer(128, Name, fc1) reluLayer(Name, relu1) fullyConnectedLayer(64, Name, fc2) reluLayer(Name, relu2) fullyConnectedLayer(1, Name, action) tanhLayer(Name, tanh)]; actor rlContinuousDeterministicActor(actorNet, obsInfo, actInfo);输出层接tanhLayer之后rlContinuousDeterministicActor会在内部把 [-1, 1] 映射到actInfo.LowerLimit和actInfo.UpperLimit定义的范围不需要自己写乘法缩放。这个映射关系很多新手不知道以为 tanh 输出直接就是动作值结果动作范围永远是 [-1, 1]和物理系统的真实量程对不上。Critic 网络的输入要同时接收观测和动作MATLAB 里用rlQValueFunction接收两个输入分支观测分支和动作分支各自过几层全连接后在中间拼接。如果动作维度很高别让动作分支单独太深否则 Critic 对动作的梯度会被深层网络的非线性抹掉DDPG 收敛会变得非常吃力。4. 把自定义环境接进 CreateAgentrlFunctionEnv 写深度强化学习案例程序的完整套路4.1 为什么案例程序 80% 的时间花在环境定义上工具箱预定义环境只有 CartPole、Pendulum、MountainCar 这类教学用环境工程案例几乎全是自定义环境。移动机器人室内自主导航要写激光雷达或里程计观测双向储能控制仿真模型要写电池和变换器动力学机械臂要写关节限位和碰撞检测。环境定义是把物理模型转换成强化学习接口的过程也是案例程序里最容易出隐藏 bug 的部分。MATLAB 里自定义环境有三种方式rlFunctionEnv适合动力学简单、先验证奖励函数设计思路的场景自定义类继承rl.env.MATLABEnvironment适合需要事件属性、可视化、多模式重置的场景Simulink 环境适合已有精确物理模型、想省掉手写动力学方程的团队。我一般先用rlFunctionEnv把策略跑通再迁到 Simulink 里做高精度验证两条腿走路。4.2 rlFunctionEnv 的最小案例写一个位置到达目标的环境下面用一个单自由度位置控制问题演示rlFunctionEnv的完整套路。被控对象是一个带速度阻尼的积分器观测是位置和速度输出是归一化到 [-1, 1] 的力目标是把位置驱动到 2 米处。这段环境的代码量足够小但覆盖了 reset、step、奖励、终止条件四个核心部分。% 定义观测与动作空间 obsInfo rlNumericSpec([2 1], LowerLimit, -inf, UpperLimit, inf); actInfo rlNumericSpec([1 1], LowerLimit, -1, UpperLimit, 1); obsInfo.Name position and velocity; actInfo.Name force; % 注册 reset 和 step 函数句柄创建环境 resetFun () resetLocal(); stepFun (action, loggedSignals) stepLocal(action, loggedSignals); env rlFunctionEnv(obsInfo, actInfo, stepFun, resetFun); % 重置环境位置和速度归零 function [initialObs, loggedSignals] resetLocal() loggedSignals.p 0; loggedSignals.v 0; loggedSignals.t 0; initialObs [loggedSignals.p; loggedSignals.v]; end % 环境动力学简单积分模型带速度阻尼 function [obs, reward, isDone, loggedSignals] stepLocal(action, loggedSignals) p loggedSignals.p; v loggedSignals.v; dt 0.1; % 动力学方程速度更新位置累加阻尼系数 0.1 v v action * dt - 0.1 * v; p p v * dt; loggedSignals.p p; loggedSignals.v v; loggedSignals.t loggedSignals.t 1; % 奖励当前位置与目标 2 米的负距离稠密奖励 reward -abs(p - 2); % 终止条件到达目标附近或超过 200 步 isDone abs(p - 2) 0.05 || loggedSignals.t 200; obs [p; v]; end这段代码必须保存成函数文件local function 放在文件末尾不能直接当脚本运行。rlFunctionEnv要求 reset 函数返回初始观测和 loggedSignals 结构体step 函数接收 action 和上一时刻的 loggedSignals返回当前观测、奖励、终止标志和更新后的 loggedSignals。loggedSignals 就是一个跨 step 传递状态的结构体相当于环境内部的内存里面想放几个字段都行。奖励函数用-abs(p - 2)这是稀疏奖励转稠密奖励的最直接做法。如果写成“到达目标给 1否则给 0”智能体在随机探索阶段几乎拿不到正反馈训练会很久都不动。用距离惩罚后每走一步都有反馈收敛速度快一个量级。工程上遇到奖励一直为 0 的情况第一步就是检查奖励是不是太稀疏。动力学方程里的阻尼项- 0.1 * v很关键。没有阻尼的纯积分器在随机策略下位置很容易发散加了阻尼后系统趋向稳定智能体只需要学会持续输出来对抗阻尼就能稳住位置训练难度低很多。4.3 训练选项里真正影响收敛的几个参数环境写完就轮到训练选项。rlTrainingOptions有十几个字段实际每次要动的就那么几个。MaxEpisodes设大一点没关系配合自动停止条件收敛了会自动结束不收敛就白跑后面看曲线再决定加不加轮次。trainOpts rlTrainingOptions(... MaxEpisodes, 1000, ... MaxStepsPerEpisode, 200, ... ScoreAveragingWindowLength, 50, ... StopTrainingCriteria, AverageReward, ... StopTrainingValue, -0.1, ... Plots, training-progress); agentOptions rlDDPGAgentOptions(); agentOptions.CriticOptimizerOptions.LearnRate 1e-4; agentOptions.CriticOptimizerOptions.GradientThreshold 1; agent rlDDPGAgent(actor, critic, agentOptions); stats train(agent, env, trainOpts);StopTrainingValue设 -0.1 的意思是最近 50 个 episode 的平均奖励达到 -0.1 就自动停止。这个值根据奖励量级定距离惩罚环境下平均位置误差 0.1 对应奖励 -0.1已经算收敛。如果是稀疏奖励环境这个值很可能永远达不到要靠观察曲线判断。GradientThreshold设 1 是用梯度裁剪限制更新幅度深度强化学习训练曲线变绿前经常先变红就是这个机制在起作用。学习率从默认的 1e-3 降到 1e-4前半段曲线可能更平缓但后面更稳不会出现奖励先涨后崩的过山车。Plots设成training-progress会弹出训练过程窗口实时显示每个 episode 的奖励、平均奖励和步数。这个窗口就是最直接的训练监控面板比任何日志都好用。5. CreateAgent 训练不收敛的常见问题与排查五个必看现象5.1 现象一训练曲线从头到尾平在 0奖励根本没变化训练跑了几百个 episodeepisode reward 曲线一直贴着 0没有一点起伏。这不是网络没“学会”而是环境几乎没有给出有效学习信号。原因几乎总是稀疏奖励。奖励函数只在任务成功时给 1其他时间给 0而随机探索策略在大型环境中几乎不可能碰巧成功一次智能体拿不到任何梯度信号参数更新只是在原地打转。解决方法是做奖励塑形把稀疏奖励改成稠密奖励。比如导航任务从“到达终点给 1”改成“每一步奖励等于当前位置到目标距离的负值”让智能体每一步都能看到改善空间。如果塑形实在太困难就用课程学习先让智能体从目标点附近出发学会基本控制后逐渐拉大初始距离这一招在移动机器人导航里非常有效。5.2 现象二奖励先涨后崩震荡幅度越来越大训练到 300 个 episode 时平均奖励已经涨到不错的位置继续跑反而开始下跌震荡越来越剧烈最终完全崩掉。这是过估计和策略更新的典型症状。原因有两个方向学习率过大导致 Q 值估计发散或者经验回放缓冲区太小导致训练样本缺少多样性。前者是网络更新步伐太大在损失曲面里来回弹跳后者是缓冲区只留住最近少量样本策略稍微变化旧经验被冲掉训练就失去稳定基础。解决方法是把 Critic 学习率降到 1e-4同时把经验回放缓冲区调大。MATLAB 里通过rlDDPGAgentOptions设置agentOptions rlDDPGAgentOptions(); agentOptions.CriticOptimizerOptions.LearnRate 1e-4; agentOptions.ExperienceBufferLength 1e5; agent rlDDPGAgent(actor, critic, agentOptions);ExperienceBufferLength从默认的 1e4 提到 1e5样本覆盖范围更广Q 值更新不容易被近期样本带偏。如果调完仍然震荡把TargetUpdateFrequency调低让目标网络更新慢半拍。5.3 现象三报错信息说 Obs/Act 维度对不上train 一启动就报错错误信息指向维度不匹配具体说是网络输入维度与 obsInfo 不一致或者输出维度与 actInfo 不一致。原因多数是手写了数字维度。CartPole 的观测是 4 维时你会写 4一旦换成自定义环境观测维度变成 6 或 12网络层忘了同步修改也有的是把obsInfo.Dimension直接传给fullyConnectedLayer而 Dimension 是[4 1]这种向量单层全连接不认向量输入。统一用prod(obsInfo.Dimension)取维度乘积不要自己数数。改环境观测维度时网络输入层只需要跟着 obsInfo 变不会漏改。同样道理动作输出层用prod(actInfo.Dimension)保持一致。5.4 现象四训练时表现正常evaluatePolicy 却一塌糊涂训练窗口里平均奖励已经稳定在较高的水平关掉训练用evaluatePolicy做评估结果却很差。这是最打击人的一个现象。原因在于评估时没有关闭探索机制。DQN 智能体训练结束后epsilon 可能还停留在 0.05 甚至更高每一步都有 5% 的概率输出随机动作DDPG 智能体的动作噪声也可能还在生效。评估阶段需要的是确定性策略任何探索噪声都会拉低真实水平。评估前显式关掉探索% DQN把 epsilon 直接清零 agent.EpsilonGreedyExploration.Epsilon 0; % DDPG重置动作噪声 reset(agent.ActionNoise);做完这一步再跑evaluatePolicy结果会明显好一截。如果仍然不稳把评估的 episode 数提高到 20 以上取平均单次 episode 的随机性太大不能代表真实性能。5.5 现象五同一份代码换个环境就复现不了MATLAB 2023 中文注释乱码换一台电脑或换一个 MATLAB 版本之前收敛很好的代码突然不收敛甚至直接报错找不到函数。最常见的原因是工具箱版本差异导致 API 变化其次是中文注释乱码导致脚本解析出错。MATLAB 2023 及后续版本对 Unicode 的支持有变化从旧版本编辑器或外部编辑器保存的中文注释打开后显示乱码严重时影响脚本执行。版本差异的问题在脚本头部用ver(reinforcement)记录工具箱版本号并保证代码注释里不写死 API 字段名。中文乱码的解法是统一用 UTF-8 编码保存脚本文件或者干脆注释全用英文。工程上我为这个踩过不少坑现在所有和 Simulink 交互的模型和脚本注释一律英文不是英文不好是不想再被编码问题打断思路。复现不稳定的另一个重要因素是随机种子。训练脚本第一行固定rng(2024)虽然两次训练结果不会完全一致但整体指标量级和收敛趋势会稳定很多。没有固定种子的强化学习连续跑三次能给你三个完全不同的人生。6. 训练完还要过三关evaluatePolicy、检查点续训与 Simulink 再验证6.1 evaluatePolicy固定随机种子做重复评估训练窗口里的平均奖励曲线只是训练过程的记录不代表最终策略的真实水平。evaluatePolicy用训练好的智能体在环境里跑指定数量的 episode不做任何梯度更新结果才是可以写进报告的性能指标。rng(2024); result evaluatePolicy(agent, env, ... NumEpisodes, 20, ... AverageScore, mean, ... AverageSteps, mean);固定rng种子让评估结果可复现。做对比实验时比如 PSO 这类启发式算法和深度强化学习比收敛曲线横轴要么都按评估次数要么都按训练步数统一量纲才公平。AverageScore返回平均累积奖励AverageSteps返回平均完成步数两个指标一起看光看奖励高不知道是不是拖了很长时间才完成。6.2 训练中断的后悔药检查点保存与续训训练跑了一整夜早上发现电脑休眠导致训练中断没有保存就全白干。这是最心痛的时刻解决方式就是训练过程中定期保存检查点。% 训练中途手动保存 save(agent_checkpoint.mat, agent); % 以后接着训练加载智能体继续跑 load(agent_checkpoint.mat, agent); trainOpts rlTrainingOptions(... MaxEpisodes, 2000, ... MaxStepsPerEpisode, 200); train(agent, env, trainOpts);MATLAB 的train函数会接着当前智能体的策略继续训练而不是从零开始。每次训练告一段落就save一份标注好 episode 数比如agent_ep300.mat、agent_ep600.mat训练中断或曲线崩盘时回到最近的稳定版本继续调参。这个习惯相当于给自己留后悔药长期来看能省下大量重复训练的时间。6.3 Simulink 再验证从仿真环境到硬件部署的最后一步用rlFunctionEnv验证的是控制算法的逻辑Simulink 验证的才是物理实现的可行度。Simulink 里的连续求解器、采样步长、信号数据类型都会影响策略的真实表现这些在自定义函数环境里是感知不到的。常见做法是用rlSimulinkEnv把 Simulink 模型包装成强化学习环境加载训练好的智能体用sim函数跑一次闭环仿真最后用 Simulink Coder 生成 C 代码部署到控制器。整个流程走下来才算完成一个深度强化学习工程案例的闭环。这套流程我坚持了很久先rlFunctionEnv快速验证奖励函数设计再进 Simulink 做精确验证最后固定随机种子跑evaluatePolicy回归测试。即使这样训练曲线偶尔还是翻车跑一晚上不收敛也是常有的事。现在我每个项目脚本第一行固定rng一个数没有任何理由跳出这个习惯。希望帮到你。本文还有配套的精品资源点击获取
返回列表