主题
代码实战
代码实战栏目汇总了本站所有教程中的可运行代码。代码风格参考 CleanRL 的“单文件实现”理念:一个文件包含一个算法的全部逻辑,不依赖自定义框架,便于阅读和修改。所有代码都在本站环境中实际运行过,下表给出的是真实观测到的结果(单线程 CPU、短训练预算、通常是单个随机种子),不是论文数字,也没有挑选最好的一次。
环境准备
Python 与 PyTorch 安装
bash
python -m venv rl && source rl/bin/activate # Windows: rl\Scripts\activate
pip install torch --index-url https://download.pytorch.org/whl/cpu # 只用 CPU 即可
pip install gymnasium numpy1
2
3
2
3
本站验证环境:Python 3.13、PyTorch 2.x(CPU)、Gymnasium 1.4.0、NumPy 2.x。有 GPU 的读者按 PyTorch 官网 安装 CUDA 版本即可,代码会自动使用 GPU(DQN 示例)或在 CPU 上运行(其余示例的网络很小,CPU 更快)。
Gymnasium 与 MuJoCo
bash
pip install "gymnasium[atari]" opencv-python # DQN 的 Atari 预处理示例
pip install "gymnasium[mujoco]" # MuJoCo 连续控制(本站示例未用到,练习题中会用到)
pip install mpe2 # 多智能体粒子环境 MPE(IPPO / MAPPO 示例)1
2
3
2
3
建议在多核机器上同时运行多个实验时设置 OMP_NUM_THREADS=1,避免 PyTorch 线程互相争抢 CPU。
实现清单
代码位于仓库的 examples/ 目录,页面中显示的就是这些文件本身。
入门(NumPy,表格方法)
| 文件 | 教程 | 环境 | 实测结果 |
|---|---|---|---|
basics/bandit.py | 多臂老虎机 | 10 臂伯努利老虎机 | 5000 步累积懊悔(200 次平均):汤普森 40.3、衰减 ε 132.9、ε=0.1 240.6、UCB1 276.4 |
basics/mdp_occupancy.py | MDP | 天气 MRP / 两状态 MDP | MRP 解析价值与蒙特卡洛一致(v(雨) 5.641 对 5.646);三种策略的 ⟨ρ,r⟩/(1−γ) 与 V(A) 完全相同 |
basics/bellman_solve.py | 贝尔曼方程 | FrozenLake-v1 | 随机策略价值:解析解与迭代解最大误差 3.3e-10 |
basics/dp.py | 动态规划 | FrozenLake-v1 | 策略迭代 7 轮、价值迭代 324 次扫描收敛,最优策略成功率 0.737 |
basics/mc_blackjack.py | 蒙特卡洛 | Blackjack-v1 | 50 万局 MC 控制后平均回报 −0.045(“≥20 停牌”策略为 −0.349) |
basics/td_random_walk.py | TD 学习 | 5 状态随机游走 | 100 回合后 RMS 误差:TD(0) 最低 0.036,MC 最低 0.085 |
basics/cliff_q_sarsa.py | Q-learning 与 SARSA | CliffWalking-v1 | 贪心路线回报:Q-learning −13.0(最短路线),SARSA −15.4(安全路线) |
basics/nstep_sarsa_cliff.py | Q-learning 与 SARSA | CliffWalking-v1 | α=0.1 时前 50 回合平均回报:n=1 −209.2,n=3 −139.3,n=5 −144.9 |
basics/gym_frozenlake_q.py | Gymnasium 上手 | FrozenLake-v1 / CartPole-v1 | Q-learning 成功率 0.728;CartPole 随机策略 23.7 分 |
basics/gym_custom_env.py | Gymnasium 上手 | 自定义走廊环境 | 通过 check_env 检查 |
进阶(PyTorch)
| 文件 | 教程 | 环境 | 训练预算 | 实测结果 |
|---|---|---|---|---|
advanced/dqn_cartpole.py | DQN | CartPole-v1 | 5 万步 | 贪心评估 500(3 个种子:500 / 470.9 / 500) |
advanced/dqn_atari_setup.py | DQN | ALE/Breakout-v5 | 不训练 | 仅验证预处理与网络形状 |
advanced/dqn_variants.py | DQN 改进 | CartPole-v1 | 5 万步 × 5 配置 × 2 种子 | 各配置差异小于种子间波动,未观察到稳定提升 |
advanced/reinforce_cartpole.py | REINFORCE | CartPole-v1 | 1000 回合 | 随机策略训练回报最高约 484;argmax 评估 289 |
advanced/a2c_cartpole.py | A2C | CartPole-v1 | 20 万步 | 训练回报在 300–480 波动;贪心评估 500 |
advanced/trpo_cartpole.py | TRPO | CartPole-v1 | 约 10 万步 | 4 万步后稳定在 500;贪心评估 500 |
advanced/ppo_cartpole.py | PPO | CartPole-v1 | 20 万步 | 约 12 万步起稳定 500;贪心评估 500(2 个种子) |
advanced/ppo_pendulum.py | PPO | Pendulum-v1 | 约 20 万步 × 3 种子 | 确定性评估 −206.3 / −202.8 / −226.6 |
advanced/ddpg_pendulum.py | DDPG | Pendulum-v1 | 2 万步 | 确定性评估 −168.0 |
advanced/td3_pendulum.py | TD3 | Pendulum-v1 | 2 万步 | 确定性评估 −169.1 |
advanced/sac_pendulum.py | SAC | Pendulum-v1 | 2 万步 | 确定性评估 −166.3 |
advanced/sac_discrete_cartpole.py | SAC | CartPole-v1 | 4 万步 × 3 种子 | 贪心评估 500 / 500 / 384.7 |
advanced/her_point_goal.py | 目标导向 RL 与 HER | 自建二维到达任务 | 600 回合 × 3 种子 | 第 100 回合成功率:DDPG+HER 1.00,DDPG 0.02–0.04;DDPG 在第 400–600 回合才到 1.00 |
advanced/dyna_q_maze.py | 基于模型的 RL | Dyna 迷宫 | 50 回合 × 30 次 | 第 2 回合步数:n=0 为 742,n=50 为 45 |
advanced/mpc_pendulum.py | MPC | Pendulum-v1 | 10 回合(2000 步)× 2 种子 | 第 3–10 回合平均:随机打靶 −278.6,CEM −170.3,PETS −196.7 |
advanced/mbpo_pendulum.py | MBPO | Pendulum-v1 | 5000 步 × 2 种子 | 2000 步时:MBPO 约 −100,SAC 约 −1300,同更新比 SAC×10 约 −98 |
advanced/offline_cartpole.py | 离线 RL | CartPole-v1 数据集 | 离线训练 | 纯专家数据:朴素 DQN 9.4,CQL 500,BC 500 |
advanced/cql_pendulum.py | 离线 RL | Pendulum-v1(SAC 回放缓冲区 6000 条) | 离线 2 万步 × 2 种子 | BC −892.9 / −821.9,朴素离线 SAC −108.5 / −108.9,CQL(α=5) −125.5 / −124.8 |
advanced/marl_climbing.py | 多智能体 RL | 攀爬博弈 | 5000 轮 × 100 种子 | 独立 Q 学习 0% 找到最优,联合学习 100% |
advanced/ippo_mappo_spread.py | 多智能体 RL | MPE simple_spread(N=3) | 80 万步 × 2 种子 | 平均回合回报:随机 −27.0,IPPO −16.44 / −16.31,MAPPO −16.67 / −16.36 |
advanced/bc_dagger_cartpole.py | 模仿学习 | CartPole-v1 | 极少示范 | BC(10 样本) 64 → DAgger(60 样本) 310;BC(60 专家样本) 464 |
advanced/gail_cartpole.py | 模仿学习 | CartPole-v1(25 对示范) | 约 20 万步 × 3 种子 | 奖励 −log(1−D):500 / 500 / 500;奖励 log D−log(1−D):9.2 / 37.7 / 9.2;同数据 BC:42.0 / 494.0 / 53.6 |
advanced/rlhf_toy.py | RLHF 与大模型 RL | 玩具“问答” | 数秒 | GRPO、DPO 均把正确回答概率从约 0.12 提升到约 1.0 |
Pendulum 的回报越接近 0 越好(随机策略约 −1200,约 −200 以上可认为学会);CartPole 满分 500。
运行方式
bash
cd examples/advanced
python ppo_cartpole.py
python dqn_variants.py --double --dueling --per --seed 0
python mpc_pendulum.py pets 0 # 部分较慢的脚本支持只跑一个“方法 + 种子”,便于并行
DQN_QUICK=1 python mbpo_pendulum.py # 支持 DQN_QUICK=1 的脚本会只跑很短的版本,用来检查环境1
2
3
4
5
2
3
4
5
如何复现与调参
- 随机种子:代码设置了 Python / NumPy / PyTorch 和环境的种子,但 Gymnasium 中
action_space.sample()有独立的随机数生成器(需env.action_space.seed(...)),多线程浮点运算也存在微小的不确定性,所以重复运行的数值可能与页面略有不同。 - 多种子评估:强化学习结果的方差很大。我们在 DQN 改进 和 PPO 页面中都遇到了“换一个种子或一个超参数,结论就变了”的情况。比较算法时至少使用 5 个种子,报告均值和置信区间(参考 Henderson et al., 2018, Deep Reinforcement Learning that Matters;Agarwal et al., 2021, Deep RL at the Edge of the Statistical Precipice)。
- 区分训练回报和评估回报:训练回报包含探索噪声(ε-贪心、随机策略采样),评估时通常用确定性策略。两者可能差异很大(例如 REINFORCE 页面)。
- 先保证正确,再调参:用最简单的环境(CartPole、Pendulum)确认代码能学会,再迁移到复杂任务。
- 常用调参顺序:学习率 → 批量 / 采样长度 → 网络大小 → 算法特有超参数(如 PPO 的 epoch 数、SAC 的目标熵)。
Jupyter notebook 与在线运行
examples/ 中的每个脚本都自动生成了一个同名的 Jupyter notebook(notebooks/ 目录,例如 notebooks/advanced/ppo_cartpole.ipynb)。每个使用了示例代码的教程页面顶部都有按钮:
- 下载 notebook:直接下载
.ipynb,在本地 Jupyter / VS Code 中打开即可运行。第一个代码单元会检查依赖,缺什么装什么。 - 在 Colab 中打开:打开 GitHub 仓库中的同一个 notebook(需要站点配置好 GitHub 仓库地址后才会启用)。注意:Google Colab 在中国大陆通常无法直接访问,国内读者建议下载后在本地运行,或使用国内的 notebook 平台(如 ModelScope 魔搭、阿里云天池、百度 AI Studio)上传运行。
- 在国内平台打开:站点配置了国内平台入口后会显示。
notebook 的内容与 .py 文件完全一致:第 1 个单元是说明,第 2 个单元是环境准备,之后按函数和逻辑段落切分成若干代码单元。支持 DQN_QUICK 开关的脚本,可以在环境准备单元中取消注释 os.environ["DQN_QUICK"] = "1",先用很短的训练确认能跑通。
本站对所有 notebook 都用 jupyter nbconvert --execute 实际执行过一遍(训练较久的脚本使用 DQN_QUICK=1 的短版本),确认可以从头运行到尾。Colab 的免费 CPU 足以运行本站的所有示例;训练最久的是 MPC(PETS)、MBPO 和多智能体示例,完整版本在单线程 CPU 上需要十几分钟到一小时。
参考文献
- Huang, S. et al. (2022). CleanRL: High-quality Single-file Implementations of Deep Reinforcement Learning Algorithms. JMLR, 23(274), 1–18. arXiv:2111.08819
- Henderson, P. et al. (2018). Deep Reinforcement Learning that Matters. AAAI. arXiv:1709.06560
- Agarwal, R. et al. (2021). Deep Reinforcement Learning at the Edge of the Statistical Precipice. NeurIPS. arXiv:2108.13264
下一步
不确定该用哪个算法?看 算法对照表。