快速上手PettingZoo——多智能体环境PettingZoo与单智能体环境Gym的区别解读

多智能体的训练起点——环境PettingZoo与环境Gym的区别解读

Gym是由OpenAI开发的一套单智能体环境,现在我们尝试上手多智能体环境PettingZoo,由于Gym和PettingZoo很像,那我们用Gym的思路快速掌握PettingZoo的相关知识,通过快速捕捉多智能体环境PettingZoo和Gym的区别以类比学习PettingZoo。

PettingZoo在支持方面和Gym还是有区别的,比如PettingZoo只支持Python≥3.8,也不完全支持Windows(某些环境不支持)

一.Gym环境的主要组成部件

我们先看一个单智能体在Gym环境下做了什么

  • 环境定义
 env = gym.make(env_name) #创建指定env_name的环境,如:CartPole-v0
  • 初始化环境/重置环境
state = env.reset() #获得s_0
  • 获取动作,这一步是智能体操作,虽然和环境没什么关系,但是很重要
action = agent.take_action(state) #我们定义智能体agent实现策略take_action方法
  • 更新环境(获得下一个状态,给出终止或者截断)
next_state,reward,terminated,truncated,info = env.step(state)#gym>0.21以后有五个返回值

terminated(终止,bool):在该MDP任务的结束与否标记,智能体到终止状态与否的标记

truncated(截断,bool):在该场景下非MDP任务的结束有否标记,触发条件可能是是否达到时间长度限制,或者智能体中途死了(如在悬崖漫步里,掉下悬崖了等情况),这些情况虽然智能体还没有达到终止状态,但是整个序列已经不得不结束了。

在比较简单的场景下,可能我们没有定义智能体会死亡或者有时间限制,我们只关注是否到达MDP的终止条件,此时可以写成:

next_state,reward,done, _ ,_ = env.step(state) #最后两个用不到,用 _ 省略标记,done表示终止

当结束一轮后,调用env.reset(),重新开始
我们可以写出Gym下训练的基本框架

#假设只训练一条轨迹
  from pettingzoo.butterfly import pistonball_v6
env = gym.make()
state = env.reset()
agent = DQN(...) #我们需要显式定义模型
done = False
while not done:
	action = agent.take_action(state)
	next_state, reward, done, _ , _ = env.step(action)
	#...
env.close()

二.PettingZoo环境的主要组成部件

PettingZoo力求了Gym相近,尽可能保证API相似,但是由于多智能体的特点,还是有不同。

面对多个智能体的情况,MARL在更新方式上将博弈的顺序分为两种情况:

  • 拓展式博弈:每一个智能体先后行动,对应PettingZoo下的AEC

  • 标准型博弈:所有智能体同时行动,对应PettingZoo下的Parallel

    从更新的区别上,下面开始介绍PettingZoo与Gym的不同点:

拓展式博弈

AEC环境中,智能体按照顺序行动,并在采取行动之前接受更新的观察结果和奖励,每个代理执行完一步后即更新一次环境,可表示连续游戏的自然方式

  • 环境定义
  from pettingzoo.butterfly import pistonball_v6
  env = pistonball_v6.env() #PettingZoo直接导入一个具体环境,通过env方法实例化
  • 初始化方式

使用env.reset()方法初始化环境,作为新一轮训练的开始,没有返回值

env.reset() #注意,AEC中reset没有返回值,与Parallel区别
  • 统计方式:

    我们对每个智能体操作进行计数,使用env.agent_iter(max_iter=2**63)迭代器,迭代产生环境的当前代理,当环境所有代理均完成或者达到max_iter,终止。

明显在PettingZoo的拓展式博弈中,我们计数当前智能体行动一次即环境的更新,而不是所有的智能体行动一次为环境的更新,可以使用agent_iter自动统计智能体执行行动总次数。

  • env.step(action):执行当前智能体的操作,并自动将控制权转交给下一个智能体,没有返回值

执行当前环境下该指定行动的智能体的操作,等同于更新环境

  • env.last(observe=True):AEC特有操作,获取当前正采取行动智能体的信息。若observe=False则不会计算观测值,而是用None替代,当单个智能体完成时环境没有结束
    • observation:包含当前智能体最新观察
    • reward:包含当前智能体在上一个时间步的奖励。
    • termination:包含当前智能体是否终止的标记
    • truncation: 包含当前智能体是否截断的标记。
    • info: 额外信息

因此,在AEC中可以写出如下基本训练框架:

from pettingzoo.butterfly import cooperative_pong_v5

env = cooperative_pong_v5.env(render_mode="human")
env.reset(seed=42)

for agent in env.agent_iter():
    observation, reward, termination, truncation, info = env.last()

    if termination or truncation:
        action = None
    else:
        # this is where you would insert your policy
        action = env.action_space(agent).sample() #可以自行定义策略,决定当前智能体的动作

    env.step(action)
env.close()

标准型博弈

Parallel中,智能体同时执行动作,对于一个可支持并行运行的环境

  • 环境定义
  from pettingzoo.butterfly import pistonball_v6
  parallel_env = pistonball_v6.parallel_env()
  • 初始化方式

使用parallel_env.reset()方法初始化环境,此时将返回所有智能体的初始观察空间和信息

observaions,infos = parallel_env.reset() #AEC可以用last获得单个智能体的观察空间,而Parrllel是用reset返回所有智能体的初始观察空间
  • 统计方式:我们对当前环境所有智能体执行一次操作后进行计数,使用env.agents方法统计当前环境还有多少智能体存活,若为空表示所有智能体都执行结束了
while parallel_env.agents:
    #parallel_env.action_space(agent).sample() 可以改成自己的智能体策略
    actions = {agent:parallel_env.action_space(agent).sample() for agents in parallel_env.agents }
  • env.step(action):输入所有智能体动作的字典,一次性所有智能体更新操作操作,返回所有智能体的观察空间,奖励,截断,结束,信息
 observations, rewards, terminations, truncations, infos = parallel_env.step(actions)

因此,在Parallel中可以写出如下基本训练框架:

from pettingzoo.butterfly import pistonball_v6
parallel_env = pistonball_v6.parallel_env(render_mode="human")
observations, infos = parallel_env.reset(seed=42)

while parallel_env.agents:
    # this is where you would insert your policy
    actions = {agent: parallel_env.action_space(agent).sample() for agent in parallel_env.agents}

    observations, rewards, terminations, truncations, infos = parallel_env.step(actions)
parallel_env.close()

三、总结与画饼

可以看出,PettingZoo的Parallel形式和Gym更加类似,需要注意

  • reset(),step()方法返回的都是所有智能体的字典形式
  • step()方法要求输入的也是所有智能体actions的字典形式,所有要注意用for循环访问env.agents获取动作字典

对于AEC形式,要利用agent_iter指向当前智能体和last方法

  • reset(),step()方法没有返回值
  • 使用last()方法获取当前智能体各种信息

画饼:之后会讲解——在PettingZoo中agent在访问环境就获得了,我们不能像Gym一样实例化一个智能体,再去该类中编写它的策略。那我们应该如何在PettingZoo中编写策略呢。

  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值