zoukankan      html  css  js  c++  java
  • Proximal Policy Optimization(PPO)算法 / 2017

    Intro

    2016年Schulman等人提出了Trust Region Policy Optimization算法。后来他们又发现TRPO算法在scalable(用于大模型和并行实现), data efficient(高效利用采样数据), robust(同一套超参,在大量不同的env上取得成功)上可以改进,于是作为TRPO的改进版本提出了PPO。

    PPO在2017年被Schulman等人提出后就刷新了continous control领域的SOTA记录,并且成为了OPENAI的default algorithm。虽然现在它已经不是领域的SOTA算法了,但因为PPO易于部署而且迭代过程方差小,训练较稳定,关键是使用方便,所以目前(2020.11)它还是大多数场景下的default algorithm。

    PPO造出来前,其他的流行RL算法缺点在哪?

    • DQN pooly understood,而且在很多简单任务上失败; 不支持continious control;训练过程poorly robust。

    • vanilla policy gradient 数据利用效率低,训练过程poorly robust。

    • trust region policy gradient 算法结构复杂,而且兼容性差,

    PPO算法结构设计思想

    • 为actor设计新的损失函数。clipped surrogate objective

    • 采样得到的数据,在更新agent的时候重复使用。multiple epochs of minibatch updates

    基本算法构造

    神经网络架构

    在PPO中critic的价值函数是V(s),而不是Q(s,a)。这和DDPG就相反,DDPG中critic的价值函数是Q(s,a)。

    PPO的paper并未写明算法的具体实现。因此我浏览github,调查了两种实现方法。

    我和作者都proposed的版本是让actor和critic参数共享。一个输入,即obs。两个输出,即actor输出和value输出。如:

    class PPO(nn.Module):
        def __init__(self, num_inputs, num_actions):
            super(PPO, self).__init__()
            self.conv1 = nn.Conv2d(num_inputs, 32, 3, stride=2, padding=1)
            self.conv2 = nn.Conv2d(32, 32, 3, stride=2, padding=1)
            self.conv3 = nn.Conv2d(32, 32, 3, stride=2, padding=1)
            self.conv4 = nn.Conv2d(32, 32, 3, stride=2, padding=1)
            self.linear = nn.Linear(32 * 6 * 6, 512)
            self.critic_linear = nn.Linear(512, 1)
            self.actor_linear = nn.Linear(512, num_actions)
            self._initialize_weights()
    
        def _initialize_weights(self):
            for module in self.modules():
                if isinstance(module, nn.Conv2d) or isinstance(module, nn.Linear):
                    nn.init.orthogonal_(module.weight, nn.init.calculate_gain('relu'))
                    # nn.init.xavier_uniform_(module.weight)
                    # nn.init.kaiming_uniform_(module.weight)
                    nn.init.constant_(module.bias, 0)
    
        def forward(self, x):
            x = F.relu(self.conv1(x))
            x = F.relu(self.conv2(x))
            x = F.relu(self.conv3(x))
            x = F.relu(self.conv4(x))
            x = self.linear(x.view(x.size(0), -1))
            return self.actor_linear(x), self.critic_linear(x)
    

    GAE(generalized advantage estimator)

    一项在Schulman, John, et al. "High-dimensional continuous control using generalized advantage estimation." arXiv preprint arXiv:1506.02438 (2015)中提出的技术。它是针对过去policy gradient系列算法中的returns作了调整,用GAE方法获取returns。

    def compute_gae(next_value, rewards, masks, values, gamma=0.99, tau=0.95):
        values = values + [next_value]
        gae = 0
        returns = []
        for step in reversed(range(len(rewards))):
            delta = rewards[step] + gamma * values[step + 1] * masks[step] - values[step]
            gae = delta + gamma * tau * masks[step] * gae
            returns.insert(0, gae + values[step])
        return returns
    

    actor损失函数设计

    PPO paper中对比了三个损失函数设计,CPI版本(作为baseline,就是没有clipping也没有KL penalty的),Clipping版本,KL penalty版本。
    根据实验结果,Clipping版本的损失函数作为proposed损失函数。

    Clipping版本如下:

    (L^{CLIP}( heta) = E_{t}( min<r_t( heta)A_{t}, clip(r_t( heta), 1-epsilon,1+epsilon)A_{t}> ))

    (1) (A_{t})

    这里的A表示advantage。(advantage = returns - values)。returns是计算得到的GAE值,values是模型的一步输出。

    (2) (r( heta)_{t})

    这里的r表示ratio,是新旧策略得到的logit_prob的比值。旧,指从env采样的时候用的policy。新,指在多步更新agent时的实时policy。

    (r( heta)_{t} = frac{pi(a_{t}|s_{t})}{pi_{old}(a_{t}|s_{t})})

    PPO整体损失函数设计

    PPO的actor和critic参数共享,用一个loss来同时更新actor和critic。loss设计如下:

    (LOSS = actor_loss + 0.5*critic_loss)

    actor-loss即前面的(L^{CLIP}( heta))。critic_loss如下:

    (critic_loss = sum(return - value))

    这里return就是前面advantage用的return,value是多步更新时实时从agent输出出来的value。

    采样(sample from environment)与更新(update our agent)

    强化学习算法,无外乎两个东西的交替迭代,即“sample from environment”和“update our agent”。在PPO算法中,采用这样的时序设计。

    LOOP for l rides:
          LOOP for s steps:
                sample from env, select action, according to current agent
                compute advantages for each transition
                compute GAE for each transition
          compute GAE as return for each step
          enough (states, actions, log_probs, returns, advantages) were collected 
          LOOP for p minibatchs:
                compute logit_probs, value, according to current agent
                compute loss 
                update our agent
                
    

    大规模、并行场景下实现PPO算法

    ./keep

  • 相关阅读:
    每日英语:Apple's Latest iPhone Puts Focus Back on Fingerprint Security
    每日英语:Stressed at Work? Reflect on the Positive
    每日英语:Hold On: Reasons For Never Giving Up Your Dream
    每日英语:China's New Anti-Graft Website: A Tale of Tigers, Flies and Bath Tubs
    每日英语:China Overtakes U.S. in Number of Diabetes Cases
    每日英语:New Reason To Get The Kids To Bed On Time
    每日英语:Why Are Items Pricier in China?
    每日英语:Burning Question / Does Reading In Dim Light Hurt Your Eyes?
    每日英语:Genetic Manipulation Extends Life of Mice 20%
    架构设计之Spring-Session分布式集群会话管理
  • 原文地址:https://www.cnblogs.com/dynmi/p/14004618.html
Copyright © 2011-2022 走看看