MAPPO动作类型改进(二)——MAPPO+连续环境


在上一篇博客中,作者给各位学者说明如何实现 基于最新版代码+离散环境,这篇文章帮大家实现 基于最新版代码+连续环境,示例环境仍然是用MPE类,
环境说明及地址https://pettingzoo.farama.org/environments/mpe/simple_spread/

第一步:设置连续环境模式

由于最新版light_mappo的代码默认就是使用连续环境,因此确认下是使用ContinuousActionEnv就行,原始代码是这样的话就不用动。

def make_train_env(all_args):
    def get_env_fn(rank):
        def init_env():
            # TODO 注意注意,这里选择连续还是离散可以选择注释上面两行,或者下面两行。
            # TODO Important, here you can choose continuous or discrete action space by uncommenting the above two lines or the below two lines.

            from envs.env_continuous import ContinuousActionEnv

            env = ContinuousActionEnv()

            # from envs.env_discrete import DiscreteActionEnv

            # env = DiscreteActionEnv()

            env.seed(all_args.seed + rank * 1000)
            return env

        return init_env

    return DummyVecEnv([get_env_fn(i) for i in range(all_args.n_rollout_threads)])

第二步:接入连续环境

import numpy as np
from pettingzoo.mpe import simple_spread_v3

class EnvCore(object):
    """
    # 环境中的智能体
    """

    def __init__(self):
        self.env = simple_spread_v3.parallel_env(render_mode="human", N=3, local_ratio=0.5, max_cycles=30,
                                            continuous_actions=True)
        #智能体个数N=3,
        # local_ratio:适用于本地奖励和全球奖励的权重。全局奖励权重将始终为 1 - 本地奖励权重。
        # max_cycles:游戏终止前的帧数(每个代理一个步骤)
        # continuous_actions:代理操作空间是离散的(默认)还是连续的
        self.agent_num = 3  #环境simple_spread_v3中Agents = 3 = N
        self.obs_dim = 18  #环境simple_spread_v3中Observation Shape = 18
        self.action_dim =5  #环境simple_spread_v3中Action Shape = 5

    def reset(self):
        """
        # 重置环境,simple_spread_v3环境自带了reset函数,可直接使用
        """
        sub_agent_obs = []
        observations, infos = self.env.reset()
        for agent in self.env.agents:
            sub_agent_obs.append(observations[agent])


        return sub_agent_obs

    def step(self, actions):

        sub_agent_obs = []
        sub_agent_reward = []
        sub_agent_done = []
        sub_agent_info = []

        i = 0  # 初始化计数器
        actions_step = {}  # 创建一个空字典来存储动作
        # 假设env.agents是一个包含所有智能体的列表
        # 并且actions是一个包含所有动作的列表
        for agent in self.env.agents:
            if i < len(actions):  # 确保不会超出actions列表的索引范围
                actions_step[agent] = actions[i] # 将智能体映射到对应的动作
                i += 1  # 递增计数器

        observations, rewards, terminations, truncations, infos = self.env.step(actions_step)
        for agent in self.env.agents:
            # 添加观察值
            sub_agent_obs.append(observations[agent])
            # 添加奖励
            sub_agent_reward.append([rewards[agent]])  # 注意:确保rewards[agent]是单个值或一维数组
            # 添加终止标志
            sub_agent_done.append(terminations[agent])
            # 添加附加信息
            sub_agent_info.append(infos[agent])
        # return [observations, rewards, terminations, infos]
        return [sub_agent_obs, sub_agent_reward, sub_agent_done, sub_agent_info]

第三步:改下config.py中episode_length

由于环境中max_cycles=30,因此必须满足episode_length<30才不会报错,如果设置为30,则会报错:ValueError: need at least one array to stack

   parser.add_argument("--episode_length", type=int, default=25, help="Max length for any episode")

注意事项

self.warmup():env_runner中的self.warmup()函数放在episode循环里面还是外面,这个自定吧 (由于这个环境运行了max_cycles后,不reset的话再传入动作会报错,所以这里要放到episode里面,接入自己环境时自定) 这里不放的话可能会报错:ValueError: need at least one array to stack
关于生成的动作越限的问题:许多学者在env_continuous文件中定义了动作值的上下限,但生成的动作仍存在超过low和high的情况,这是由于网络输出并未基于环境的限制做缩放。

u_action_space = spaces.Box(
                low=-np.inf,
                high=+np.inf,
                shape=(self.signal_action_dim,),
                dtype=np.float32,
            )

解决办法:
在act.py的初始化添加self.sigmoid = nn.Sigmoid()
注:环境的标准动作是在(0,1)之间,所以用的sigmoid,如果想要动作在(-1,1)之间,额可以用self.tanh = nn.Tanh()

    def __init__(self, action_space, inputs_dim, use_orthogonal, gain):
        super(ACTLayer, self).__init__()
        self.mixed_action = False
        self.multi_discrete = False
        self.continuous_action = False
        self.sigmoid = nn.Sigmoid()
  elif self.continuous_action:
            action_logit = self.action_out(x)
            actions = action_logit.mode() if deterministic else action_logit.sample()
            action_log_probs = action_logit.log_probs(actions)
            actions = self.sigmoid(actions)

结语

以上改进都来自个人经验,正确性还有需要结合具体环境验证,如有错误,欢迎指正
同时大家有疑问可评论留言,如 想要已经改好的代码可联系本人(可提供指导),邮箱2360278536@qq.com
对MAPPO算法代码总体流程不太了解,可以参考多智能体强化学习MAPPO源代码解读
对MAPPO算法理论知识不太了解,可以参考多智能体强化学习之MAPPO理论解读多智能体强化学习(二) MAPPO算法详解
MAPPO+离散环境讲解

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值