【动手学强化学习】番外6-MAPPO应用框架学习


一、待解决问题

1.1 问题描述

由于有自建环境的需求,但想使用MAPPO的算法,但MAPPO benchmark没有可以直接应用的框架,因此在网上参考学习。

1.2 解决方法

(1)下载light_mappo 源码
(2)light_mappo 框架实际应用
(3)light_mappo 代码解析

二、方法详述

2.1 必要说明

MAPPO 框架讲解参考链接:多智能体强化学习(二) MAPPO算法详解
MAPPO 框架讲解(视频)参考链接:MAPPO的代码框架解析
light_mappo 源码链接: github/ tinyzqh /light_mappo

✅非常感谢大佬的分享!!!

2.2 应用步骤

2.2.1 下载light_mappo 源码

根据源码链接下载对应源码,得到目录如下:
在这里插入图片描述首先查看对应README_CN.md说明

## 背景

MAPPO原版代码对于环境的封装过于复杂,本项目直接将环境封装抽取出来。更加方便将MAPPO代码移植到自己的项目上。

## 安装

直接将代码下载下来,创建一个Conda环境,然后运行代码,缺啥补啥包。具体什么包以后再添加。

## 用法

- 环境部分是一个空的的实现,文件`light_mappo/envs/env_core.py`里面环境部分的实现:[Code](https://github.com/tinyzqh/light_mappo/blob/main/envs/env_core.py)

import numpy as np
class EnvCore(object):
    """
    # 环境中的智能体
    """
    def __init__(self):
        self.agent_num = 2  # 设置智能体(小飞机)的个数,这里设置为两个
        self.obs_dim = 14  # 设置智能体的观测维度
        self.action_dim = 5  # 设置智能体的动作维度,这里假定为一个五个维度的

    def reset(self):
        """
        # self.agent_num设定为2个智能体时,返回值为一个list,每个list里面为一个shape = (self.obs_dim, )的观测数据
        """
        sub_agent_obs = []
        for i in range(self.agent_num):
            sub_obs = np.random.random(size=(14, ))
            sub_agent_obs.append(sub_obs)
        return sub_agent_obs

    def step(self, actions):
        """
        # self.agent_num设定为2个智能体时,actions的输入为一个2纬的list,每个list里面为一个shape = (self.action_dim, )的动作数据
        # 默认参数情况下,输入为一个list,里面含有两个元素,因为动作维度为5,所里每个元素shape = (5, )
        """
        sub_agent_obs = []
        sub_agent_reward = []
        sub_agent_done = []
        sub_agent_info = []
        for i in range(self.agent_num):
            sub_agent_obs.append(np.random.random(size=(14,)))
            sub_agent_reward.append([np.random.rand()])
            sub_agent_done.append(False)
            sub_agent_info.append({})

        return [sub_agent_obs, sub_agent_reward, sub_agent_done, sub_agent_info]



只需要编写这一部分的代码,就可以无缝衔接MAPPO。在env_core.py之后,单独提出来了两个文件env_discrete.py和env_continuous.py这两个文件用于封装处理动作空间和离散动作空间。在algorithms/utils/act.py中elif self.continuous_action:这个判断逻辑也是用来处理连续动作空间的。和runner/shared/env_runner.py部分的# TODO 这里改造成自己环境需要的形式即可都是用来处理连续动作空间的。

在train.py文件里面,选择注释连续环境,或者离散环境进行demo环境的切换。

核心点总结:

(1)直接下载源码后,创建conda虚拟环境,并运行light_mappo-main/train/train.py可直接调用mappo算法,缺少什么包安装什么依赖;
(2)该框架已经把mappo benchmark中的env环境的代码抽离了出来,可以在light_mappo/envs/env_core.py源码上修改为自己的env环境

2.2.3 light_mappo 框架实际应用

主要参考:强化学习-MAPPO算法解析与实践-Multi Agent Proximal Policy Optimization

✅非常感谢大佬的分享!!!

(1)安装ma-gym环境

该实例直接应用了ma_gym当中的Combat环境,因此首先安装ma-gym多智能体环境,具体安装步骤及Combat可参考:
【动手学强化学习】番外7-MAPPO应用框架2学习与复现

(2)更改环境代码

light_mappoenv_core.py的环境代码修改为如下:

import time
 
import numpy as np
 
from ma_gym.envs.combat.combat import Combat
class EnvCore(object):
    """
    # 环境中的智能体
    """
 
    def __init__(self):
        self.agent_num = 2  
        team_size = self.agent_num
        grid_size = (15, 15)
        self.env = Combat(grid_shape=grid_size, n_agents=team_size, n_opponents=team_size)
        self.obs_dim = 150  # 设置智能体的观测维度 # set the observation dimension of agents
        self.action_dim = self.env.action_space[0].n  # 设置智能体的动作维度,这里假定为一个五个维度的 # set the action dimension of agents, here set to a five-dimensional
 
    def reset(self):
 
 
        s = self.env.reset()
    
        sub_agent_obs = []
        for i in range(self.agent_num):
            sub_obs = np.array(s[i])#np.random.random(size=(14,))
            sub_agent_obs.append(sub_obs)
        return sub_agent_obs
 
    def step(self, actions):
      
        self.env.render("human")
        time.sleep(0.4)
        sub_agent_obs = []
        sub_agent_reward = []
        sub_agent_done = []
        sub_agent_info = []
        action_index = [int(np.where(act==1)[0][0]) for act in actions]
        next_s, r, done, info = self.env.step(action_index)
        for i in range(self.agent_num):
            # r[agent_i] + 100 if info['win'] else r[agent_i] - 0.1
            sub_agent_obs.append(np.array(next_s[i]))
            # sub_agent_reward.append([r[i] + 100 if info['winners'] else r[i] - 0.1])
            sub_agent_reward.append(r[i])
            sub_agent_done.append(done[i])
            sub_agent_info.append(info)
 
        return [sub_agent_obs, sub_agent_reward, sub_agent_done, sub_agent_info]
(3)解决报错

首次运行,关键报错如下:

libGL error: MESA-LOADER: failed to open iris:
libGL error: MESA-LOADER: failed to open swrast
version `GLIBCXX_3.4.30’ not found
ContextException: Could not create GL context

从报错信息来看,询问大模型,大概率是加载 OpenGL 驱动时遇到了问题,特别是 iris 和 swrast 驱动。并且发现缺少 GLIBCXX_3.4.30,可以尝试升级 libstdc++ 库,这一步骤可参考:
【动手学强化学习】番外5-MPE(Multi-agent Particle-World Environment)多智能体仿真环境介绍

大致过程总结如下:

#安装或更新 MESA 驱动
sudo apt-get install mesa-utils
sudo apt-get install mesa-opencl-icd

#排查当前conda环境是否缺失GLIBCXX_3.4.30,XXXX改为自己的用户名
strings /home/XXXX/anaconda3/envs/simple_mappo/lib/libstdc++.so.6 | grep GLIBCXX

#若缺失GLIBCXX_3.4.30的话,更新libstdcxx-ng版本,,无缺失即可省略
#查询当前libstdcxx-ng版本
conda list | grep libstdcxx-ng
#直接通过默认源是无法升级安装libstdcxx-ng的,需要先添加conda-forge源
conda config --add channels conda-forge
#可以执行以下命令来查看下载源
conda config --show channels
conda install libstdcxx-ng=12.1.0
conda list | grep libstdcxx-ng
#升级完成之后再查询 GLIBCXX 版本
strings /home/XXXX/anaconda3/envs/simple_mappo/lib/libstdc++.so.6 | grep GLIBCXX

#如果 iris_dri.so 和 swrast_dri.so 文件存在于 /usr/lib/x86_64-linux-gnu/dri 目录下,但系统无法找到它们,可以尝试创建软链接
cd /usr/lib
#创建文件夹
sudo mkdir ./dri
#创建iris_dri.so文件软链接
sudo ln -s /usr/lib/x86_64-linux-gnu/dri/iris_dri.so /usr/lib/dri/
#创建swrast_dri.so文件软链接
sudo ln -s /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so /usr/lib/dri/
cd dri
ls

#记得删除conda-forge镜像源
conda config --remove channels conda-forge
rm ~/.condarc
conda config --add channels defaults
conda config --set show_channel_urls yes
#测试源是否删除(安装一个仅有conda-forge有的包)
conda install libstdcxx-ng=12.2.0

能够成功运行,但是到第5步依然会报错:
在这里插入图片描述

File ~/code/light_mappo-main/utils/separated_buffer.py:70, in SeparatedReplayBuffer.insert(self, share_obs, obs, rnn_states, rnn_states_critic, actions, action_log_probs, value_preds, rewards, masks, bad_masks, active_masks, available_actions)
68 self.action_log_probs[self.step] = action_log_probs.copy()
69 self.value_preds[self.step] = value_preds.copy()
—> 70 self.rewards[self.step] = rewards.copy()
71 self.masks[self.step + 1] = masks.copy()
72 if bad_masks is not None:

ValueError: could not broadcast input array from shape (5,) into shape (5,1)

总体感觉,方法之间封装太多层了,不好调试。

2.2.2 light_mappo 代码解析

后续补充

三、疑问

暂无。

四、总结

  • light_mappo 框架直接基于原文献MAPPO的框架上将环境独立了出来,但是原框架内容还是比较繁琐,封装了很多层,不如人直接理解PPO原理,然后直接在PPO算法的框架下,设计centralized_V,即全局中心化critic网络,直接就应用为MAPPO算法;若每个agent采用自身的critic网络,即为IPPO算法。
  • 在agent类型上,可考虑shared policyseparated policy以确定同质异质智能体,其本质上就是多agent使用一个policy网络和还是分别是用各自的policy网络。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值