【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏:
【强化学习】(47)---《深入理解多智能体近端策略优化(MAPPO)算法与调参》
深入理解多智能体近端策略优化(MAPPO)算法与调参
目录
0 前言
1 MAPPO核心特点
2 On-Policy 和 Off-Policy
2.1. On-Policy 算法
2.2 Off-Policy 算法
对比总结
形象比喻
On-Policy 的小孩
Off-Policy 的小孩
它们的关键区别:
3 MAPPO 是 On-Policy,如何学习历史经验?
4 MAPPO 算法的调参建议
超参数相关
网络结构相关
环境相关
更新频率
[Python] On-Policy 和 Off-Policy 实现
[Notice] 注意事项
5 总结
0 前言
MAPPO 是一种多智能体强化学习算法,基于单智能体的 PPO (Proximal Policy Optimization) 算法进行了扩展,专门设计用于解决多智能体协作和竞争环境中的决策问题。
如果对于MAPPO算法不了解,可以查看这篇文章(代码):
【MADRL】多智能体近端策略优化(MAPPO)算法
1 MAPPO核心特点
-
集中价值网络(Centralized Critic)
- MAPPO 使用一个 centralized critic,将多个智能体的状态、动作信息整合在一起,用于计算价值函数。
- 政策(policy)仍然是每个智能体独立的(decentralized),适合分布式执行。
-
分布式执行与集中式学习
- 在训练时,所有智能体共享全局信息,进行集中式学习。
- 在执行时,每个智能体仅依赖自己的局部观察,保持分布式决策的能力。
-
对 PPO 的优化
- PPO 的核心是通过 clip range 限制策略更新的幅度,确保训练稳定。MAPPO 在多智能体环境中保留了这一优点。
- 针对多智能体场景,对网络结构、数据处理等进行了调整,优化了 PPO 在该场景下的性能。
2 On-Policy 和 Off-Policy
要想更好的理解MAPPO算法的原理机制,得先从On-Policy 和 Off-Policy 两种算法类型出发。在强化学习中,on-policy 和 off-policy 算法根据策略更新时是否依赖当前策略的经验来区分。
以下是两类算法的定义和常见算法列表:
2.1. On-Policy 算法
定义:
- On-policy 算法依赖于当前策略生成的经验进行更新。
- 每次策略更新需要使用最新的采样数据,不能直接利用历史经验。
- 强调策略与数据分布的一致性。
常见的 On-Policy 算法
-
Policy Gradient (PG)
- 基本策略梯度方法。
-
Trust Region Policy Optimization (TRPO)
- 提高策略更新的稳定性,限制更新幅度。
-
Proximal Policy Optimization (PPO)
- TRPO 的改进版本,具有更简单的实现。
- 两种变体:clip-PPO 和 adaptive KL-PPO。
-
Actor-Critic 系列
- A2C (Advantage Actor-Critic):同步更新的 Actor-Critic。
- A3C (Asynchronous Advantage Actor-Critic):异步更新版本。
-
MAPPO (Multi-Agent PPO)
- 专为多智能体场景设计的 PPO 变种。
优点
- 理论收敛性强。
- 更新稳定,适合复杂策略。
缺点
- 样本利用率低(每条数据通常只用一次)。
- 对环境交互的需求较高。
2.2 Off-Policy 算法
定义:
- Off-policy 算法利用历史经验进行策略更新,数据采样可以来自不同策略。
- 借助经验回放(replay buffer)提高样本利用率。
常见的 Off-Policy 算法
-
Q-Learning 系列
- DQN (Deep Q-Network):结合神经网络的 Q-learning。
- Double DQN:解决 DQN 过估计问题。
- Dueling DQN:分离状态价值和动作优势。
-
Deterministic Policy Gradient (DPG)
- 专为连续动作空间设计。
-
Deep Deterministic Policy Gradient (DDPG)
- DPG 的深度强化学习版本,结合 replay buffer 和目标网络。
-
Twin Delayed Deep Deterministic Policy Gradient (TD3)
- DDPG 的改进版,缓解过估计问题。
-
Soft Actor-Critic (SAC)
- 基于最大熵的策略,适用于连续动作空间。
-
Q-Learning with Function Approximation
- Fitted Q、Neural Fitted Q 等。
优点
- 样本利用率高(数据可多次利用)。
- 更适合数据采样成本高的任务(如真实机器人交互)。
缺点
- 更新的稳定性较差(需要经验回放和目标网络)。
- 训练复杂度较高。
对比总结
特性 | On-Policy | Off-Policy |
---|---|---|
样本利用率 | 低(一次性使用) | 高(可重复利用) |
缓冲区 | 无长期缓冲区 | 使用 replay buffer |
策略一致性 | 必须与当前策略一致 | 可利用任意策略生成的数据 |
学习效率 | 依赖高频环境交互 | 适合数据采样成本高的场景 |
收敛性 | 理论收敛性强 | 收敛性依赖数据分布 |
应用场景 | 实时决策、多智能体 | 复杂连续动作、高成本环境 |
形象比喻
on-policy有点像个调皮的小孩子,被打了/奖励了,当场就长记性的那种。而off-policy这种小孩子,被打了/奖励了,它还得回味下,这是一次偶然的惩罚还是这样做就是不好的,他还会去调皮的捣蛋,直到被打怕了(学习到了)。
On-Policy 的小孩
- “被打了/奖励了,当场就长记性”
贴合 on-policy 的特点:- on-policy 是即时性学习,完全依赖于当前策略的反馈进行调整。
- 它专注于当前的策略表现,而不会回头复盘过去的错误或奖励。
- 优点:即时调整,学习过程直接且明确。
- 缺点:缺乏对历史的反思和利用,样本效率低。
Off-Policy 的小孩
-
“回味一下,这是一场偶然的惩罚还是这样做就是不好的”
- 描述了 off-policy 的核心机制:利用经验回放。off-policy 会保存大量的历史经验,在反复回顾和分析中找到优化策略的方法。
- 这种行为类似一个喜欢“钻牛角尖”的小孩,经过无数次试验才明白真正的规律。
-
“调皮地捣蛋,直到被打怕了”
- off-policy 算法在学习时确实会反复尝试甚至冒险探索(如 DQN 的 ϵϵ-greedy 策略),不断调整对环境的理解。
- 它的学习过程可能显得缓慢,但通过深入分析历史数据,它最终会学得更全面和稳定。
它们的关键区别:
- 即时性 vs 历史性:on-policy 专注于当前,而 off-policy 反思过去。
- 效率 vs 深度:on-policy 快速适应环境,而 off-policy 更深刻地理解长期规律。
3 MAPPO 是 On-Policy,如何学习历史经验?
有了上面的基础,MAPPO 是 on-policy。它的缓冲区(buffer)在每次新的 episode 开始时会被清空,而不像 off-policy 算法那样长期保留数据。这主要体现在以下几点:
为什么会清空缓冲区?
On-Policy 的约束
On-policy 算法(如 PPO 和 MAPPO)的策略更新只能依赖最新策略采样的数据,历史数据与当前策略分布不一致,因此被舍弃。这确保了策略更新的稳定性。
如何应对这个问题?
尽管无法直接使用历史经验,仍然可以通过以下方法弥补:
-
加大采样量(buffer size)
增加单次采样的episode_length
或batch_size
,让模型在每次采样时接触更多样本。 -
使用 advantage 标准化
通过标准化 GAE 或 Q 值来减小不同 episode 数据间的方差,从而稳定更新。 -
调整训练步数
MAPPO 的一个优势是,它通常以 centralized critic 方式加速策略学习。通过适当增加训练步数,可以弥补无法利用历史经验的缺陷。 -
环境重置机制
对于训练环境,确保多样性,例如引入 domain randomization 或多种初始化状态,间接增加训练数据的广度。
4 MAPPO 算法的调参建议
MAPPO 的核心参数调节分为以下几类:
超参数相关
-
学习率(learning rate)
适当调低学习率可以提高稳定性,尤其在多智能体环境中噪声较大的情况下。通常建议从 1e−4或 5e−4开始测试。 -
折扣因子(gamma)
γγ 控制长期回报的权重,推荐从 0.95 或 0.99开始,根据任务的时间跨度调整。 -
GAE λ(lambda for Generalized Advantage Estimation)
通常设置为 0.95 左右,平衡偏差与方差的影响。 -
clip range(裁剪范围)
PPO 的核心超参数,通常设置为 0.1 到 0.3 之间,越小代表对策略更新的限制越强。
网络结构相关
-
隐藏层大小(hidden size)
可以调试网络的层数和每层的单元数。典型设置为两层,每层 64 到 256 个单元,视环境复杂度而定。 -
共享网络与独立网络
MAPPO 支持共享网络(centralized critic)或独立网络(decentralized critic)。如果任务需要高效协作,建议使用共享网络。
环境相关
-
batch size
批量大小对训练效率有很大影响,推荐设置为每次采样 2048 到 4096 个 time steps,或者按环境规模调整。 -
episode length
对于 MAPPO,episode_length
确实非常关键,因为它决定了每次采样的数据量。可以根据环境复杂度和任务长度动态调整,通常从 200 到 1000 步之间。
更新频率
- policy update iterations
每次采样后,建议进行 4 到 10 次梯度更新(epochs),以保证策略能够充分利用每批数据。
[Python] On-Policy 和 Off-Policy 实现
以 Proximal Policy Optimization (PPO) 为例:
🔥若是下面代码复现困难或者有问题,欢迎评论区留言;需要以整个项目形式的代码,请在评论区留下您的邮箱📌,以便于及时分享给您(私信难以及时回复)。
"""《on-Policy》时间:2024.11作者:不去幼儿园
"""
Initialize policy network πθ with parameters θ
Initialize value network Vϕ with parameters ϕfor iteration = 1, 2, ..., N do# Collect trajectories (states, actions, rewards) using current policy πθtrajectories = []for episode = 1, ..., M dostate = environment.reset()episode_trajectory = []for t = 1, ..., T doaction = πθ(state) # Sample action from current policynext_state, reward, done = environment.step(action)episode_trajectory.append((state, action, reward))if done:breakstate = next_statetrajectories.append(episode_trajectory)# Compute advantages using GAE or Monte Carlo returnsadvantages, returns = compute_advantages(trajectories, Vϕ)# Update policy πθ using clipped surrogate objectivefor _ in range(policy_update_epochs):policy_loss = compute_policy_loss(πθ, advantages)θ = θ - α_policy * ∇(policy_loss)# Update value network Vϕfor _ in range(value_update_epochs):value_loss = compute_value_loss(Vϕ, returns)ϕ = ϕ - α_value * ∇(value_loss)
以 Deep Q-Learning (DQN) 为例:
"""《off-Policy》时间:2024.11作者:不去幼儿园
"""
Initialize Q-network Qθ with parameters θ
Initialize target network Qθ' with parameters θ' = θ
Initialize replay buffer Dfor iteration = 1, 2, ..., N dostate = environment.reset()for t = 1, ..., T do# ε-greedy policy for explorationif random() < ε:action = random_action()else:action = argmax(Qθ(state))next_state, reward, done = environment.step(action)# Store transition in replay bufferD.append((state, action, reward, next_state, done))# Sample minibatch from replay bufferminibatch = random_sample(D, batch_size)# Compute target valuestarget_values = []for (s, a, r, s_, done) in minibatch:if done:target = relse:target = r + γ * max(Qθ'(s'))target_values.append(target)# Update Q-network Qθloss = compute_loss(Qθ, minibatch, target_values)θ = θ - α * ∇(loss)# Update stateif done:breakstate = next_state# Periodically update target networkif iteration % target_update_freq == 0:θ' = θ
[Notice] 注意事项
on-policy 关键点:
- 数据从环境实时采样,不存储历史数据。
- 更新策略和价值网络时仅使用当前采样的数据。
- 每次策略更新后,之前的数据会被丢弃。
off-policy 关键点:
- 使用 replay buffer 保存历史数据,重复利用经验。
- 策略与目标网络更新分离,数据可以来自不同的策略。
- 数据利用率高,但需要经验回放和目标网络来稳定训练。
由于博文主要为了介绍相关算法的原理和应用的方法,缺乏对于实际效果的关注,算法可能在上述环境中的效果不佳或者无法运行,一是算法不适配上述环境,二是算法未调参和优化,三是没有呈现完整的代码,四是等等。上述代码用于了解和学习算法足够了,但若是想直接将上面代码应用于实际项目中,还需要进行修改。
5 总结
MAPPO 是一个高效、稳定且适应性强的多智能体强化学习算法,通过结合 PPO 的稳定性和多智能体环境的需求,为协作与竞争场景提供了强有力的解决方案。
博客都是给自己看的笔记,如有误导深表抱歉。文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者添加VX:Rainbook_2,联系作者。✨
相关文章:

