强化学习PPO从理论到代码详解(1)--- 策略梯度Policy gradient

第0章 闲聊吹水

Proximal Policy Optimization(PPO) 近端策略优化,可以说是目前最稳定,最强的强化学习算法之一了,也是openAI默认的强化学习算法,有多叼不用我说了吧。

笔者在强化学习的道路上看来很多书,看了很多代码,和很多大佬的博客,只是很多都是侧重一个方面,所以我在吸取百家之长后,决定完完整整的写一回PPO从算法理论到逐行代码手敲和详解的文章,我会做到非常详尽,尽量做到每一个符号都解释。我在学习强化学的初期,入手了一些不那么友好的书籍或者视频,满脑都是:这个符号是啥?这个符号又是啥?😵😵😵后来我看来很多家的视频和书籍,主要参考了的easy RL 和李宏毅老师视频,当然还有很多大佬的博客我就不一一列出了。

我希望我的文章能给强化学习道路上的同志们一点帮助,由于笔者才疏学浅,有写的不好的地方还望大家多多指正批评,在此谢过👊。

本系列将分四章:

1. PPO基础之策略梯度(Policy gradient) 篇

2. PPO 算法详解 篇

3. PPO 代码详写详解 篇

4. PPO 实战 篇

接下来就正式开始吧。

第一章 策略梯度(Policy gradient)

基础概念

强化学习有三要素 1. 演员actor 2. 环境env 3.奖励函数 reward function

这个图就很好的阐述了这三个要素在实际应用当中的是什么,也很好理解。我们强化学习的目是什么呢?,就是训练出一个actor,这个actor玩游戏跟开了挂一样, 或者是下棋能击败人类一切玩家的棋神。这里我们把这个actor,或者说策略用 \pi _{\theta (s)} 来表示,我们把这个

  • 策略记做\pi
  • \theta表示这个策略的参数,通常会用一个神经网络代替这个策略, \theta就是这个神经网络的参数
  • s表示这个策略网络的输入,也就是状态state, 或者说是observation,这个之后还会提到。

找到奖励

那么我们现在有个这个策略,我们就可以让这个策略去玩游戏,去和游戏环境做互动。像这样子

(这里不对马尔科夫过程做详细解释,不影响后面的理解)然后我们可以得到一条轨迹,这个轨迹长这个子。       

                                             s_{1} ,a_{1} ,r_{1} ,s_{2} ,a_{2} ,r_{2} ... a_{t},r_{t}                                    1.1

假设策略\pi _{\theta (s)}是一个玩游戏AI,输入一个游戏状态s1, 策略网络根据这个游戏画面,选择一个动作a1, 然后得到奖励r1,随着游戏画面改变,输入新游戏状态s2,选择下一个动作a2,得到奖励r2,依次循环直到游戏结束,直观上这还是很符合逻辑的嘛。

然后根据这个轨们迹我就可以的到一个总奖励,我们先把这个总奖励记做 R{_{\theta }},根据上面1.1式中的轨迹来看,总奖励 R_{\theta } = {\textstyle \sum_{t=1}^{T}} r_{t},这也很简单吧。但是事情到这里开始变复杂了,如果我们的奖励函数合理,又能很轻松得到R{_{\theta }},我们就优化网络让其最大化奖励不久完了吗,好,讲到这,完结撒花🌹🌹🌹。

当然,事情远没有结束,事实上,无论是在actor中,还是在环境中,随机性(randomness)都是不可避免的,同样的情况可能有不同的奖励。既然得不到完全准确R{_{\theta }},我们可以用一个期望值来代替,这个期望值记做\bar{R}{_{\theta }},现在问题是如何到底这个期望值\bar{R}{_{\theta }}

actor和环境互动,每玩一轮游戏,或者说每一个episode都可以得到一条轨迹 \tau,每条轨迹的reward也可以计算。 

                              \tau = \left \{ s_{1} ,a_{1} ,r_{1} ,s_{2} ,a_{2} ,r_{2} ... a_{t},r_{t} \right \}                            1.2

                              R_{(\tau)}=\sum_{n=1}^{N}r_{_{n}}                                                                      1.3

 每一个轨迹都一个概率(probability), 这依赖于actor的参数\theta,定义为 P_{_{(\tau\mid \theta)}}。如果我们能穷举所有的轨迹和对应的概率,那么\bar{R}{_{\theta }}就会非常简单,公式如下。

                                                      \bar{R}{_{\theta }} = \sum_{ \tau}^{} R_{(\tau) } P_{(\tau \mid \theta) }                                        1.4 

 但是,but again,但是实际上得到所有的\tau基本不可能,那怎么办呢?那么我们可以做sample, 只要sample的次数足够做,\bar{R}{_{\theta }}就能非常接近真实值(概率论的知识)。

现在让策略\pi _{\theta} 玩N次游戏,做很多次的采样。就可以获得很多条轨迹\left \{ \tau^{_{1}},\tau^{_{2}},\tau^{_{3}},\tau^{_{4}} ... \tau^{_{n}} \right \}

那现在公式变为了如下,

                                       \bar{R}{_{\theta }} = \sum_{ \tau}^{} R_{(\tau) } P_{(\tau \mid \theta) }\approx \frac{1}{N}\sum_{n=1}^{N}R_{\tau^{n}}                       1.5        

其实也很好理解,理想状态得到所有轨迹,各个轨迹概率和对应的这个奖励相乘就得到期望奖励值,现在做采样得到很多条轨迹求他们的平均奖励值,就可以近似得到期望奖励。

举个例子,如果我们掷一枚硬币,正面奖励为1,反面奖励为0,每一轮游戏扔10次,得到所有状态太麻烦,或者就认定其不可取,这时候我们干脆玩100轮,将所有的奖励求和,然后在求平均,得到这个奖励的期望值(应当是约等于5)。

梯度上升Gradient Ascent:

我先贴出求目标函数梯度的完整数学推导过程:

 完了,BBQ了,估计到这你已经完成强化学习的从入门到放弃了。不过不要慌先忘记这一大串这个式子,一步一步来。

先从式1.4,我们知道了怎么求每个奖励的期望值。

                                                        \bar{R}{_{\theta }} = \sum_{ \tau}^{} R_{(\tau) } P_{(\tau \mid \theta) }

\bar{R}{_{\theta }}就可以看做是我们的目标方程(objective function),我们要找的就是一组最优的参数\theta^{*},这个参数可以最大化\bar{R}{_{\theta }}.

                                                          \theta^{*} = argmax\bar{R}_{\theta}

既然要最大化 \bar{R}{_{\theta }},就可以用gradient ascent! 其计算原理如下,有机器学习基础应当不难理解:

 知道了思路,接下来对式1.4进行计算梯度计算,在贴一遍式1.4,防止忘记:

                                                             \bar{R}{_{\theta }} = \sum_{ \tau}^{} R_{(\tau) } P_{(\tau \mid \theta) }

对 \theta求梯度过程如下 ,中间有一步很跳跃,主要用到了链式法则,链式法则我贴在右边。             

注意看下面红色框,是不是感觉很熟悉。对,就是式1.5,把理想状态换成采样,我也把式1.5 贴在了红色框上面!

用式1.5替换之后,式子就变成了1.6。 

                                               \bar{R}{_{\theta }} \approx \frac{1}{N}\sum_{n=1}^{N}R_{\tau^{n}} \nabla log P_{(\tau^{n}\mid\theta) }                              1.6

现在我们有了策略梯度的一个基本式子,但是这个式子还不够清楚,因为每一条轨迹的概率是可以更细化的去算的。现在我们将P_{(\tau^{n}\mid\theta) }展开(公式太长,这里直接截用李宏毅老师上课的PPT中的公式)

 遇到长的式子不要慌,先看最长的那一行

其实这是一个很直觉的公式,我们一项一项看:

  • p(s_{_{1}})初始状态s1的概率
  • p(a_{_{1}} \mid s_{1},\theta)基于这个状态s1和参数\theta选择动作a1的概率
  • p(r_{_{1}},s_{2} \mid s_{1},a_{1})基于动作a1和s1,得到奖励函数r1,然后状态转移到s2

后面就是循环往复。在看这个式子

我们现在要先两边取log,这样可以把相乘换成相加,式子就变成了 如下

其中红色框这一项\theta没有关系,然后两边对\theta求梯度就可以消去和\theta无关的项。整个式子就变成了如下

 把上面的式子带入式子1.6,就得到了一个完整的可用的梯度公式

 其中我们还是稍稍做了一点改变,

 这个式子也很好理解,一条轨迹的概率不就是这条轨迹每一个 采取某个动作基于某一个状态概率 的相乘,但是因为取了log这里就变成了相加,用了求和符号。现在再回过头看看那一大串的公式,这里附加一张图以便理解,现在这当中的每一步相信就非常清楚了。

 然后去做梯度上升就更新\theta啦,整个式子的推导就完成了。

\theta^{new} \leftarrow \theta^{old}+ \eta \nabla{\bar{R}}_{ \theta{old}}

直观的理解

我们再来看这个最重要的式子

 这个式子看起来很复杂,直观上可以理解为如果在\tau^{^{n}} 这个轨迹中,agent在玩到第t步时,看到了s{_{t}^{n}},采取了一个动作a{_{t}^{n}}

最后的R_{(\tau^{n})}正的,就更新\theta提升p(a_{t}^{n}\mid s_{t}^{n})概率

最后的R_{(\tau^{n})}负的,就更新\theta降低p(a_{t}^{n}\mid s_{t}^{n})概率

终于policy gradient的基本思路就讲清楚了!!

随之而来的问题

但是,又是但是😭😭,这里还会有几个小问题。

Q1:为什么要用log呀,就是单纯的简化计算吗?

Q2: 万一\bar{R}{_{\theta }}都是正的会影响结果吗?

Q3:用整个 episode,或者说一条轨迹的reward评价一个其中的一个pair a_{t} \mid s_{t}的好坏合理吗?换句话说,我整局游戏输了,难道我的每一步操作都是错的吗?

