项目分享 | 昇思MindSpore接入强化学习的新环境和新算法

作者:****严可熙, 景煜恒, 刘志豪, 丰效坤, 雷世骐-**中国科学院自动化研究所

摘要

本次强化学习实验,我们小组选择的题目为“昇思MindSpore 接入强化学习的新环境/新算法”。我们将一个面向多智能体合作场景的游戏测试环境——SISL(Stanford Intelligent Systems Laboratory)接入到昇思MindSpore平台,并实现了QMIX和MAPPO算法对此实验环境的性能基准测试。本次分享,我们将围绕选题、环境、算法、实验结果和结论这5个方面来进行相应的介绍和分析。

 

项目相关代码详见附件。

https://gitee.com/lemonifolds/reinforcement/tree/c03e5f8e6104b5880fdfa53d579332078c7dfb99

01

选题介绍

强化学习是一门研究序列决策的学科,其通过分析智能体与环境的交互过程,来学习优化策略以使得累计回报最大。其中,环境是强化学习中的重要要素,其不仅直接决定了算法模型的输入数据格式,还与强化学习的研究任务紧密相关。一些经典的强化学习算法,往往伴随而来的是一些经典的验证环境。例如,对于单智能体感知决策任务,其经典算法DQN(Deep Q-learning)[1] 是在此任务经典的环境Atari游戏中验证的;对于完全信息零和博弈任务、以及非完全信息多人混合博弈任务,其代表性工作AlphaGo[2][3]、AlphaStar[4]更是将相应的验证环境(Go, StarCraft)来为算法命名。由此可见验证环境在强化学习领域中的重要作用。

