MADDPG多智能体博弈对抗源码解析:从环境配置到训练调参实战
简介这份资源是基于MADDPG的多智能体博弈对抗算法Python实现项目源码面向计算机相关专业正在做毕业设计、课程设计或期末大作业的学生以及需要多智能体强化学习实战练习的学习者。项目经导师指导并认可通过评审分98分可作为高分参考方案。压缩包共14个文件约1.6MB以10个py源码文件为核心另含zip依赖包、cfg环境配置、gitignore与txt说明覆盖算法实现、网络结构、经验回放与训练入口等模块。内容围绕MADDPG的Actor-Critic架构、多智能体环境交互与博弈对抗训练展开读者可据此理解集中训练分散执行的实现思路并对照自身课题完成环境搭建、参数调试与结果复现。目前已有189人学习适合作为多智能体强化学习方向的实战起点。1. 从一份 98 分毕设说起MADDPG 多智能体博弈对抗源码到底能跑出什么如果你正在做多智能体强化学习方向的毕业设计或期末大作业大概率会遇到一个尴尬局面单智能体的 DQN、PPO 代码一抓一大把但一旦把环境里塞进两个以上会互相博弈的智能体训练曲线立刻变成玄学——奖励不升反降loss 震荡得像心电图。这份基于 MADDPG 的多智能体博弈对抗算法 Python 实现项目源码正是冲着这个痛点来的。它把 MADDPGMulti-Agent Deep Deterministic Policy Gradient这套集中训练、分散执行的框架完整落地成可运行代码配套 ma-gym 环境覆盖 buffer、网络、训练主循环、测试脚本等模块。适合两类人一是需要一份结构清晰、能讲清原理又能跑通结果的毕设/课设同学二是想从单智能体跨到多智能体、需要一份可改可调的实战代码的从业者。下面我按「这是什么 → 怎么跑起来 → 坑在哪 → 怎么改出花」的顺序把这份源码拆开讲透。2. MADDPG 的集中训练分散执行为什么它比独立 DDPG 更抗环境非平稳2.1 多智能体博弈的核心难点环境非平稳性先把原理立住不然后面调参全是瞎猜。单智能体强化学习里环境转移概率是固定的智能体只要逼近最优策略就行。但多智能体场景下每个智能体的最优策略依赖于其他智能体的策略——你变我也变环境对每个个体来说都是非平稳的。独立 DDPG每个智能体各自学一个 DDPG在这种非平稳环境下经验回放里的样本分布会随对手策略漂移critic 估计的 Q 值根本收敛不了这就是为什么很多人直接拿 DDPG 复制 N 份跑多智能体结果奖励曲线一路向下。MADDPG 的解法是训练时允许 critic 看到所有智能体的观测和动作集中训练执行时 actor 只用本地观测分散执行。这样 critic 的输入包含了全局信息Q 值估计不再受对手策略漂移的干扰而 actor 依然保持去中心化部署时不需要全局通信。这个「CTDE」范式是 MADDPG 的灵魂也是这份源码里MADDPG.py和DDPG.py分工的底层逻辑。2.2 源码模块拆解每个文件在训练链路里的位置拿到一份源码先别急着python main.py把文件职责理清楚能省掉一半调试时间。这份项目的核心文件大致这样分工文件职责关键内容MADDPG.pyMADDPG 主算法类多智能体 actor/critic 管理、动作选择、更新入口DDPG.py单智能体 DDPG 实现单个 actor/critic 网络、软更新、目标网络network.py网络结构定义actor/critic 的 MLP 结构、前向传播buffer.py经验回放池存储全局观测、全局动作、奖励、下一状态rl_utils.py强化学习工具函数折扣回报计算、训练辅助main.py训练主入口环境创建、智能体初始化、训练循环test.py/test_env.py测试与验证加载模型、跑测试回合、环境自检mag.py/ceshi.py辅助/实验脚本环境封装或临时实验逻辑ma-gym-master.zip多智能体环境库提供博弈对抗类环境buffer.py是容易被忽视但极其关键的一环。MADDPG 的回放池存的不是单个智能体的(s, a, r, s)而是所有智能体的联合观测和联合动作。如果这里存错了维度critic 拿到的全局信息就是残缺的训练必然翻车。常见做法是把每个智能体的观测拼成一个全局状态向量动作同理拼接采样时再按智能体数量切分回去。2.3 环境依赖与 Python 环境配置这份源码依赖 Python 3.x、PyTorch、gym 以及 ma-gym。环境配置是新手第一道坎尤其是ma-gym这个库它不在标准 pip 源里直接可用项目里附带了ma-gym-master.zip就是为了解决这个问题。我一般会这样搭环境# 创建独立虚拟环境避免和系统 Python 冲突 python -m venv maddpg_env # Linux/Mac 激活 source maddpg_env/bin/activate # Windows 激活 # maddpg_env\Scripts\activate # 安装核心依赖torch 按自己 CUDA 版本去官网选对应命令 pip install torch numpy gym matplotlib # 解压并本地安装 ma-gym unzip ma-gym-master.zip cd ma-gym-master pip install -e . cd ..这里pip install -e .是本地可编辑安装好处是你改了 ma-gym 里的环境代码能直接生效不用重装。pyvenv.cfg这个文件说明原作者用的是 venv 虚拟环境你如果直接用系统 Python 跑很可能因为 gym 版本不匹配报AttributeError。参数上torch 版本建议 1.10 以上gym 建议 0.21 左右太新的 gym 改了 APIenv.step()返回值结构会变直接导致主循环解包失败。2.4 训练主循环怎么读从 main.py 入手main.py是理解整个训练流程的入口。它一般做四件事创建多智能体环境、实例化 MADDPG、跑训练回合、定期保存模型。读的时候重点看三个地方动作是怎么从各 actor 收集并拼成联合动作的、buffer 是怎么存入联合经验的、每个智能体是怎么轮流更新的。# main.py 训练循环的典型骨架按源码逻辑还原 for episode in range(max_episodes): obs env.reset() # 多智能体环境返回各智能体观测列表 episode_reward 0 for step in range(max_steps): # 每个智能体用自己的 actor 基于本地观测选动作 actions maddpg.select_action(obs) # 环境接收联合动作返回下一观测、各智能体奖励、done next_obs, rewards, dones, info env.step(actions) # 存入联合经验全局观测、全局动作、各智能体奖励 maddpg.add(obs, actions, rewards, next_obs, dones) # 每个智能体依次更新自己的 actor 和 critic maddpg.update() obs next_obs episode_reward sum(rewards) # 每隔若干回合评估一次并保存模型 if episode % eval_interval 0: maddpg.save_model()逻辑说明select_action内部对每个智能体调用各自的 actor 网络输出确定性动作并加探索噪声add把联合经验写入buffer.py的回放池update是 MADDPG 的核心每个智能体的 critic 用全局信息算 TD 误差actor 用 critic 的梯度更新。参数上max_steps控制单回合最大步数eval_interval控制评估频率这两个值直接决定训练时长和显存占用环境复杂时要适当调小。3. 把源码跑起来从环境自检到第一条训练曲线3.1 先跑 test_env.py 做环境自检血泪经验不要一上来就跑main.py训练先确认环境本身没问题。test_env.py通常就是干这个的——创建环境、随机采样几个动作、打印观测和奖励的维度。这一步能帮你排除掉 80% 的「训练不收敛其实是环境报错」的情况。# test_env.py 环境自检逻辑 import gym import ma_gym env gym.make(Combat-v0) # 博弈对抗类环境具体名以源码为准 obs env.reset() print(智能体数量:, env.n_agents) print(单智能体观测维度:, env.observation_space[0].shape) print(单智能体动作维度:, env.action_space[0].n) for _ in range(5): # 随机动作用于验证环境 step 是否正常 actions [env.action_space[i].sample() for i in range(env.n_agents)] next_obs, rewards, dones, info env.step(actions) print(奖励:, rewards, 结束:, dones) env.close()逻辑说明env.n_agents告诉你环境里有几个智能体这个数字必须和 MADDPG 初始化时的智能体数量一致否则网络维度对不上直接报错。observation_space和action_space是列表每个元素对应一个智能体维度信息决定了network.py里 actor/critic 输入输出层的大小。如果这里打印出来的维度和network.py里写死的维度不一致就得改网络定义。常见坑是环境名写错ma-gym 里不同环境名对应不同博弈场景名字错了会直接gym.error.NameNotFound。3.2 启动训练与关键超参数环境自检通过后跑main.py开始训练。但直接跑默认参数往往效果一般得知道哪些参数值得动。# 启动训练输出重定向到日志方便回看曲线 python main.py train_log.txt 21训练脚本里几个关键超参数的作用和调整方向参数典型值作用调整方向lr_actor1e-4actor 学习率太大策略震荡太小收敛慢lr_critic1e-3critic 学习率一般比 actor 大一个量级gamma0.95折扣因子博弈场景步数多可调高到 0.99tau0.01目标网络软更新系数越小越稳但越慢buffer_size1e6回放池容量显存/内存不够就调小batch_size1024采样批量太小梯度噪声大noise_std0.1~0.3探索噪声标准差前期大后期衰减gamma这个参数在多智能体博弈里特别敏感。博弈对抗往往需要智能体有长远眼光gamma太低会让智能体只盯着眼前奖励学不出配合或对抗策略。我一般会从 0.95 起步如果发现智能体行为短视就往 0.99 调。noise_std是探索的关键MADDPG 是确定性策略没有噪声就完全不探索但噪声太大又会让策略学不稳常见做法是随训练回合线性衰减。3.3 用 test.py 验证训练结果训练跑完或者中途保存了模型用test.py加载模型跑测试回合看智能体实际表现。这一步是把「训练曲线好看」翻译成「策略真的能用」。# test.py 加载模型并评估 import torch from MADDPG import MADDPG maddpg MADDPG(...) # 用和训练时一致的参数初始化 maddpg.load_model(model.pth) # 加载保存的权重 for episode in range(10): obs env.reset() total_reward 0 while True: # 测试阶段不加探索噪声用确定性动作 actions maddpg.select_action(obs, noiseFalse) obs, rewards, dones, info env.step(actions) total_reward sum(rewards) if all(dones): break print(f测试回合 {episode} 总奖励: {total_reward})逻辑说明测试阶段noiseFalse是关键训练时加噪声是为了探索测试时加噪声会让表现随机化看不出真实策略水平。all(dones)判断所有智能体是否都结束多智能体环境里每个智能体的 done 可能不同步必须等全部结束再重置。如果测试奖励远低于训练时的平均奖励通常是过拟合或者训练回合不够也可能是训练和测试用的环境配置不一致。4. 避坑与排查多智能体训练里那些让人怀疑人生的报错4.1 现象训练一开始就报维度不匹配原因network.py里 actor/critic 的输入输出维度是写死的但环境实际的观测维度或动作维度跟写死的不一样。多智能体环境里每个智能体的观测维度可能不同如果代码假设所有智能体维度相同就会在拼接全局状态时出错。解决先跑test_env.py打印真实的observation_space和action_space然后对照network.py改输入输出层。如果各智能体维度不同要么统一 padding 到最大维度要么给每个智能体单独定义网络。改完再跑别硬扛。4.2 现象奖励曲线长期不涨loss 也不降原因大概率是探索不足或者 critic 学不动。MADDPG 是确定性策略如果noise_std设得太小智能体从头到尾都在做几乎相同的动作回放池里样本多样性极差critic 拿不到有效梯度。解决先把noise_std调大到 0.3 左右观察回放池里的动作分布是否有变化。如果还是不动检查buffer.py里存的联合动作是不是真的包含了所有智能体的动作有时候拼接顺序错了critic 看到的「全局动作」其实是错位的Q 值自然学不对。4.3 现象显存/内存爆掉训练中途被 kill原因buffer_size设得太大或者batch_size太大。多智能体场景下每条经验存的是所有智能体的联合观测和动作单条经验体积是单智能体的 N 倍回放池很容易吃满内存。解决把buffer_size从 1e6 降到 1e5 甚至更小batch_size从 1024 降到 256。如果用的是 GPU还要注意每次update时张量是否及时释放torch.no_grad()在目标网络计算时别忘了加否则计算图会一直累积。4.4 现象训练能跑但结果每次都不一样复现不了原因随机种子没固定。多智能体强化学习对随机性极其敏感环境初始化、网络初始化、动作采样噪声、回放池采样任何一处随机都会导致结果漂移。解决在main.py开头统一固定种子包括random、numpy、torch以及环境的 seed。注意即使固定了这些GPU 上的某些算子仍有非确定性追求严格复现可以设torch.backends.cudnn.deterministic True代价是训练稍慢。4.5 现象ma-gym 环境导入报错或 step 返回值解包失败原因gym 版本和 ma-gym 不兼容。新版 gym 把step()的返回值从 4 个改成了 5 个多了truncated而这份源码大概率是按旧版 4 返回值写的。解决要么把 gym 降到 0.21 左右要么在环境封装层做兼容处理把 5 返回值截断成 4 个。我一般倾向于降版本因为改源码容易引入新问题。装的时候用pip install gym0.21.0明确指定版本别让它自动装最新版。5. 进阶玩法把 MADDPG 改造成你自己的博弈场景5.1 换环境从现成博弈环境到自定义对抗场景这份源码最大的价值不是跑通自带环境而是作为模板让你换成自己的博弈场景。换环境的核心是保证三件事对齐智能体数量、观测维度、动作空间类型。MADDPG 要求动作是连续的如果你的场景是离散动作得先把动作空间连续化或者在 actor 输出后加一层离散化映射。# 自定义环境接入 MADDPG 的适配层 class MyMultiAgentEnv: def __init__(self): self.n_agents 3 # 智能体数量必须和 MADDPG 初始化一致 self.observation_space [Box(...) for _ in range(self.n_agents)] self.action_space [Box(low-1, high1, shape(2,)) for _ in range(self.n_agents)] def reset(self): # 返回所有智能体的初始观测列表 return [self._get_obs(i) for i in range(self.n_agents)] def step(self, actions): # actions 是长度为 n_agents 的列表每个元素是该智能体的连续动作 next_obs [self._get_obs(i) for i in range(self.n_agents)] rewards [self._get_reward(i) for i in range(self.n_agents)] dones [self._is_done(i) for i in range(self.n_agents)] return next_obs, rewards, dones, {}逻辑说明observation_space和action_space必须是列表长度等于智能体数量MADDPG 初始化时会逐个读取。step返回的rewards也必须是列表每个智能体一个奖励值因为 MADDPG 里每个智能体的 critic 是独立计算 TD 误差的。如果你的场景奖励是全局共享的就把同一个值复制 N 份但要注意这样会让智能体难以区分个体贡献博弈对抗场景一般不这么做。5.2 调奖励函数博弈对抗里奖励设计比算法更重要多智能体博弈里奖励函数设计往往比换算法更能决定成败。常见做法是给每个智能体设计独立的奖励包含任务奖励和对抗/协作奖励两部分。比如对抗场景里一方得分给正奖励对方得分给负奖励再叠加一个时间惩罚促使智能体尽快结束回合。def compute_reward(self, agent_id, event): reward 0 if event hit_opponent: reward 10 # 击中对手的正奖励 elif event get_hit: reward - 10 # 被击中的负奖励 reward - 0.01 # 每步时间惩罚促使快速决策 return reward参数上正负奖励的绝对值要平衡如果正奖励远大于负奖励智能体会变得激进但容易翻车反之则过于保守。时间惩罚系数一般设得很小0.01 量级只起引导作用太大会让智能体为了省步数而放弃得分机会。调奖励是个反复试的过程建议每次只改一个维度配合test.py观察行为变化。5.3 验证方法怎么判断你的 MADDPG 真的学到了博弈策略训练曲线好看不代表策略真的学会了博弈。我一般用三个层次验证第一层看测试回合的平均奖励是否稳定高于随机策略第二层看智能体行为是否有明显的策略分化对抗场景里双方应该表现出不同的行为模式而不是做同样的动作第三层做消融把某个智能体的观测屏蔽掉看整体表现是否下降下降说明智能体之间确实形成了依赖关系。从那以后我每次拿到一份多智能体强化学习源码都强制先跑环境自检、再固定随机种子、最后用测试脚本验证行为而不是盯着训练曲线自我安慰。这套流程帮我省下了大量「以为在收敛其实在瞎跑」的时间。希望这份拆解能帮你把这份 MADDPG 源码真正跑通、改懂、用起来。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →