前言

本文讲解多智能体强化学习(Multi-agent Reinforcement Learning,MARL)中最最经典的一篇论文MADDPG,以及它的复现,超详细的!咱们往下看吧~

MADDPG的论文链接如下:

[1706.02275] Multi-Agent Actor-Critic for Mixed Cooperative-Competitive Environments (arxiv.org)

这篇文章需求有一些单智能体的先验常识,可参考之前的文章:

强化学习—DQN(Deep Q-Network)算法原理加代码实现 – ()

1. MADDPG模型介绍

MADDPG算法以DDPG为根底,提出了一种会集式练习散布式履行的多智能体深度强化学习算法,本办法既能够应用于包括通讯信道的协作场景,也能够应用于智能体之间只存在物理交互的竞赛性场景中。

  • 场景:环境部分可观、完全协作(共用同一奖赏)/竞赛(方针相互冲突)
  • 练习办法:会集练习、散布履行(CTDE)
  • 研讨点:研讨协作或协作竞赛混合场景下的多智能体深度强化学习算法算法
  • 立异点:提出了一种actor-critic办法的习惯,考虑其他智能体的行动战略,并能成功地学习需求复杂多智能体协调的战略

1.1 模型结构

MADDPG的模型结构如下:

多智能体强化学习——超详细的MADDPG原理及代码实现

如上图,在MADDPG的结构中,每个智能体都需求学习一个Actor网络i(ai∣oi)\pi _{i} (a_{i} |o_{i} )与一个Q网络Qi(X,a1,…,aN)Q_{i}^{\pi } (X,a_{1} ,…,a_{N} ),其间Q网络在练习阶段接纳一切智能体的观测所组成的环境信息X以及一切智能体的动作(a1,…,aN)(a_{1} ,…,a_{N} )作为输入,以此会集式地核算该智能体的动作-价值函数;而Actor网络则以智能体的部分观测为输入,输出其动作。因为每个智能体都会独自学习一个Q值,因此每个智能体都能够规划恣意归于自己的奖赏

MADDPG算法根据以下几个根本的束缚

  • 每个智能体在履行的动作的进程中,只能根据自己的部分观测核算出动作值
  • 不考虑环境动力学微分方程模型;
  • 不考虑智能体之间特定的通讯协议或许办法。

根据上述束缚,为各个模块规划方针函数并核算梯度

在图中,=(1,…,N)\pi =(\pi _{1},…,\pi _{N})表明N个智能体的战略,分别由=(1,…,N)\theta =(\theta _{1},…,\theta _{N})的N个Actor网络来拟合。在DDPG算法中,方针函数的界说为:

多智能体强化学习——超详细的MADDPG原理及代码实现

战略梯度为:

多智能体强化学习——超详细的MADDPG原理及代码实现

其间,D表明数据集,在MADDPG中界说每个智能体的方针函数为:

多智能体强化学习——超详细的MADDPG原理及代码实现

对每个智能体的战略梯度可由下式核算:

多智能体强化学习——超详细的MADDPG原理及代码实现

梯度的核算思路是相同的,本质上便是梯度核算的链式法则,只是在实际操作的进程中,actor网络和critic网络的更新是分隔的。

留意:在核算 Q 函数时,要将一切智能体的观测和动作值都作为输入,即 oa。否则,信息不全,核算出来的Q值就会不精确,导致练习进程不稳定。这便是“会集式练习”的关键所在。

1.2 模型扩展

本文还提出了MADDPG的两种扩展模式

1.2.1 猜测其它智能体的战略

原始MADDPG中,每个智能体的Q网络均需求接纳一切智能体的动作(战略)作为输入,此时每个智能体 ii 能够通过对其他智能体的战略进行估计而代替其他智能体 jj 真实的战略,即除了学习Actor网络和Q网络之外,还需求学习其余一切智能体战略的估计ij\hat{\mu } _{\phi _{i}^{j} },运用一个熵正则化器

多智能体强化学习——超详细的MADDPG原理及代码实现

其间,H是战略散布的熵,能够用下式核算近似值来代替:

多智能体强化学习——超详细的MADDPG原理及代码实现

1.2.2 从单一战略优化到战略集优化

为了进一步增强模型应对敌对智能体战略改动所导致的环境非平稳性,作者提出每个智能体能够练习得到由 K 个不同子战略组成的战略调集,即每个智能体的战略 i\mu _{i} 是K个不同子战略的组合,每个子战略都具有一个经历回访池,独自练习。对智能体 ii,其方针函数就能够改成:

