PPO-强化学习算法


PPO受到与TRPO相同的问题的激励:我们如何才能使用当前拥有的数据在策略上采取最大可能的改进步骤,而又不会走得太远而导致意外导致性能下降? 在TRPO试图通过复杂的二阶方法解决此问题的地方,PPO是一阶方法的族,它使用其他一些技巧来使新策略接近于旧策略。 PPO方法实施起来非常简单,并且从经验上看,其性能至少与TRPO相同。

PPO有两种主要变体:PPO-penalty和PPO-clip。

  • PPO-Penalty 近似解决了像TRPO这样的受KL约束的更新,但是对目标函数中的KL偏离进行了惩罚,而不是使其成为硬约束,并且在训练过程中自动调整了惩罚系数,以便对其进行适当缩放。
  • PPO-Clip 在目标中没有KL散度项,也没有任何约束。 取而代之的是依靠对目标函数的专门裁剪来消除新政策消除旧政策的激励。

这里我们将聚焦PPO-clip(OpenAI)

Quick Facts

  • PPO是一个on-policy算法
  • PPO能用于离散或者连续的动作空间
  • Spinningup的PPO支持用MPI并行

Key Equations

PPO-clip更新策略通过: θ k + 1 = arg max θ E s , a π θ k [ L ( s , a , θ k , θ ) ] , \theta_{k+1} = \arg \max_{\theta} \underset{s,a \sim \pi_{\theta_k}}{{\mathrm E}}\left[ L(s,a,\theta_k, \theta)\right], 一般用多步(通常minibatch)SGD去最大化目标。这里的 L L L ( s , a , θ k , θ ) = min ( π θ ( a s ) π θ k ( a s ) A π θ k ( s , a ) ,      clip ( π θ ( a s ) π θ k ( a s ) , 1 ϵ , 1 + ϵ ) A π θ k ( s , a ) ) , L(s,a,\theta_k,\theta) = \min\left( \frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)} A^{\pi_{\theta_k}}(s,a), \;\; \text{clip}\left(\frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)}, 1 - \epsilon, 1+\epsilon \right) A^{\pi_{\theta_k}}(s,a) \right), 其中 ϵ \epsilon 是一个较小的超参数,大概地描述新策略与旧策略相距多远。

这是一个较复杂的表述,很难一眼看出它是怎么做的或是如何有助于保持新策略接近旧策略。事实证明,此目标有一个相当简化的版本[1],较容易解决(也是我们在代码中实现的版本): L ( s , a , θ k , θ ) = min ( π θ ( a s ) π θ k ( a s ) A π θ k ( s , a ) ,      g ( ϵ , A π θ k ( s , a ) ) ) , L(s,a,\theta_k,\theta) = \min\left( \frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)} A^{\pi_{\theta_k}}(s,a), \;\; g(\epsilon, A^{\pi_{\theta_k}}(s,a)) \right), 其中 g ( ϵ , A ) = { ( 1 + ϵ ) A A 0 ( 1 ϵ ) A A < 0. g(\epsilon, A) = \left\{ \begin{array}{ll} (1 + \epsilon) A & A \geq 0 \\ (1 - \epsilon) A & A < 0. \end{array} \right. 为了弄清楚从中得到的直觉,让我们看一下单个状态-动作对 ( s , a ) (s,a) ,并考虑多个案例。

  • Advantage is positive 假设该 状态-动作对 的优势为正,在这种情况下,其对目标的贡献减少为 L ( s , a , θ k , θ ) = min ( π θ ( a s ) π θ k ( a s ) , ( 1 + ϵ ) ) A π θ k ( s , a ) . L(s,a,\theta_k,\theta) = \min\left( \frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)}, (1 + \epsilon) \right) A^{\pi_{\theta_k}}(s,a). 因为优势是正的,所以如果采取行动的可能性更大,即 π θ ( a s ) \pi_\theta(a|s) 增加,则目标也会增加。但是此术语中的最小值限制了目标可以增加多少。当 π θ ( a s ) > ( 1 + ϵ ) π θ k ( a s ) \pi_\theta(a|s)>(1+\epsilon)\pi_{\theta_k}(a|s) ,这个式子达到 ( 1 + ϵ ) A π θ k ( s , a ) (1+\epsilon)A^{\pi_{\theta_k}}(s,a) 的上限.因此新政策不会因远离旧政策而受益。
  • Advantage is negative: 假设该状态对对的优势为负,在这种情况下,其对目标的贡献减少为 L ( s , a , θ k , θ ) = max ( π θ ( a s ) π θ k ( a s ) , ( 1 ϵ ) ) A π θ k ( s , a ) . L(s,a,\theta_k,\theta) = \max\left( \frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)}, (1 - \epsilon) \right) A^{\pi_{\theta_k}}(s,a). 因为优势是负面的,所以如果行动的可能性降低,即 π θ ( a s ) \pi_\theta(a|s) 减小,则目标将增加。但是这个式子的最大值限制了目标增加的多少。当 π θ ( a s ) < ( 1 ϵ ) π θ k ( a s ) \pi_\theta(a|s)<(1-\epsilon)\pi_{\theta_k}(a|s) , 式子达到最大值 ( 1 ϵ ) A π θ k ( s , a ) (1-\epsilon)A^{\pi_{\theta_k}}(s,a) .因此,再次:新政策不会因远离旧政策而受益。