【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅…...
深入探索Go语言中的sync.Mutex与sync.RWMutex:原理、应用与实践
深入探索Go语言中的sync.Mutex与sync.RWMutex:原理、应用与实践 在并发编程的世界里,Go语言以其独特的并发模型和简洁的语法赢得了广泛的关注。在Go语言的并发控制工具箱中,sync.Mutex和sync.RWMutex是两个至关重要的工具,它们帮助开发者保护共享资源,避免竞态条件,确保…...

15.postgresql--jsonb 数组进行打平,过滤
用jsonb_array_elements函数先展开数组,再用jsonb_each函数遍历元素中的键值对 例如: SELECT * FROM data_table, LATERAL jsonb_array_elements(json_column) WITH ORDINALITY as elem(element, idx) JOIN LATERAL jsonb_each(elem.element) as kv(ke…...

linux下i2c开发与框架源码分析
目录 1 概述 2 I2c子系统框架 3 I2C的使用流程 3.1 在驱动里使用 3.2 在应用层使用 3.3 I2ctool的使用 4 为硬件i2c注册一个适配器 5 i2c子系统源码流程分析 5.1 i2c device与driver绑定过程 5.1.1 Driver的注册与处理 5.1.2 Client device的生成 5.2 I2c的发送与接…...
[ruby on rails] 安装docker
1. docker安装 ubuntu14.04后自带docker安装包,可以直接安装docker.io sudo apt-get updatesudo apt-get install -y docker.io # 安装后启动sudo service docker start最新版本docker 安装docker-ce # 官方源 curl -fsSL https://download.docker.com/linux/ubun…...
I2C学习
详情学习 12. I2C通讯 — [野火]Linux基础与应用开发实战指南——基于LubanCat-RK系列板卡 文档 (embedfire.com) 问题 i2c总线中scl和sda两条线的作用以及区别 在 I2C 总线(Inter-Integrated Circuit)中,SCL 和 SDA 是两条核心信号线&am…...

VUE:基于MVVN的前端js框架
文章目录 vue框架v-show vue框架 注意是 先写函数名,再写function。 handle:function (){}下面是错误的 function:handle(){}3 v-show 本质上等于号后面还是判断条件,所以不能写赋值语句,下面是正确的 下面是错误的 v-show " ge…...

06、Spring AOP
在我们接下来聊Spring AOP之前我们先了解一下设计模式中的代理模式。 一、代理模式 代理模式是23种设计模式中的一种,它属于结构型设计模式。 对于代理模式的理解: 程序中对象A与对象B无法直接交互,如:有人要找某个公司的老总得先打前台登记传达程序中某个功能需要在原基…...
c语言学习26字符串的应用
字符串在stm32串口中的应用 串口控制流水灯 pc通过串口发送字符串命令控制流水灯 open 流水灯打开 close 流水灯关闭 speed 1~9速度控制 if(strcmp((char *)usart1_rec_buff,"open")0) { led_flag 1; } else if(strcmp((char *)usart1_rec_buff,"close&qu…...

法语旅游常用口语-柯桥学外语到蓝天广场泓畅学校
以下是一些实用的法语旅游常用口语,帮助你在法国旅行时能够进行基本的交流: 问候与道别 Bonjour: 用于日常问候。Au revoir: 用于告别。 请求帮助 S’il vous plat: 用于请求帮助,例如在需要寻找某个地点或服务时。 询问信息 Excusez-moi: 用…...

Kafka 生产者优化与数据处理经验
Kafka:分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析:从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析:…...

MySQL 主从复制之多线程复制
一、MySQL 多线程复制的背景 MySQL 的主从复制延迟一直是受开发者最为关注的问题之一,MySQL 从 5.6 版本开始追加了并行复制功能,目的就是为了改善复制延迟问题,并行复制称为enhanced multi-threaded slave(简称MTS)。…...

Linux2.6内核进程调度队列
文章目录 前言运行队列 runqueue优先级活动队列过期队列活跃队列 VS 过期队列active指针和expired指针O(1)调度算法 前言 在前面学习并认识了进程之后,我们会发出一个疑问:Linux内核是如何调度进程的呢? 接下来我们就以Linux2.6内核为例深入探…...

Infineon(英飞凌) TLE985xQX 芯片电机工作电流、电压AD采样
其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 单片机芯片合集 文章目录 其他系列文章导航 文章目录 前言 一、选取合适的端口 1.通过 OP1、OP2 电流采集运放输入端口进行H桥驱动的电流采集。 2.通过 O_D_VBAT_AD_EN、I_A_VBAT_A…...
Sparrow系列拓展篇:对信号量应用问题的深入讨论
前言 笔者之前已经介绍过了Sparrow信号量的源码,但是对于信号量的使用,并没有讲得非常详细,仅仅讲了同步与互斥的概念。 本章让笔者介绍如何使用Sparrow的信号量,深入探讨一下信号量在同步、计数与互斥中的应用。 使用信号量解…...

图文详解Docker下配置、测试Redis
文章目录 前言实测环境:实验思路: 正文1.准备工作2. 配置、运行 Redis 容器3. 配置测试 总结 前言 配置、测试redis数据库服务器,首先确保正确安装docker,并且已启动运行,具体安装docker方法见笔者前面的博文《OpenEu…...

Python编程艺术:优雅与实用的完美平衡(推导式)
在Python这门优雅的编程语言中,处处体现着"简洁即是美"的设计哲学。今天我们深入探讨Python中那些让代码更优雅、更高效的编程技巧,这些技巧不仅能提升代码的可读性,还能让编程过程充满乐趣。 列表推导式的魔力 Python的列表推导…...
Spring Boot框架Starter组件整理
在Spring Boot框架中,starter是一种预定义的依赖集合,旨在简化Maven或Gradle等构建工具中的依赖管理。每个starter都包含了实现特定功能所需的库和组件,以及相应的配置文件。开发者只需在项目中引入相应的starter依赖,即可快速搭建…...
C/C++基础知识复习(27)
1) 移动语义和拷贝语义的区别 拷贝语义和移动语义是C中对象所有权管理的两种机制,主要在对象初始化、赋值或传参时体现。 拷贝语义 (Copy Semantics) 行为:通过深拷贝或浅拷贝,创建一个新对象,并将原对象的值或资源复制到新对象…...

IEC61850实现方案和测试-2
IEC61850实现方案和测试-1作为介绍实现方案和测试的第二篇文章,后续会继续更新,欢迎关注。 第一篇是:IEC61850实现方案和测试-1-CSDN博客 UCA详细测试用例下载: 链接: https://pan.baidu.com/s/1TTMlYRfzKITgrkWwwtcrDg 提取码:…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...