多智能体强化学习——超详细的MADDPG原理及代码实现

unif(1,K)unif(1,K)表明子战略索引集,相应的战略梯度可改写为:

多智能体强化学习——超详细的MADDPG原理及代码实现

1.3 定论&模型缺陷

本文将DDPG算法扩展到多智能体强化学习中,通过“会集式练习散布式履行”的思路,核算出每个智能体的最优战略。该算法中智能体根据一切智能体的调查和动作学习一个会集的critic。在多种合作和竞赛的多智能体环境下,该办法优于传统的RL算法。咱们能够通过调集战略来练习智能体来进一步进步咱们办法的功能。

缺陷是当智能体数量比较大的时分,Q网络的输入空间随着智能体数目线性添加,无法扩展到大规模智能体系统中

2. MADDPG模型复现

2.1 MPE环境装置

MPE(Multi-Agent Particle Environment)是由 OpenAI 开源的一款多智能体强化学习试验渠道,以 OpenAI 的 gym 为根底,运用 Python 编写而成。它创造了一个简单的多智能体粒子国际,粒子们能够进行接连的调查和离散的动作。

2.1.1 前期预备

  • GitHub网站下载MPE的装置包:github.com/openai/mult…
  • 装置anaconda,通过conda创立虚拟环境,优点是便于创立咱们需求的不同版别的python环境,很方便,不必重复装置不同版别的python
  • conda虚拟环境装备如下(常用命令):

检查装置了哪些包:conda list

检查存在哪些虚拟环境:conda env list

Python创立虚拟环境:conda create -n your_env_name python=x.x

激活虚拟环境:source activate your_env_name

检查当前Python版别:python --version

装置相应的包:conda install package_name=x.xx或许pip install package_name==x.xx

封闭虚拟环境:conda deactivate

2.1.2 MPE装置环境要求

下载 Multi-Agent Particle Environment 源码,阅读 README.md 可知需求先装备:

多智能体强化学习——超详细的MADDPG原理及代码实现

  • python(3.5.4),openAI gym(0.10.5),tensorflow(1.8.0),numpy(1.14.5)

2.1.3 开始装置

在 Pycharm 自带的 terminal 或进入 cmd,翻开终端,将路径cd到multiagent-particle-envs文件夹下(即含有setup.py文件的文件夹下)履行pip install -e .(不要疏忽这个“.”)

multiagent环境装置完结。

同样的,将路径再cd到maddpg文件夹下(即含有setup.py文件的文件夹下),履行pip install -e .(不要疏忽这个“.”)。maddpg装置完结。

多智能体强化学习——超详细的MADDPG原理及代码实现

2.2 环境测验

装置完结后,输入测验命令

  • cd到/maddpg/experiments文件夹下:cd experiments

  • 运转train.py文件,默许环境为simple先在该目录下进行切换:python train.py --scenario simple

第一遍运转的时分,练习只会呈现练习数据,如下:

多智能体强化学习——超详细的MADDPG原理及代码实现

第一遍运转没有动画,运转结束,如果报错:

多智能体强化学习——超详细的MADDPG原理及代码实现
直接修正下格局就好:修正train.py第182行为

rew_file_name = str(arglist.plots_dir) + str(arglist.exp_name) +'_rewards.pkl'

第185行为

agrew_file_name = str(arglist.plots_dir) + str(arglist.exp_name) +'_agrewards.pkl'

运转第二遍,输入:python train.py --scenario simple --display,就能够进行可视化,如下图:

多智能体强化学习——超详细的MADDPG原理及代码实现

2.3 中心代码解读

Actor-Critic结构

  • 给Actor输入环境的调查值obs,输出的便是动作;
  • 把Actor输出的动作和对应的环境的调查值obs输入给Critir,最后输出Q值。
# Actor
def predict(self, obs):
    """ input:  
            obs: observation, shape([B] + shape of obs_n[agent_index])
        output: 
            act: action, shape([B] + shape of act_n[agent_index])
    """
    this_policy = self.model.policy(obs)
    this_action = SoftPDistribution(
        logits=this_policy,
        act_space=self.act_space[self.agent_index]).sample()
    return this_action
def predict_next(self, obs):
    """ input:  observation, shape([B] + shape of obs_n[agent_index])
        output: action, shape([B] + shape of act_n[agent_index])
    """
    next_policy = self.target_model.policy(obs)
    next_action = SoftPDistribution(
        logits=next_policy,
        act_space=self.act_space[self.agent_index]).sample()
    return next_action