为了下一步的学习PPO,这几个问题还必须要解决,但是李宏毅老师已经把这几个问题讲的非常清楚了,这里我截取其中的图片再稍微解释一下。如果想去看视频的也可以:这里恰个链接,不想去也可以往下看
Deep Reinforcemen Learning(3_1)_哔哩哔哩_bilibiliDeep Reinforcemen Learning(3_1)是李宏毅2020机器学习深度学习(完整版)国语的第108集视频,该合集共计119集,视频收藏或关注UP主,及时了解更多相关视频内容。https://www.bilibili.com/video/BV1JE411g7XF?p=108&vd_source=30e162a938f0ff832e2713d1b1f6640fQ1:为什么要用log呀,就是单纯的简化计算吗?

首先我们先理解log,再求梯度中根据链式法则用log其实等于做了一个normalization

                                 log p(a_{t}^{n} \mid s_{t}^{n},\theta ) = \frac{ \nabla p(a_{t}^{n} \mid s_{t}^{n},\theta ) }{p(a_{t}^{n} \mid s_{t}^{n},\theta ) }                                    1.7

怎么理解呢,上图!

在四次轨迹中,a被sample了一次,b被sample了三次。a对应的轨迹奖励是2,b是1。

其实我们应该提升a的概率,因为奖励高嘛!但是因为b被sample3次,也就被提升了三次,a的奖励虽然大但是只被提升了一次。随后选择动作b的概率相对a的概率竟然提升了😰😰,这肯定会影响结果。根据式1.7,就可以解决这个问题,不光计算梯度,还要除以对应的概率。这个问题就可以被解决。

 Q2: 万一\bar{R}{_{\theta }}都是正的会影响结果吗?

其实理想状态是不会的影响的,如果每一个action都被sample到,那就都提升,其实也就没有问题。但是如果有一个没有sample到就坏了,概率关系就不对了。

 

这个时候我们只要添加一个baseline就可以了

 

这样就可以有正有负,不光只有提升还有下降,相对关系是正确的就可以。至于这个b的选择可以约等于 ≈ sample到每条轨迹的奖励的均值,这里先不做过多解释,后面实际用到时在详解。红色框这一项非常重要,又称为优势函数,下一节我们会用到

Q3:用整个 episode的reward表示一个pair a_{t} \mid s_{t}的好坏合理吗?换句话说,我整局游戏输了,难道我的每一步操作都是错的吗?

这个问题从直觉上我们觉得是不对的,实际也是不准的。我整局游戏虽然输了,但是可能也有很精彩的操作啊,就像玩OW,麦克雷枪枪爆头😁😁,就是最后放大空了,游戏输了,很明显枪枪爆头是好的操作,应当提升这个概率。如何解决呢,我们可以计算从某一个action往后的奖励,看看这个action对之后有什么影响,再加上一个折扣,来当做正确的奖励值。替换如下:

如果这个奖励的计算你还是觉得有点懵,可以再看看下面这张图,是否会更多的理解:

更新中。。。喜欢请多支持

  • 21
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
以下是一个简单的强化学习 policy gradient 的 Matlab 代码: ```matlab % 环境初始化 env = RLenv(); state = env.reset(); % 参数初始化 num_episodes = 5000; % 训练的总回合数 num_actions = env.action_space_size(); % 动作空间的大小 hidden_size = 16; % 隐藏层的神经元数量 learning_rate = 0.01; % 学习率 % 策略网络初始化 policy_net = PolicyNet(hidden_size, num_actions); % 训练过程 for episode = 1:num_episodes % 记录当前回合的状态、行动和奖励 states = []; actions = []; rewards = []; % 采样并执行一个动作 while true % 根据当前状态和策略网络选择一个动作 action_probs = policy_net.predict(state); action = randsample(num_actions, 1, true, action_probs); % 执行动作并观察环境的反馈 [next_state, reward, done] = env.step(action); % 记录状态、行动和奖励 states = [states; state]; actions = [actions; action]; rewards = [rewards; reward]; % 更新当前状态 state = next_state; % 如果回合结束,则退出循环 if done break; end end % 计算回合的总奖励 total_reward = sum(rewards); % 计算回合的折扣奖励 discounted_rewards = calculate_discounted_rewards(rewards, 0.99); % 计算策略梯度 grads = policy_gradient(policy_net, states, actions, discounted_rewards); % 使用策略梯度更新策略网络 policy_net = update_policy(policy_net, grads, learning_rate); % 重置环境并开始下一回合 state = env.reset(); end % 测试过程 state = env.reset(); while true % 根据当前状态和策略网络选择一个动作 action_probs = policy_net.predict(state); action = randsample(num_actions, 1, true, action_probs); % 执行动作并观察环境的反馈 [next_state, reward, done] = env.step(action); % 更新当前状态 state = next_state; % 如果回合结束,则退出循环 if done break; end end ``` 其中,`PolicyNet` 是一个简单的神经网络模型,用于拟合策略函数;`calculate_discounted_rewards` 是一个计算折扣奖励的函数;`policy_gradient` 是一个计算策略梯度的函数;`update_policy` 是一个使用策略梯度更新策略网络的函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值