强化学习使用的环境种类繁多,典型的环境有Gym[5]、MuJoCo[6]、MPE[7]、 Atari[1]、PySC2[8]、SMAC[9]、TORCS、ISAAC等。目前昇思MindSpore架构上已接入了 Gym、SMAC (StarCraft Multi-Agent Challenge) 两个环境,分别面向了单智能体强化学习以及多智能强化学习场景。对于后者,由于星际争霸游戏复杂高维的状态、动作和决策空间,使其成为多智能体强化学习算法的重要挑战基准。然而,在实际科研实践中,当我们提出一个新的算法时,我们往往会先在一些小型的环境中(如Gym中的Atari游戏环境)进行验证。基于此,我们小组选择了一个面向多智能体场景的小型测试环境——SISL(Stanford Intelligent Systems Laboratory),并将其接入到了昇思MindSpore平台,为该平台提供更多样化的多智能体验证环境。除此之外,我们还针对SISL环境,将MAPPO[10]和QMIX[[11]这两个典型的多智能体强化学习算法进行了实现,并提供了相应的基准测试结果。

接下来,本次分享先针对所接入的SISL环境(第2章节),以及所使用到的QMIX和MAPPO算法(第3章节)进行初步的介绍;然后,将环境接入的实现过程,实验得到的基准测试结果以及实验中所遇到的问题进行展示和分析(第4章节);最后,根据实验结果,我们给出相应的结论(第5章节)。

02

环境简介

PettingZoo[12]是一个多智能体强化学习研究中常用的Python库,SISL(Stanford Intelligent Systems Laboratory)是其中的一个环境包,包含了3个子环境:Multiwalker、Pursuit和Waterworld。

PettingZoo的基本使用方式和Gym比较相似,下面是一个在Waterworld环境中构建一个随机行动的agent的代码示例:

from pettingzoo.sisl import waterworld_v4
env = waterworld_v4.env(render_mode='human')

env.reset()
for agent in env.agent_iter():
    observation, reward, termination, truncation, info = env.last()
    if termination or truncation:
        action = None
    else:
        action = env.action_space(agent).sample()
    env.step(action)
env.close()

下面针对SISL中的三个子环境,进行展开介绍

2.1Multiwalker

在Multiwalker环境中,双足机器人试图扛起它们身上的货物向右走。几个机器人扛起一个大货物,它们需要通力合作,如下图所示。

图片Multiwalker环境示意图

每个agent都会收到包裹和前一个时间点相比位置的变化乘以forward_reward的收益。如果包裹掉落、包裹超过地形的左边界两者至少有一个发生,则环境结束,每个agent获得-100的收益。如果包裹从地形的右边界掉落,环境也会结束,获得0的收益。

如果一个agent摔倒,它额外获得-10的收益。如果 terminate_on_fall = False,那么环境不会在agent摔倒时终止,否则agent一旦摔倒环境就会终止,并带来-100的收益。如果 remove_on_fall = True,那么摔倒的agent会从环境中被移除。各个agent同时还会收到-5乘以头部角度改变量来保持头部水平。如果shared_reward = True,那么每个agent的个人收益被平均后返回给每个agent。

每个agent在起两条腿的两个关节施加力,因此其连续动作空间为4维向量。每个agent的观测空间为包含有噪声的关于环境和周围agent的雷达数据、自己身体各个关节的角度和速度等信息在内的31维向量。

2.2 Pursuit

在Pursuit环境中,一些追逐者agent试图追赶并包围逃离者,如下图所示(红色为受控制的追逐者agent,蓝色为随机运动的逃离者)。

图片

Pursuit环境示意图

默认条件下,在16X16的网格中有30个逃离者和8个追逐者agent,地图中央有一个障碍物(白色部分)。如果agent完全包围了一个逃离者,则每个包围的agent获得5的收益,且逃离者被移出环境。每次agent触碰到一个逃离者也会获得0.01的收益。

每个agent都有着离散动作空间:向上、向下、向左、向右、停止。每个agent的观测空间为其周围7X7的网格,在图中以橘色表示。

2.3 Waterworld

Waterworld环境模拟了古细菌试图在环境中生存的状况。各个agent要试着消费食物并避开毒素,如下图所示。

图片

Waterworld环境示意图

根据输入的参数,各个agent可能需要合作来消费食物,因此这个模型可能同时是合作的和竞争的。同样,收益也可以是各个agent不同的或者平均化的。整个环境是一个连续的二维空间,收益根据食物和毒素的接触情况而定。

每个agent的动作空间为2维向量,即水平方向和竖直方向的推进(加速度)。每个agent的观测空间为各个传感器收到的与食物、毒素、其它agent的距离等信息,以及是否与食物或毒素碰撞,总维数为图片图片,因参数而定。

03

算法介绍

本小节,来对实验中所使用到的MAPPO[10]算法和QMIX[11]算法进行展开介绍。

3.1 MAPPO算法

MAPPO的全称为 Multi-Agent Proximal Policy Optimization,由名字可知,MAPPO算法是经典强化学习算法——PPO[13]算法,在多智能环境下扩展。对于多智能体环境,其常使用<图片>七元组来进行描述。其中,n表示智能体的数量;S表示环境的状态空间;图片是由所有智能体的动作所构成的行为空间;图片表示智能体i从全局状态s下所获得的局部观察(如果是完全可观察的环境,则图片);图片表示在给定联合动作的情况下,由s转化为s'的概率;R(s,A)表示共享的奖励函数;图片表示折扣因子。

MAPPO算法使用了经典的actor-critic结构,也即需要训练了两个分离的神经网络:策略网络图片和值函数图片(分别作为actor和critic)。

对于策略网络图片,其用于学习一个从观察o_i到动作分布a_i的映射,对应的优化目标为:

图片

其中,B表示batch size的大小,图片使用GAE[14]方法来计算,图片表示策略熵,图片表示权重系数超参数。

对于值函数图片,其用于学习从状态S到奖励估计值图片的映射,对应的优化目标为:

图片

其中,图片表示计算得到的折扣回报。由于MAPPO采用集中训练分散执行的训练方式,所以值函数可以直接对全局状态图片进行除了;而策略函数只能对各个智能体的局部观察信息图片进行处理。

基于上述优化目标公式,便可以得到MAPPO的运算流程,将原文[10]中提供的 循环MAPPO算法的处理流程整理如下:

图片

3.1 MAPPO算法

在这一小节中,使用u表示动作,而图片表示动作-观测历史。QMIX算法的设计思路类似VDN,希望可以通过计算一个全局的图片来得到每个图片。只需要

图片

即可满足要求。为了使上式成立,图片关于Q_i应有单调性,即

图片

QMIX的神经网络结构如下图所示:图片QMIX框架图

对每个智能体i,都有一个智能体网络用来计算其图片,如图(c)所示。该网络为DRQN网络,即将DQN中的全连接层替换为GRU,输入为智能体t时刻的观察图片和t-1时刻的动作图片

混合网络为一个前馈神经网络,它接收智能体网络的n个输出并将其单调地混合,输出图片作为结果,如图(a)所示。混合网络的权值由单独的超网络产生,超网络以全局状态s_t作为输入,生成一层混合网络的权值。每个超网络由一个单一的线性层组成,同时有一个绝对值激活函数,确保混合网络的权值是非负的。

QMIX网络是端到端训练的,最小化下面的loss:

图片

其中,图片图片为目标网络(类似DQN中的)的参数。

04

实验结果

本节基于上述关于SISL环境,以及MAPPO和QMIX算法的介绍,开展具体的实验分析。首先,我们对SISL环境的接入过程进行介绍(4.1节);然后,我们在MindSporeRL原始仓库中提供的MAPPO和QMIX算法的基础之上,经过修改和调整之后,尝试将其在新接入的SISL环境中完成基准测试实验(4.2和4.3节);我们将相应的工程改进要点、实验结果与思考进行展示和介绍。

4.1 SISL环境接入流程

我们使用pip install pettingzoo[sisl] 命令对SISL的基本环境库进行安装,当然,也可以通过下面的方法本地安装该基本环境:

cd ~/reinforcement/mindspore_rl/environment
git clone https://github.com/Farama-Foundation/PettingZoo.git
cd PettingZoo
pip install -e .[sisl]

在该基本环境的基础上,我们按照MindSpore Reinforcement对其已有环境的封装模式对SISL进行封装,具体代码实现见sisl_environment.py。

SISL环境的Wrapper类主要继承了下面的类:

from mindspore_rl.environment import Environment

为了兼容的MindSpore Reinforcement和MindSpore的训练框架,我们在SISL环境的Wrapper类中继承或者使用了下面的数据结构:

import mindspore as ms
from mindspore.ops import operations as P
from mindspore_rl.environment.space import Space

在观察过MindSpore Reinforcement的代码框架之后,我们发现不同的算法只针对特定的环境进行了适配,所有的环境和算法都不具有通用性。例如,MAPPO算法只适配了MPE环境,因此该算法只支持连续的向量形式的状态空间、离散的动作空间,而且由于MPE环境的实现使用了多进程,故MAPPO算法也为其多进程进行了专门化的适配。又例如,QMIX算法只适配了SMAC环境,因此该算法只支持连续的向量形式的状态空间、离散的动作空间,而SMAC环境是单进程,故QMIX算法只适用于单进程。因此,MindSpore Reinforcement已有的算法不能通用地支持离散、连续的状态或动作空间,且状态空间一般只适合向量形式,针对其他形式的输入例如图像,需要额外实现CNN等相关的骨干网络。另外,接入的环境也需要根据算法的单进程或多进程实现进行特定的适配。

为了适配QMIX算法,我们实现SISL环境的单进程版本Wrapper类SISLEnvironment,并按照MindSpore Reinforcement的封装格式对环境的所有API进行封装。

为了适配MAPPO算法,我们实现SISL环境的多进程版本Wrapper类SISLMultiEnvironment,额外基于Python的multiprocessing库实现多进程调度类EnvironmentProcessNew,并按照MindSpore Reinforcement的封装格式对环境的所有API进行封装。

4.2 MAPPO算法基准测试实验

reinforcement_MAPPO
├─ example
│  ├─ make_plot.py
│  ├─ scripts
│  │  ├─ mappo_train_log.txt
│  │  └─ run_standalone_train.sh
│  └─ train_SISL.py
└─ mindspore_rl
   ├─ algorithm
   │  ├─ config.py
   │  ├─ config_SISL.py
   │  ├─ mappo.py
   │  ├─ mappo_replaybuffer.py
   │  ├─ mappo_session.py
   │  ├─ mappo_trainer.py
   │  ├─ mappo_vmap.py
   │  ├─ mappo_vmap_trainer.py
   │  ├─ mpe
   │  ├─ mpe_environment.patch
   │  ├─ mpe_environment.py
   │  ├─ on-policy
   │  ├─ sisl_environment.py
   │  └─ __init__.py
   └─ environment
      └─ sisl_environment.py

MAPPO算法实现的SISL环境代码树

MAPPO****算法与环境解耦

昇思Mindspore中MAPPO原生接入了MPE环境,并且在小组成员的尝试中,能够直接在MPE环境上运行,成功完成了与环境交互、训练、参数更新等步骤,保证了MAPPO算法代码的正确性。SISL有不同的地图作为实验环境,包含Multiwalker、Pursuit以及Waterworld,但是直接更改config.py文件后却不能成功在SISL环境上运行。在小组成员研究讨论后发现,在昇思MindSpore框架中的MAPPO实现中,MAPPO算法与环境高度耦合。如MAPPOSession.py中,所有的有关智能体数目,状态维度观测维度以及可行动作维度等与环境相关的变量都实现为了具体的数值,而非环境变量;在sisl_environment.py中同样,显式地定义了智能体数目等本应为配置参数的变量。该显式定义使得更改config.py文件无法传递到算法内部,从而在特征输入网络的接口出产生运行错误。

我们对原有的算法进行了改进,增加了与环境的解耦部分,能够使得框架正确的从config.py文件中读取对应的环境信息,并且能够正确的使用环境信息传递给算法,真正实现了环境与MAPPO算法的解耦。

MAPPO接入SISL环境****

在以上的工作完成之后,我们能够确保MAPPO算法无误,并且配置文件的参数能够正确的传递到算法内部。随后,小组成员着手开始接入SISL环境。在昇思MindSpore框架中,不同的算法对应的环境不同,对应的执行也不同。在调试的过程中,我们发现,对于多线程版本的SISL环境,不能直接更改多线程的线程数以及每个线程中存在的环境数目,直接更改进程数目或者环境数目会导致算法在某一处卡死;此外,在代码运行过程中,由于数据类型不匹配,例如不能将numpy.int32与int32也不能兼容,导致了环境转换的麻烦;从环境中返回的是动作的one-hot编码,并不能直接输入到定义的mappo网络中进行训练等问题。

在解决掉数据类型以及与环境交互问题以后,小组成员进行MAPPO在SISL环境上的训练,但是根据默认的训练代码,每次训练到19个episode后程序报错并退出。经过小组成员讨论并且逐行进行调试,根据原始的训练代码,在每次训练结束后,其中并不包含结束episode的truncation提示信息,于是在下一轮的训练开始时,会接着从上一轮环境的状态开始执行,并且上一轮环境的运行步数也不会清空。由于Pursuit环境设置有最大运行步数,运行到环境的最大执行数目后,根据环境框架,会将sisl_environment.py的run函数中所有执行到最终步骤环境的reward以及observation清空,而在run函数中并未对清空后的变量进行处理,因此在函数运行过程中,每当运行到环境规定的最大步数后,程序发生崩溃,这也是每训练19个episode后程序报错的原因。因此小组成员添加了是否达到设定最大数目的检测,若达到最大数目,则由环境发出trunction信号,终止run函数并重置环境。

在解决上述困难后,MAPPO算法已经能够在SISL环境上成功运行。设置MAPPO所需的状态信息为所有智能体observation的拼接,并最大运行500个episode,每个episode包含500个时间步,进行MAPPO在SISL环境上的实验,并绘制训练中reward以及loss的曲线。训练完成后,我们得到以下结果:

图片

4.3 QMIX算法基准测试实验

reinforcement_QMIX
├─ example
│  ├─ qmix
│  │  ├─ eval.py
│  │  ├─ scripts
│  │  │  ├─ run_standalone_eval.sh
│  │  │  └─ run_standalone_train.sh
│  │  └─ train.py
│  └─ __init__.py
└─ mindspore_rl
   ├─ algorithm
   │  ├─ qmix
   │  │  ├─ config.py
   │  │  ├─ qmix.py
   │  │  ├─ qmix_session.py
   │  │  ├─ qmix_trainer.py
   │  │  ├─ _config.py
   │  │  ├─ __init__.py
   │  └─ __init__.py
   └─ environment
      ├─ sc2_environment.py
      └─ sisl_environment.py

QMIX算法实现的SISL环境代码树

QMIX算法修正

在我们实现的过程中,发现在昇思MindSpore框架中,原有的QMIX算法及其对应的实验环境SMAC并不能运行,eval.py例程同样报错无法运行。因此,为了检验算法的正确性以及环境的可行性,我们首先修正了框架中实现的QMIX算法以及对应的环境。

由于是初次使用昇思MindSpore框架,小组同学在实验中发现框架的报错信息不明显。经过小组成员讨论合作,发现,这是由于该框架反复使用了继承和重载,以及底层计算逻辑将python语言转译为cpp的计算图进行计算,导致报错几乎相同,而框架中的debugger并不总能够返回对应的错误定位。

我们通过逐行调试发现,在实现的QMIXTrainer类中,本应返回save_reward,而错误的返回了SMAC环境中的Step_info,经过调试后,QMIX算法能够正确地在SMAC的其中一个环境中进行验证。


QMIX算法与环境解耦

 

基于小组成员之前的经验,SMAC有不同的地图作为实验环境,如昇思MindSpore中已经实现的2s3z,以及如3m,3s5z等。然而,当我们按照文档中所说的改变对应config.py文件时,原有的程序并不能直接运行。在小组成员研究讨论后发现,在昇思MindSpore框架中的QMIX实现中,QMIX算法与环境高度耦合。如QMIXTrainer中,几乎所有的有关智能体数目Agent_num,观测维度obs_shape以及可行动作维度等与环境相关的变量都实现为了具体的数值,而非环境变量。


  • 上述的evaluate()函数被训练与测试阶段复用,出现上述问题。在此将其区分开,避免功能混淆。

  • Agent_num, obs_shape等变量与环境相关,而与算法无关。增加了局部变量,按照MindSporeRL的文档进行代码重构,使得算法与环境解耦,符合框架规范。

综上, 我们通过对于框架的调试以及修正,解决了环境与算法耦合程度过高的问题,真正实现了QMIX算法与SMAC环境的解耦。我们同时将该版本的代码在原代码仓库中提交了pull request,以便框架后续使用者的方便。

在3s5z环境下,利用我们的代码测试QMIX得到如下结果:

图片

QMIX接入SISL环境

在以上的工作完成之后,我们能够确保QMIX算法无误,并且能够在对应的SMAC环境中得到相应结果。随后,小组成员着手开始接入SISL环境。如前文中所提到的, 在昇思MindSpore框架中,不同的算法对应的环境不同,对应的执行也不同。QMIX算法仅实现了单线程版本,因此与前述MAPPO环境并不互通。在调试的过程中,我们发现,对于单线程版本的SISL环境,始终无法正常运行。报错的位置难以定位,其内容为:Unable to cast Python instance to C++ type.

小组成员讨论并且逐行进行调试,发现昇思MindSpore框架由于使用了Cpp底层编译成计算图进行加速计算,因此存在python到cpp的转译过程,而该过程与传统的python运行过程有些微区别。传统的Python程序为解释型语言,程序几乎是逐行运行;而cpp作为编译型语言,需要完整编译后运行。正因如此,小组成员推测,这样的混用导致了前文中提到的上述报错不明显的问题。同时,在写程序的过程中需要时刻检查各个变量的数据类型,与传统python不同,numpy.int32与int32也不能兼容,这导致需要花大量时间去检查从环境到算法各个步骤的数据类型。

面对遇到的困难,小组同学试图通过依次检查环境与算法中各个数据的数据类型等方法进行尝试,但是始终无法定位到具体出现问题的变量以及出现问题的位置。此外,我们已经实现了多进程版本的SISL环境并且运行了MAPPO代码。小组成员讨论后的结论认为,是数据类型与它底层调用的C++的数据类型不一致导致的。而这个问题难以通过单点调试定位问题所在,需要尝试编译调试。同时,该问题与强化学习课程内容关系不大,因此,我们没有继续花时间调试实现QMIX算法在单进程的SISL环境的实现。

05

结论

本次强化学习实验作业,我们小组成功实现了将一个面向多智能体合作场景的游戏测试环境——SISL(Stanford Intelligent Systems Laboratory)接入到昇思MindSpore平台;并尝试使用QMIX和MAPPO算法对此实验环境进行了性能基准测试。完成了作业中所给定的各项要求,对昇思MindSpore的底层架构也有了更深刻的认知,这有利于我们今后更熟练地将MindSporeRL库应用到我们的科研活动中。

参考文献

[1]. Mnih V, Kavukcuoglu K, Silver D, et al. Playing atari with deep reinforcement learning[J]. arXiv preprint arXiv:1312.5602, 2013.

[2]. Silver D, Huang A, Maddison C J, et al. Mastering the game of Go with deep neural networks and tree search[J]. nature, 2016, 529(7587): 484-489.

[3]. Silver D, Schrittwieser J, Simonyan K, et al. Mastering the game of go without human knowledge[J]. nature, 2017, 550(7676): 354-359.

[4]. Vinyals O, Babuschkin I, Czarnecki W M, et al. Grandmaster level in StarCraft II using multi-agent reinforcement learning[J]. Nature, 2019, 575(7782): 350-354.

[5]. Brockman G, Cheung V, Pettersson L, et al. Openai gym[J]. arXiv preprint arXiv:1606.01540, 2016.

[6]. Todorov E, Erez T, Tassa Y. Mujoco: A physics engine for model-based control[C]//2012 IEEE/RSJ international conference on intelligent robots and systems. IEEE, 2012: 5026-5033.

[7]. Mordatch I, Abbeel P. Emergence of grounded compositional language in multi-agent populations[C]//Proceedings of the AAAI conference on artificial intelligence. 2018, 32(1).

[8]. Romo L, Jain M. PySC2 Reinforcement Learning[J].

[9]. Samvelyan M, Rashid T, De Witt C S, et al. The starcraft multi-agent challenge[J]. arXiv preprint arXiv:1902.04043, 2019.

[10]. Yu C, Velu A, Vinitsky E, et al. The surprising effectiveness of ppo in cooperative multi-agent games[J]. Advances in Neural Information Processing Systems, 2022, 35: 24611-24624.

[11]. Rashid T, Samvelyan M, De Witt C S, et al. Monotonic value function factorisation for deep multi-agent reinforcement learning[J]. The Journal of Machine Learning Research, 2020, 21(1): 7234-7284.

[12]. https://pettingzoo.farama.org/environments/sisl/

[13]. Schulman J, Wolski F, Dhariwal P, et al. Proximal policy optimization algorithms[J]. arXiv preprint arXiv:1707.06347, 2017.

[14].  John Schulman, Philipp Moritz, Sergey Levine, Michael Jordan, and Pieter Abbeel. Highdimensional continuous control using generalized advantage estimation. In Proceedings of the International Conference on Learning Representations (ICLR), 2016.

90后程序员开发视频搬运软件、不到一年获利超 700 万,结局很刑! 谷歌证实裁员,涉及 Flutter、Dart 和 Python 团队 中国码农的“35岁魔咒” Xshell 8 开启 Beta 公测:支持 RDP 协议、可远程连接 Windows 10/11 ​MySQL 的第一个长期支持版 8.4 GA 开源日报 | 微软挤兑Chrome;阳痿中年的福报玩具;神秘AI能力太强被疑GPT-4.5;通义千问3个月开源8模型 Arc Browser for Windows 1.0 正式 GA Windows 10 市场份额达 70%,Windows 11 持续下滑 GitHub 发布 AI 原生开发工具 GitHub Copilot Workspace JAVA 下唯一一款搞定 OLTP+OLAP 的强类型查询这就是最好用的 ORM 相见恨晚
{{o.name}}
{{m.name}}

猜你喜欢

转载自my.oschina.net/u/4736317/blog/11072547