# Critic
def Q(self, obs_n, act_n):
    """ input:  
            obs_n: all agents' observation, shape([B] + shape of obs_n)
        output: 
            act_n: all agents' action, shape([B] + shape of act_n)
    """
    return self.model.value(obs_n, act_n)
def Q_next(self, obs_n, act_n):
    """ input:  
            obs_n: all agents' observation, shape([B] + shape of obs_n)
        output: 
            act_n: all agents' action, shape([B] + shape of act_n)
    """
    return self.target_model.value(obs_n, act_n)

这一部分描述了Actor详细怎么输出动作,以及Critir怎么打分。

Actor网络的参数更新

以下代码表现的是多个Actor网络的更新:

def _actor_learn(self, obs_n, act_n):
    i = self.agent_index
    this_policy = self.model.policy(obs_n[i])
    sample_this_action = SoftPDistribution(
        logits=this_policy,
        act_space=self.act_space[self.agent_index]).sample()
    action_input_n = act_n + []
    action_input_n[i] = sample_this_action
    eval_q = self.Q(obs_n, action_input_n)
    act_cost = layers.reduce_mean(-1.0 * eval_q)
    act_reg = layers.reduce_mean(layers.square(this_policy))
    cost = act_cost + act_reg * 1e-3
    fluid.clip.set_gradient_clip(
        clip=fluid.clip.GradientClipByNorm(clip_norm=0.5),
        param_list=self.model.get_actor_params())
    optimizer = fluid.optimizer.AdamOptimizer(self.lr)
    optimizer.minimize(cost, parameter_list=self.model.get_actor_params())
    return cost

MADDPG算法中心

MADDPG算法是对DDPG算法为习惯多Agent环境的改善,最中心的部分便是每个Agent的Critic部分能够获取其余一切Agent的动作信息,进行中心化练习和非中心化履行,即在练习的时分,引进能够调查大局的Critic来指导Actor练习,而测验的时分只运用有部分观测的actor采纳行动

def learn(self, agents):
    self.global_train_step += 1
    # only update parameter every 100 steps
    if self.global_train_step % 100 != 0:
        return 0.0
    if self.rpm.size() <= self.min_memory_size:
        return 0.0
    batch_obs_n = []
    batch_act_n = []
    batch_obs_new_n = []
    rpm_sample_index = self.rpm.make_index(self.batch_size)
    for i in range(self.n):
        batch_obs, batch_act, _, batch_obs_new, _ \
            = agents[i].rpm.sample_batch_by_index(rpm_sample_index)
        batch_obs_n.append(batch_obs)
        batch_act_n.append(batch_act)
        batch_obs_new_n.append(batch_obs_new)
    _, _, batch_rew, _, batch_isOver \
            = self.rpm.sample_batch_by_index(rpm_sample_index)
    # compute target q
    target_q = 0.0
    target_act_next_n = []
    for i in range(self.n):
        feed = {'obs': batch_obs_new_n[i]}
        target_act_next = agents[i].fluid_executor.run(
            agents[i].next_a_program, # 每个Agent独自采样
            feed=feed,
            fetch_list=[agents[i].next_action])[0]
        target_act_next_n.append(target_act_next)
    feed_obs = {'obs' + str(i): batch_obs_new_n[i] for i in range(self.n)}
    feed_act = {'act' + str(i): target_act_next_n[i]for i in range(self.n)}
    feed = feed_obs.copy()
    feed.update(feed_act)  # merge two dict
    target_q_next = self.fluid_executor.run(
        self.next_q_program,  # 能够观测大局的Critic的方针网络,专门用来稳定Q_target
        feed=feed,
        fetch_list=[self.next_Q])[0]
    target_q += (
        batch_rew + self.alg.gamma * (1.0 - batch_isOver) * target_q_next)
    feed_obs = {'obs' + str(i): batch_obs_n[i] for i in range(self.n)}
    feed_act = {'act' + str(i): batch_act_n[i] for i in range(self.n)}
    target_q = target_q.astype('float32')
    feed = feed_obs.copy()
    feed.update(feed_act)
    feed['target_q'] = target_q
    critic_cost = self.fluid_executor.run(
        self.learn_program,  # 练习能够观测大局的Critic
        feed=feed,
        fetch_list=[self.critic_cost])[0]
    self.alg.sync_target()
    return critic_cost

总结

以上便是MADDPG算法的一切内容啦,喜爱的不要忘记一键三连呐~