美文网首页
论文笔记

论文笔记

作者: loffer | 来源:发表于2017-10-26 15:27 被阅读0次

    Multi-agent Actor-Critic for Mixed Cooperative-Competitive Environments

    pytorch-maddpg在下面的场景中实现了MADDPG,所以就结合程序来说明MADDPG的原理和运行过程。

    场景及设置介绍

    运行场景

    如上图,红点是毒药,蓝点和黑线都是捕猎者Pursuers,绿点为猎物Evaders,为蓝点的食物,青色的为障碍物Obstacles。图中两个蓝点需要学习合作策略,最大化共同的reward。

    1. Reward 设置如下:

      food_reward = 10.
      poison_reward = -1.
      encounter_reward = 0.01   //蓝点相遇时的reward,
      n_coop = 2   //表示需要训的合作的agent个数。
      

    Reward为2x2的numpy.ndarray,个数为蓝点捕猎者的个数,在本场景中为2。
    全局和局部的计算方法分别为:

       if self.reward_mech == 'global':
           rewards += (
               (len(ev_caught) * self.food_reward) + (len(po_caught) * self.poison_reward) +
               (len(ev_encounters) * self.encounter_reward))
       else:
           rewards[which_pursuer_caught_ev] += self.food_reward
           rewards[which_pursuer_caught_po] += self.poison_reward
           rewards[which_pursuer_encounterd_ev] += self.encounter_reward
    

    全局:遇到#的次数 * # reward的总和。

    局部:分别更新第一个或第二个蓝点的reward,遇到食物增加food_reward等。

    1. Action表示为2x2的FloatTensor,用于改变agent的速度和位置。

    2. 每一步的状态Obs由2x213的FloatTensor表示,为从环境中提取的各个agent的位置和速度等信息。环境的观测值由长度为2的list,用obs_表示,list中每个元素为numpy.ndarray,ndarray长度为213。

    3. Agent的网络结构定义为:

       class Actor(nn.Module):
         def __init__(self, dim_observation, dim_action):
         super(Actor, self).__init__()
         self.FC1 = nn.Linear(dim_observation, 500)
         self.FC2 = nn.Linear(500, 128)
         self.FC3 = nn.Linear(128, dim_action)
      
         # action output between -2 and 2
         def forward(self, obs):
         result = F.relu(self.FC1(obs))
         result = F.relu(self.FC2(result))
         result = F.tanh(self.FC3(result))
         return result
      

    输入观察,输出动作。这也就是图中蓝点的网络,调用父类的初始化操作,使用pytorch默认的随机初始化方法。初始化之后就可以用到游戏当中。

    1. Critic的网络结构为:

       class Critic(nn.Module):
         def __init__(self, n_agent, dim_observation, dim_action):
           super(Critic, self).__init__()
           self.n_agent = n_agent
           self.dim_observation = dim_observation
           self.dim_action = dim_action
           obs_dim = dim_observation * n_agent
           act_dim = self.dim_action * n_agent
      
           self.FC1 = nn.Linear(obs_dim, 1024)
           self.FC2 = nn.Linear(1024+act_dim, 512)
           self.FC3 = nn.Linear(512, 300)
           self.FC4 = nn.Linear(300, 1)
      
           # obs: batch_size * obs_dim
           def forward(self, obs, acts):
           result = F.relu(self.FC1(obs))
           combined = th.cat([result, acts], 1)
           result = F.relu(self.FC2(combined))
           return self.FC4(F.relu(self.FC3(result)))
      

    输入观察和动作,输出每个agent的Q值。也是使用随机初始化方法。这个网络在上图中不表示任何实物,因为它只在训练过程中出现,每个actor都有一个critic,收集所有agent的观察和动作,输出单个actor的Q值,用于更新actor。

    训练

    1. 开始游戏

    指定episode数目n_episode、每个episode最大steps max_steps、开始训练之前玩的局数episodes_before_train,初始化观测obs,total_reward,batch_size。
    对一局游戏的每一个steps,根据Agent网络输出动作,根据动作得到reward。将动作前后的状态,动作本身,reward 即(x,x’,a,r) 都保存到reply buffer D用于接下来的训练(,)。当完成episodes_before_train局数,收集到足够的reply buffer后,就可以开始训练了。设置episodes_before_train是为了满足训练中minibatch的要求。
    并且为了更好的探索动作,每个step,网络输出动作后增加一个随机过程。

    1. 训练过程
    训练过程

    对于每一个agent,从reply buffer D中随机抽取minibatch的S个(x,x’,a,r)的样本。
    如图所示,输入到critic网络中,输出的Q值反馈给actor。

    • 目标函数

    公式中的Q由上面提到的critic网络输出,r为单个agent即蓝点的reward。用于计算loss。

    • 更新critic的loss为:

    程序中的实现为:

    # 使用从D中取到某一个step的x和a,输出critic计算的Q值。
    # 由于每个step都有一个Q和r值,程序中一个episode有max_steps = 1000,
    # 所以Q和r都是1000 x 1的FloatTensor。 agent代表当前训练中的agent。
    current_Q = self.critics[agent](whole_state, whole_action)  
    # batch是从D中取到的四元组
    non_final_mask = ByteTensor(list(map(lambda s: s is not None,batch.next_states)))
    # 输入x’,a’使用critic计算出Q’,critics_target是前一step的critic
    self.critics_target = deepcopy(self.critics)
    target_Q[non_final_mask] = self.critics_target[agent](
    non_final_next_states.view(-1, self.n_agents * self.n_states),
    non_final_next_actions.view(-1,self.n_agents * self.n_actions))
    # self.GAMMA = 0.95, scale_reward: to scale reward in Q functions.
    # reward_batch中存的是两个蓝点1000步的reward,是1000 x 2的FloatTensor
    target_Q = (target_Q * self.GAMMA) + (reward_batch[:, agent] * scale_reward)
    # torch.nn.MSELoss() 为平方损失函数,detch返回新的Variable,使其跟以前的Q
    # 分离
    loss_Q = nn.MSELoss()(current_Q, target_Q.detach())
    
    • Actor接收到Q值后,结合本身的网络计算策略梯度用于优化参数:


      程序中处理如下:

       actor_loss = -self.critics[agent](whole_state, whole_action)
       actor_loss = actor_loss.mean()
       actor_loss.backward()
       self.actor_optimizer[agent].step()
      

    Critic和actor更新参数的部分写在MADDPG类的update_policy()中,主函数中每执行一个step,就会调用一次,每一步都会更新参数并保存critic前一个step的参数,用于计算loss。

    • 对每个agent都完成上述操作后,防止θ更新太快,做一些微调:

    然后重新开始一局,让agent用现在已更新的网络加上随机化过程来选择动作,对一局中的每个step,存储(x,x’,a,r),然后对每个agent做上述(1)-(4)的操作。反复训练,直到达到合适的效果,让两个蓝点学会竞争合作,就可以使用训练好的模型来玩游戏了。

    相关文章

      网友评论

          本文标题:论文笔记

          本文链接:https://www.haomeiwen.com/subject/lmdkpxtx.html