多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

强化学习零基础入门:路线图与PPO实践心得

强化学习零基础入门:路线图与PPO实践心得 从入门到跑通给零基础学习者的强化学习路线图与实践心得我不止一次在后台收到类似的问题“学强化学习是不是得先把数学啃透”“看了三个月理论上来写代码还是懵的怎么办”说实话这类困惑我太熟悉了。强化学习看起来门槛高因为横跨了概率论、最优化、深度学习等多块知识但其实只要路线对它并没有想象中那么难。这篇文章我打算用我自己的学习经历给想入门强化学习的你一条可以照做的路径包括怎么补基础、怎么选工具、怎么写第一个实验以及那些教科书里不会告诉你的坑。这篇文章适合谁适合 Python 基本语法没问题、对机器学习有一定概念、但还没正式接触强化学习的初学者也适合那些已经跑过一点 Demo 但总觉得“原理没串起来”的朋友。我会尽量用大白话讲概念用可以直接运行的代码讲实操保证你看完能独立跑通一个小项目并对后面的进阶路线心里有数。1. 下定决心前先把这条学习路线捋清楚1.1 强化学习到底在学什么入门强化学习之前最好先搞清楚它和普通机器学习到底哪里不一样。监督学习是给你一堆带标签的数据你学习一个从输入到输出的映射学完拿去预测新数据。强化学习则完全不是这个套路它没有现成的“正确答案”只有一个智能体在一个环境里不断试错通过环境返回的奖励信号来调整自己的行为策略。这个本质区别直接决定了两件事第一你的训练数据不是静态的而是智能体和环境交互过程中动态生成的时间序列第二模型好不好不是看准确率而是看长期累积奖励高不高。所以学强化学习的时候不能用“喂数据、训模型、测精度”的思维去套那样会非常别扭。入门阶段的目标也简单先理解马尔可夫决策过程怎么描述交互、策略和价值函数分别是什么、以及几种主流算法分别怎么优化策略。弄懂这几样你已经跨过了第一道门槛。1.2 需要哪些前置基础问到基础很多人容易被劝退。我的看法是你需要具备的数学和代码基础比大多数人想象的要少但也不能完全不碰。Python 基础熟练使用类、列表推导式、字典这些常见语法会安装第三方库、写简单的函数就够了。强化学习的代码框架性很强不会涉及太花哨的 Python 技巧。深度学习基础至少要理解“神经网络是什么、梯度下降怎么更新参数、输入输出的维度怎么流动”。因为主流算法都是深度神经网络做函数近似这部分概念躲不开。数学基础线性代数掌握向量和矩阵乘法微积分了解偏导数和链式法则概率论知道期望、采样的含义即可。你不需要从零开始证明公式但看到损失函数时得知道各项代表什么。如果在这些基础上还有缺口我建议不要系统性地去重学数学而是用到什么补什么哪里不会查哪里。等读到公式卡住了再回头翻书效率远高于一上来就啃数学教材。1.3 明确你的学习动机这个因素很关键因为强化学习的上手曲线比普通深度学习更陡容易让人中途放弃。如果你的动机是“听说这个方向前景好”或者“大家都在学”建议先冷静一下。我更建议你先想清楚“我想用强化学习解决什么”——是想做游戏 AI、机器人控制、推荐系统策略优化还是纯粹对智能体训练感兴趣动机决定了你后面选项目、选算法的方向。如果你对机械臂控制感兴趣那就往连续动作空间的算法的方向走如果你只是想把基础概念过一遍CartPole 这种经典控制环境就够你玩很久。有了具体的方向你才能在踩坑的时候有耐心继续往下走。2. 核心概念用大白话讲清楚2.1 智能体、环境与一次完整的交互强化学习里最重要的一张图就是智能体和环境之间的交互循环。我常用一个例子比喻你第一次去一家从没吃过的自助餐厅这就是一次强化学习的过程。你是智能体餐厅是环境你站起来拿食物是动作餐厅里菜品的摆放位置是状态吃到好吃的菜会开心吃到难吃的会后悔这就是奖励。在这个交互循环里每一步都有一个状态 ( s_t )智能体根据当前状态选择一个动作 ( a_t )环境收到动作后转移到新状态 ( s_{t1} )同时返回一个即时奖励 ( r_{t1} )。这个循环不断进行直到到达终止状态为止比如游戏通关、机器人摔倒、或者在自助餐厅吃饱了离开。从数学上讲大多数强化学习问题都被建模为马尔可夫决策过程简称 MDP。马尔可夫性质的意思是“未来只取决于当前状态跟过去怎么走到这一步无关”。也就是说智能体做决策时不需要记忆整条历史轨迹只需要看当前状态就够了。这个假设极大简化了问题也是几乎所有强化学习算法的基石。2.2 策略、价值函数和模型一张表看清三件套理解强化学习有三个概念就像三根柱子分别是策略、价值函数和模型。策略是智能体的决策规则它定义了在某个状态下应该选择哪些动作。策略可以是确定的比如“看到红灯就停”也可以是随机的比如“有 80% 概率选当前最优动作有 20% 概率随机探索”。随机策略看着绕其实用处很大它保证智能体能持续探索环境里没走过的角落不容易提前锁死在一个次优方案里。价值函数是评估某个状态或者某个“状态-动作对”到底“有多好”的函数。这里的“好”不是指即时奖励高而是指从这个状态出发、按照当前策略继续走下去能拿到的长期累积奖励的期望。注意“长期累积”这四个字它意味着智能体要学习的不是贪图眼前利益而是追求长期回报最大化。一个经典的例子就是下棋时选择“弃子”的走法当前这步可能损失一个棋子但长期看为胜利铺了路。模型指的是对环境动态的建模也就是知道在状态 ( s ) 下执行动作 ( a )会以多大概率转移到状态 ( s )并得到多少奖励。如果环境规则完全已知那可以用动态规划直接求最优策略但大多数实际问题并拿不到这个模型所以主流强化学习算法都会绕开“显式建模环境”这一步这也是深度强化学习能站上舞台的重要原因。下面用一张表把三者列清楚方便对照概念通俗理解数学符号策略状态的“行动指南”( \pi(a|s) )状态价值函数当前状态对智能体有多少“长期价值”( V(s) )动作价值函数在某个状态执行某动作的“长期价值”( Q(s,a) )环境模型描述环境如何转移、如何给奖励( P(s,r|s,a) )2.3 折扣因子和回报为什么明天的奖励不如今天的值钱前文说强化学习追求“长期累积奖励”那这个“累积”具体怎么算答案是用回报即把一条轨迹上的奖励全部加起来但通常会乘以一个折扣因子 ( \gamma )。折扣因子的取值在 0 到 1 之间比如 0.99。为什么要有折扣因子两个原因一是数学上的考虑无穷长轨迹的奖励之和可能发散打折后总和就是有限的数学性质好处理二是经济学的直觉今天的 100 块钱比一年后的 100 块钱更值钱同理离当前越近的奖励越应该被重视。折扣因子的取值直接影响智能体的“近视程度”。设成 0 时智能体只关心当下这一步能拿多少奖励妥妥的近视眼设成 0.99 时智能体愿意牺牲短期利益去换取远期收益。如果你做实验发现智能体表现怪怪的可以先检查一下折扣因子是不是设得不太符合场景需求。2.4 探索与利用鱼和熊掌怎么兼得探索与利用是强化学习特有的矛盾初学者特别容易忽略但它是很多算法失灵的根本原因。用大白话说利用就是你按照已经学到的经验做当前看起来最好的选择探索则是故意做出一些不一定最优的选择去获取更多环境信息。拿选餐厅来比喻利用是“昨天吃过的火锅不错今天还去那家”探索是“路过一家没试过的烧烤店进去看看”。只利用不探索你很可能一直困在局部最优里永远不知道还有更好的选择只探索不利用你的知识无法沉淀收益也上不去。经典强化学习算法里常常用贪心策略来平衡二者。简单说它有 ( \epsilon ) 的概率随机探索有 ( 1-\epsilon ) 的概率选当前最优动作。训练早期 ( \epsilon ) 设高一点多探索随着训练推进逐步降低让策略收敛。这个看似简单的机制是很多入门项目跑不起来的隐形影响因素。3. 从零搭建你的第一个强化学习实验3.1 工具选型稳定才是一切的基础概念看完接下来最重要的就是动手。我见过太多人一上来就纠结“我要不要从零写一个 DQN”我觉得完全没必要。入门的核心是快速跑通闭环建立对算法训练过程的直观感受而不是重复造轮子。我强烈推荐的学习路线是直接站在巨人肩膀上。环境方面用 Gymnasium它是业界最常用的强化学习环境库内置 CartPole、Lunar Lander、MountainCar 等经典任务接口统一文档齐全。算法方面用 Stable-Baselines3这个库实现了 PPO、DQN、SAC、DDPG 等主流算法API 友好训练时只需要少量配置就能调用。PyTorch 是底层深度学习框架Stable-Baselines3 依赖它来做网络的前向计算和梯度更新。所以入门阶段你不需要自己写网络但不代表完全不用懂至少得知道里面的策略网络和价值网络长什么样。3.2 环境安装与第一个 CartPole 实验安装过程不复杂前提是你已经搞定了 Python 3.10 以上版本和虚拟环境。我用 conda 建一个干净环境然后依次安装conda create -n rl-basic python3.10 -y conda activate rl-basic pip install torch --index-url https://download.pytorch.org/whl/cpu pip install gymnasium stable-baselines3 tensorboard为了避免依赖冲突我建议严格按这个顺序装先装 PyTorch 再装环境库。装完后跑一个最简单的脚本先看环境能不能正常交互import gymnasium as gym env gym.make(CartPole-v1, render_modergb_array) obs, info env.reset() print(初始状态, obs) for step in range(5): action env.action_space.sample() obs, reward, terminated, truncated, info env.step(action) print(f第 {step1} 步动作 {action}奖励 {reward}状态 {obs[:4]}) if terminated or truncated: obs, info env.reset() env.close()CartPole 的任务是让一根杆子立在小车上不回倒状态是四维向量动作只有左右两个选项。这个环境简单到什么程度随便采取随机动作一两秒就会失败。所以它是验证“算法是否学到了东西”最直接的试金石。3.3 使用 PPO 训练一个能稳定跑到满分的智能体环境通了下面直接上 Stable-Baselines3 的 PPO 算法训练。PPO 是现在最通用的基线算法之一稳定性和效果都经过大量实践检验特别适合入门。训练代码短到让人怀疑自己是不是漏了什么from stable_baselines3 import PPO from stable_baselines3.common.callbacks import EvalCallback from stable_baselines3.common.env_util import make_vec_env env_id CartPole-v1 train_env make_vec_env(env_id, n_envs4) model PPO( MlpPolicy, train_env, learning_rate3e-4, gamma0.99, n_steps2048, batch_size64, n_epochs10, verbose1, ) eval_env make_vec_env(env_id, n_envs4) eval_callback EvalCallback( eval_env, best_model_save_path./logs/best_model, log_path./logs/results, eval_freq1000, n_eval_episodes5, deterministicTrue, ) model.learn(total_timesteps100_000, callbackeval_callback) model.save(ppo_cartpole)几个参数我解释一下n_steps是每轮收集多少步轨迹后再统一更新参数batch_size是每批更新用多少样本n_epochs是指在同一条轨迹数据上反复训练几轮。这些就是初学者常听到的“超参数”它们直接影响训练效果但不用背后文会讲怎么调。训练结束后我们加载最优模型把策略可视化成一段视频。model PPO.load(logs/best_model/best_model.zip) env gym.make(CartPole-v1, render_modehuman) obs, info env.reset() total_reward 0 for _ in range(500): action, _ model.predict(obs, deterministicTrue) obs, reward, terminated, truncated, info env.step(action) total_reward reward if terminated or truncated: break print(累计奖励, total_reward) env.close()如果一切顺利你会在弹出来的窗口中看到小车每隔几秒就把杆子往反方向推一下整个轨迹能稳稳跑满 500 步也就是 CartPole 的满分。第一次看到这个过程的时候那种“算法真的学会了”的兴奋感是支撑我继续深入下去的动力。3.4 训练过程怎么看把 TensorBoard 开起来训练模型只是开始真正难的是看明白训练曲线在说什么。Stable-Baselines3 会自动把训练日志写到logs/results文件夹启动 TensorBoard 就能看tensorboard --logdir logs打开浏览器访问http://localhost:6006重点看rollout/ep_rew_mean这条曲线它表示训练过程中每轮的平均累积奖励。正常情况应该是阶梯式上升最后收敛在一个平台。如果你看到的是剧烈震荡甚至一直贴地说明算法、环境配置或超参数出了问题需要回头排查。TensorBoard 是我调试各种算法用得最多的工具没有之一。它比打印日志高效太多能同时对比多个超参数下的曲线走向训练中期换参数也完全不需要中断任务。4. 经典算法逐个拆从 Q-Learning 到 PPO4.1 DQN 如何用神经网络改造 Q-LearningCartPole 跑通后你已经对“训练循环”有了直接体验这时再回头理解算法就不那么抽象了。我们先从 DQN 讲起因为它是很多现代强化学习算法的起点。DQN 解决的核心问题是传统 Q-Learning 无法处理高维状态空间。传统 Q-Learning 用一张表格记录“每个状态-动作对的值”这在状态特别多时完全存不下也没法泛化到没见过的状态。DQN 的思路简单粗暴用神经网络代替那张表输入状态输出每个动作的 Q 值估计。光有网络还不够DQN 能成功有两个关键技巧。第一是经验回放系统不把每步交互数据直接用掉而是存到一个大缓冲区里训练时随机抽一小批来更新网络。这个技巧打破了连续样本之间的强相关性让梯度更新更稳定。第二是目标网络设置一个更新频率更慢的“影子网络”用来计算目标值防止模型一直在追逐一个随时移动的靶标。从代码角度看 DQN 的更新公式并不复杂它只是把 Q-Learning 的贝尔曼更新转换成带深度神经网络的监督回归问题。你训练模型的时候不用自己写这些机制但理解它以后调参出问题就更容易定位。4.2 策略梯度与 Actor-Critic绕开价值函数的另一种思路DQN 属于 value-based 方法它先学一个价值函数再从函数里推出策略。策略梯度方法则不同它直接对策略本身做参数化然后沿着“增大高回报动作概率、降低低回报动作概率”的方向去更新参数。你可以把策略梯度理解为体育教练带训练动作做得好下次就多鼓励运动员重复这条路线动作做得不好就帮他改正路线。它天然适合连续动作空间因为不需要去枚举所有动作来取最大值。不过纯策略梯度方法有一个明显缺点方差很大因为一条轨迹里每一步哪些动作好、哪些动作坏只能靠最后的累积回报来归因评估信号波动太剧烈。为了缓解这个问题Actor-Critic 架构应运而生它用一个价值网络Critic来评估当前状态的好坏用来指导策略网络Actor的更新。因为 Critic 能提供比原始奖励更平滑的反馈信号训练方差显著降低收敛也明显加速。4.3 为什么我建议初学者把 PPO 当第一个算法虽然 DQN 更早出现概念也更经典我还是强烈建议初学者直接把 PPO 作为第一个学完整实现的算法。理由有三个第一PPO 训练稳定性好它通过一个剪辑目标阻止策略在单次更新中变化过大杀死了很多“策略突然崩溃”的问题第二PPO 对超参数的敏感度相对低默认参数在很多环境下已经能跑出不错的结果这点对新手极其友好第三PPO 同时支持离散动作和连续动作控制领域从 CartPole 到机械臂仿真你不需要重复换框架。之后你可能会接触到 DDPG、SAC、TD3 这些算法也不用慌都是价值网络和策略网络在不同优化思路下的组合变体。下面这张对比表你可以收藏着作为选型时的第一参考。算法类型适用动作空间核心特点入门推荐度DQNValue-based离散动作用神经网络近似 Q 函数借助经验回放和目标网络四星REINFORCEPolicy-based离散或连续最朴素的策略梯度直观但方差大三星PPOActor-Critic离散或连续稳定、全面、超参数宽容社区资料最多五星SACActor-Critic连续动作基于最大熵探索能力强样本效率高四星DDPGActor-Critic连续动作确定性策略梯度适合机械臂但超参数略敏感四星4.4 用同一个环境对比 DQN 和 PPO 的表现“纸上得来终觉浅”这句话放在算法学习上特别对。学到这里我非常建议你自己做一组对比实验在 CartPole 上同时跑 DQN 和 PPO设置差不多的训练步数然后在 TensorBoard 里对比两条 reward 曲线的上升速度和最终水平。我在第一次做这个对比时收获巨大。同样训练 5 万步PPO 的曲线已经爬到 450 分附近DQN 还在 200 分徘徊。虽说深层次的原因涉及算法样本效率、探索策略的差异但你亲眼看到趋势发生比看十遍公式都印象深刻。这种对比实验也能帮你建立“算法效果好坏”的直觉估值能力对后续调参非常有用。5. 进阶方向盘点从基础算法到更贴近应用的研究热点5.1 深度强化学习与图强化学习不只换了个名字很多初学者看到“图强化学习”这个热搜词会比较懵这里简单拆一下。常规深度强化学习把状态表示成向量或图像然后用全连接网络或卷积网络提取特征图强化学习则把状态建模成图结构用图神经网络做特征提取。它适合节点关系非常重要的任务比如分子结构优化、交通路网信号控制、社交网络推荐等场景。我建议在没把基础算法玩熟之前先别直奔图强化学习因为它的难点不在“强化学习”而在“图神经网络”。如果你已经熟悉基础算法且研究的问题天然带图结构这条线再值得深入也不迟。5.2 基于模型的强化学习让智能体学会“想象”前面我们说过很多强化学习算法不显式建模环境直接靠真实交互学策略这类方法统称为 model-free。与之相对model-based RL 的核心思想是先从交互数据里学一个环境模型然后再在那个模型上做规划或训练策略。基于模型的强化学习最大优势是样本效率高因为智能体可以“在脑子里想象”无数次模拟轨迹不需要每次都去真实环境里碰壁。缺点是模型本身的误差会被累积放大容易出现“在虚拟世界学得很好一到现实就翻车”的情况。如果以后你考虑做机器人的真实部署model-based 方向会是绕不开的话题。5.3 离线强化学习与 IQL不靠在线探索也能学好策略离线强化学习的热度近年上升很快它的研究问题非常实际给你一批已经存在的日志数据不让你和真实环境交互你能不能从中学出好的策略这个场景在工业界太常见了因为在线试错成本高、风险大而历史数据往往已经存了很多。IQL全称是 Implicit Q-Learning是离线强化学习里一个比较有代表性的方法。它的核心思路是避免对数据集之外的“状态-动作对”做过高的价值估计从而减少外推误差。简单说它只依赖数据里真实出现过的转移不给模型发挥想象力的空间。入门者可以先理解它解决什么问题不必急着追细节等需要处理离线数据时再重点啃。5.4 机械臂强化学习实战从仿真到真实环境的挑战机械臂强化学习是热搜词里离“实体世界”最近的一条赛道。入门时建议不要碰真实硬件先用仿真环境训练一个策略。常见的选择是 Gymnasium 里的人工环境或者更专业的 MuJoCo、Isaac Gym 这类物理仿真器。机械臂任务的特征是连续动作空间所以算法通常选 SAC、PPO 或 DDPG。实践中最大的坑是奖励设计。比如你希望机械臂把一个方块推到目标位置如果只给“到达目标给 1”的稀疏奖励学习过程会极其漫长如果改成“离目标越近奖励越高”的密集奖励学习会快很多但奖励函数设计稍有不当又可能让机械臂学会把方块推着转圈而不去靠近目标。这里给一个调试奖励函数的通用经验先把任务拆成里程碑每个里程碑完成给一个中等大小的奖励再辅以少量距离诱导。我自己在仿真里调奖励函数时从一天只跑通一个简单抓取到后来半天就能让策略收敛靠的就是这套拆解方法。这中间的另一大关键是域随机化也就是在训练时随机扰动摩擦系数、质量、初始位置等参数让策略学会应对真实世界的不确定性。仿真到真实的差距越大域随机化的收益就越明显。6. 学习效率翻倍的几个经验与避坑指南6.1 固定随机种子不可省略的一步入门做实验最常见的错误是不固定随机种子。强化学习有一套完整的随机流程包括环境初始状态、策略网络权重初始化、动作采样的随机性。不固定种子导致每次实验结果都不一样你根本分不清刚调的超参数到底是变好了还是纯属运气。我的习惯是在每次训练前给torch.manual_seed、np.random.seed和 Gymnasium 环境的seed都显式设好。Stable-Baselines3 提供了seed参数直接传给model.learn即可。这样每次对比实验才有意义问题也能被稳定复现。6.2 超参数套路先默认后微调新手很容易一上来就狂调超参数结果越来越差。我在多数项目里的建议是先全部用算法库的默认参数跑通一个小环境确认代码链路没毛病再开始小范围微调。要调参数时优先看learning_rate它是所有超参数里影响最大的之一。学习率设太大网络权重震荡容易让训练直接发散设太小收敛慢几万步更新完像没学一样。通常取值范围在1e-5到1e-3之间用对数均匀网格搜索效果比线性搜索好得多。其次是gamma对环境的“视野”影响很大。任务需要长期规划设 0.99 甚至 0.995 才合理如果任务每一步独立性较强0.9 就够。经验法则是你希望智能体考虑“未来多少步”的影响就把 gamma 设成接近这个步数的倒数。6.3 判断训练有没有问题的三看方法训练一跑起来新手最容易陷入焦虑“我的曲线是在涨吗”“是不是训练废了”我总结了一个三看排查法帮你快速定位问题。一看平均奖励曲线是否呈现阶梯上升。如果完全平着不动先检查环境是否在正常交互动作是否真的影响了环境状态。二看损失曲线是否异常变大。损失有波动很常见但如果直接冲到几十万甚至 NaN那基本是学习率太大或者奖励值没做归一化。三看智能体的行为本身是否有语义。光看数值不够还需要用render_modehuman实际盯着智能体跑几局看它是在瞎撞还是有点章法。这三步排查走下来大多数入门阶段的训练问题都能定位到是数据流、超参数还是环境设定出了问题而不是两眼一抹黑地盲调。6.4 抄作业的正确姿势最后聊一个很多大牛不爱提的学习方法抄作业。所谓抄作业不是直接复制粘贴代码然后跑完就算了而是先照着优秀的项目把代码一行行读进肚里弄懂每个函数在干嘛然后手动重写一遍再改动环境或奖励目标做出自己的版本。我入门时有两份常驻收藏一份是 Hugging Face 的 Deep RL Course另一份是 Stable-Baselines3 官方文档里的示例项目。前者课程设计系统从基础概念到训练智能体都有讲解后者的示例代码是最适合改写的模板。把这两份材料啃透一遍再去啃论文和复现实验难度会指数级下降。6.5 关于算力和投入的定心丸写到这里我想多说一句关于硬件焦虑的话。很多人觉得强化学习一定需要多张高端显卡才能跑其实入门阶段完全没必要。像 CartPole 和 Lunar Lander 这类环境靠 CPU 几分钟就能跑完整个训练。即便到 MuJoCo 机械臂仿真单张普通游戏显卡也够了。真正的成本是时间需要反复调参、反复观察曲线、反复跑实验。如果你发现某次训练怎么调都不收敛不用急着砸显卡先回去检查环境和奖励函数大概率问题出在那里。我在机械臂仿真里遇到一次策略彻底学不会的情况最后是因为动作上限没缩放到合理范围根因只在参数的一个符号上。回到开头的话题强化学习入门这件事难的不是代码和数学而是心理预期和路径选择。不要指望一上来就复现论文级别的效果把目标定成“跑通一个项目、调通一个算法、看懂一条曲线”这个阶段的任务就算漂亮收官了。顺着这条路走下去下一步无论是啃图强化学习、离线强化学习还是试水机械臂真实部署你都已经有了一个能持续成长的地基。
返回列表