强化学习入门-5(MAPPO)
多智能体强化学习项目-5-simple_spread-v3(MAPPO)
环境
本环境是 PettingZoo 库中 MPE (Multi-Agent Particle Environments) 系列的一个经典多智能体协作环境。
官网链接:https://pettingzoo.farama.org/environments/mpe/simple_spread/
任务描述:
这是一个 完全合作(Cooperative) 的任务。
- 环境中有 $N$ 个智能体(Agents,通常为紫色圆圈)和 $N$ 个地标(Landmarks,通常为黑色圆点)。
- 目标是让智能体通过移动,覆盖所有的地标(每个地标上至少有一个智能体)。
- 同时,智能体之间需要避免发生碰撞。
操作 (Action Space):
设置为离散动作空间 (continuous_actions=False) 时,每个智能体的动作空间大小为 5:
- 0: 什么都不做 (No-op)
- 1: 向左移动 (Move Left)
- 2: 向右移动 (Move Right)
- 3: 向下移动 (Move Down)
- 4: 向上移动 (Move Up)
对应状态向量 (Observation Space)
对于环境中的每一个智能体 $i$,其观测向量 $o_i$ 包含了自己的物理状态以及与其他物体(地标、队友)的相对位置信息。
假设有 $N$ 个智能体和 $N$ 个地标,单个智能体的观测向量结构如下:
$$
o_i = \left[
\begin{aligned}
v_x, v_y \\
p_x, p_y \\
l_{1x}, l_{1y} \\
\vdots \\
l_{Nx}, l_{Ny} \\
a_{1x}, a_{1y} \\
\vdots \\
a_{kx}, a_{ky}
\end{aligned}
\right]
$$
- $v_x, v_y$ : 智能体自身的在 x, y 轴上的速度 (2维)
- $p_x, p_y$ : 智能体自身的在 x, y 轴上的绝对位置 (2维)
- $l_{jx}, l_{jy}$ : 所有地标相对于该智能体的相对位置向量 ( $N \times 2$ 维)
- $a_{kx}, a_{ky}$ : 其他队友相对于该智能体的相对位置向量 ( $(N-1) \times 2$ 维)
- (通讯位): 在某些配置下可能包含其他智能体的通讯信息,但在标准 simple_spread 中通常为空或不启用。
维度计算示例 (3智能体 3地标):
$2(速度) + 2(位置) + 3 \times 2(地标相对位置) + 2 \times 2(队友相对位置) = 18$ 维。
奖励函数 (Reward Function):
该环境采用全局共享奖励(所有智能体获得的奖励值是相同的),以鼓励合作。
- 覆盖奖励(距离惩罚):根据每个地标距离其最近的智能体的距离之和计算。
- $R_{cover} = -\sum\limits_{j=1}^{N} \min_{i} (\text{dist}(agent_i, landmark_j))$
- 也就是:大家要把所有坑都填上,距离坑越近,惩罚越小(分越高)。
- 碰撞惩罚:如果两个智能体发生重叠(碰撞)。
- 每次碰撞:$-1$ (该数值可能随版本微调,通常是固定的惩罚值)。
总奖励 = 覆盖奖励 + 碰撞惩罚
引入环境
下载包
PettingZoo 是 Gymnasium 的多智能体版本。
1 | |
导入
注意:多智能体通常使用 parallel_env 来支持并行训练(如 MAPPO)。
1 | |
MAPPO算法
与PPO的区别
虽然此时为多智能体环境,但此时仍然采用Actor-Critic算法作为基础,但此时两个网络的功能如下:
Actor: 输入局部信息,输出对应的动作(即对于每个智能体,均使用该网络对动作进行预测)Critic: 输入全局信息(即所有智能体的状态集合),输出预测价值
激活函数选择
对于ReLu激活函数而言,一旦出现负数,那么输出为0,同时梯度也为0,那么在强化学习中可能会导致智能体在环境中的某些区域停止学习或无法探索新的动作,导致策略陷入局部最优解甚至是崩溃。
而Tanh 的优势为:虽然 Tanh 在饱和区(极值)梯度也会变小,但它处处可导且几乎不会完全“死掉”(除非数值溢出),这保证了梯度的持续流动。
因此这里选择Tanh激活函数。
改进GAE
前面使用的GAE将两种结束直接通过或运算计算得到的值作为done值的选择,但是对于模型而言,正常到达回合上限的操作往往是较好的行动,而此时若乘上$0$将优势消除反而会告诉模型这个行为一文不值,就可能会导致模型最终无法收敛。
因此,这里额外传入terminations作为结束标志,用于更准确的计算得到优势。
代码如下:
1 | |
损失函数 (Loss Function)
在 train 函数中,MAPPO 的核心优化逻辑与 PPO 保持一致,但在 Critic 的输入上体现了“中心化训练”的特点(使用 global_obs)。损失函数主要由Actor 损失(策略梯度+剪切)、Critic 损失(价值预测误差)以及熵正则项三部分组成。
1. 数学公式
Actor 总损失:
$$L_{Actor} = - \left[ \underbrace{\min(r_t(\theta)\hat{A}t, \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon)\hat{A}t)}{\text{PPO Clip 策略梯度}} + \underbrace{c_2 \cdot H(\pi_\theta(s_t))}{\text{熵正则项 (Entropy Bonus)}} \right]$$
Critic 总损失:
$$L_{Critic} = c_1 \cdot \underbrace{(V_\phi(s_{global}) - R_{target})^2}_{\text{均方误差 (MSE)}}$$
其中:
- $\hat{A}_t$ 是优势函数 (GAE)。
- $H(\pi)$ 是策略的熵,用于鼓励探索。
- $V_\phi$ 是 Critic 网络对全局状态价值的预测。
MAPPO类
MAPPO的总体操作与PPO类似,但要注意此时数据的维度调整。
1 | |
数据收集以及训练
simple-spread包含顺序模式以及并行模式,区别就是对于每个智能体的状态以及动作选择是否统一进行,并行就是统一获取所有智能体的状态,同时返回动作要将所有智能体的动作一次性告诉环境。
这里选择并行模式,因此收到的数据以及返回的动作都是字典格式的,需要进行转换。
1 | |
训练结果
经过3000轮训练后,模型表现均值收敛在$-10$左右。