到目前为止,我们看到的是clipping作为一种调节器消除策略急剧变化的激励,而超参数ε则对应于新政策与旧政策的距离有多远,同时仍然有利于实现目标。

[1]https://drive.google.com/file/d/1PDzn9RPvaXjJFZkGeapMHbHGiWWW20Ey/view?usp=sharing

尽管这种clipping对确保合理的策略更新大有帮助,但仍然有可能最终产生与旧策略相距太远的新策略,并且不同的PPO实现使用了很多技巧来避免这种情况 关。 在此处的实现中,我们使用一种特别简单的方法:提前停止。 如果新政策与旧政策的平均KL差距超出阈值,我们将停止采取梯度步骤。
如果您对基本的数学知识和实施细节感到满意,则有必要查看其他实施以了解它们如何处理此问题!

Exploration vs. Exploitation

PPO以一种基于策略的方式训练随机策略。 这意味着它将根据最新版本的随机策略通过采样操作来进行探索。 动作选择的随机性取决于初始条件和训练程序。 在培训过程中,由于更新规则鼓励该策略利用已发现的奖励,因此该策略通常变得越来越少随机性。 这可能会导致策略陷入局部最优状态。

Pseudocode

在这里插入图片描述

Documentaton

spinup.ppo(env_fn, actor_critic=, ac_kwargs={}, seed=0, steps_per_epoch=4000, epochs=50, gamma=0.99, clip_ratio=0.2, pi_lr=0.0003, vf_lr=0.001, train_pi_iters=80, train_v_iters=80, lam=0.97, max_ep_len=1000, target_kl=0.01, logger_kwargs={}, save_freq=10)
Parameters:

  • env_fn – A function which creates a copy of the environment. The environment must satisfy the OpenAI Gym API.
  • actor_critic – A function which takes in placeholder symbols for state, x_ph, and action, a_ph, and returns the main outputs from the agent’s Tensorflow computation graph:在这里插入图片描述
  • ac_kwargs (dict) – Any kwargs appropriate for the actor_critic function you provided to PPO.
  • seed (int) – Seed for random number generators.
  • steps_per_epoch (int) – Number of steps of interaction (state-action pairs) for the agent and the environment in each epoch.
  • epochs (int) – Number of epochs of interaction (equivalent to number of policy updates) to perform.
  • gamma (float) – Discount factor. (Always between 0 and 1.)
  • clip_ratio (float) – Hyperparameter for clipping in the policy objective. Roughly: how far can the new policy go from the old policy while still profiting (improving the objective function)? The new policy can still go farther than the clip_ratio says, but it doesn’t help on the objective anymore. (Usually small, 0.1 to 0.3.)
  • pi_lr (float) – Learning rate for policy optimizer.
  • vf_lr (float) – Learning rate for value function optimizer.
  • train_pi_iters (int) – Maximum number of gradient descent steps to take on policy loss per epoch. (Early stopping may cause optimizer to take fewer than this.)
  • train_v_iters (int) – Number of gradient descent steps to take on value function per epoch.
  • lam (float) – Lambda for GAE-Lambda. (Always between 0 and 1, close to 1.)
  • max_ep_len (int) – Maximum length of trajectory / episode / rollout.
  • target_kl (float) – Roughly what KL divergence we think is appropriate between new and old policies after an update. This will get used for early stopping. (Usually small, 0.01 or 0.05.)
  • logger_kwargs (dict) – Keyword args for EpochLogger.
  • save_freq (int) – How often (in terms of gap between epochs) to save the current policy and value function.