白话强化学习笔记

本文介绍了强化学习中的Q值与V值,以及它们之间的转换关系。讨论了蒙地卡罗算法、时序差分TD学习,特别是Qlearning和SARSA的区别。接着讲解了DQN如何使用深度学习解决连续状态问题,以及DoubleDQN和DuelingDQN的改进。最后提到了策略梯度和Actor-Critic方法,以及PPO算法在处理离散到连续动作空间和数据浪费问题上的应用。
摘要由CSDN通过智能技术生成

白话强化学习笔记

白话强化学习

Q与V

  • Q:评估动作的价值。它代表了智能体选择这个动作后,一直到最终状态奖励总和的期望。
  • V:评估状态的价值。它代表了智能体在这个状态下,一直到最终状态的奖励总和的期望。
  • VQVQVQVQ:状态—动作—状态—动作…

下面讲的都是从后向前更新

从Q到V

从动作反推状态

一个状态的V值,就是这个状态下的所有动作的Q值,在策略下的期望
v π ( s ) = ∑ a ∈ A π ( a ∣ s ) q π ( s , a ) v_{\pi}(s)=\sum_{a\in{A}}\pi(a|s)q_{\pi}(s,a) vπ(s)=aAπ(as)qπ(s,a)

  • v π ( s ) v_{\pi}(s) vπ(s):V值
  • π ( a ∣ s ) \pi(a|s) π(as):策略
  • q π ( s , a ) q_{\pi}(s,a) qπ(s,a):Q值

从V到Q

从状态反推动作
q π ( s , a ) = R s a + γ ∑ s ′ P s s , a v π ( s ′ ) q_{\pi}(s,a)=R_s^a+\gamma\sum_{s'}P_{ss^,}^av_{\pi}(s') qπ(s,a)=Rsa+γsPss,avπ(s)

  • q π ( s , a ) q_{\pi}(s,a) qπ(s,a):Q值
  • R s a R_s^a Rsa:奖励
  • γ \gamma γ:折扣率
  • P s s , a P_{ss^,}^a Pss,a:状态转移概率
  • v π ( s , ) v_{\pi}(s^,) vπ(s,):V值
  • 这里不需要关注策略,这里是环境的状态转移概率决定的。
  • 当我们选择A,并转移到新的状态时,就能获得奖励,我们必须把这个奖励也算上!

从V到V

把公式代进去就可以了。
v π ( s ) = ∑ a ∈ A π ( a ∣ s ) ( R s a + γ ∑ s , ∈ S P s s ′ a v π ( s ′ ) ) v_{\pi}(s)=\sum_{a\in{A}}\pi(a|s)(R_s^a+\gamma\sum_{s^,\in{S}}P_{ss'}^av_{\pi}(s')) vπ(s)=aAπ(as)(Rsa+γs,SPssavπ(s))

小结

  • V就是子节点的Q的期望!但要注意V值和策略相关。
  • Q就是子节点的V的期望!但要注意,记得把R计算在内。

蒙地卡罗

算法

  1. (小猴子走迷宫)
  2. 根据策略往前走,一直走到最后,期间什么都不用算,需要记录每一个状态转移,获得多少奖励r即可
  3. 从终点往回走,一边走一边计算G值。G值等于上一个状态的G值(记作G’),乘以一定的折扣 γ \gamma γ,再加上r
  4. 进行多次试验后,有可能会经过某个状态多次,通过回溯,也会有多个G值;
  5. 平均每个状态的G值,这就是我们需要求的V值。

但蒙地卡罗有一个比较大的缺点,就是每一次游戏,都需要先从头走到尾,再进行回溯更新。如果最终状态很难达到,那小猴子可能每一次都要转很久很久才能更新一次G值。

平均香蕉

有两条长度分别为A,B的香蕉(并假设:A>B)。如果我要知道他们平均有多长。

我只需要把A切成和B长;然后把多出来的那一节,再切一半,接到B就可以了。

这时候,我们称那条加长了的B香蕉为平均香蕉。
V n e w = V o l d − G N + V o l d V_{new}=\frac{V_{old}-G}{N}+V_{old} Vnew=NVoldG+Vold
甚至可以不用记录N,把 1 N \frac{1}{N} N1设置成一个固定的数(超参数),这个值就是学习率。

也就是说,每一次G都会引导V增加一些或者减少一些,而这个V值慢慢就会接近真正的V值

蒙地卡罗MC更新公式

V ( S t ) ← V ( S t ) + α [ G t − V ( S t ) ] V(S_t){\leftarrow}V(S_t)+\alpha[G_t-V(S_t)] V(St)V(St)+α[GtV(St)]

  • G t G_t Gt:新来的G
  • 右边的 V ( S t ) V(S_t) V(St):原来的平均值

蒙地卡罗有一些缺点:

  • 相对动态规划,会有点不那么准。因为蒙地卡罗每一次的路径都是不一样的。
  • 如果环境的状态空间非常大,或者最终状态只有非常小的概率达到。那么蒙地卡罗算法将会很难处理。

时序差分TD估算状态V值

算法流程

  1. 小猴子每走1步,看一下这个路口的V值,还有获得的奖励r
  2. 回到原来的路口,把刚刚看到的V值和奖励r进行运算,估算出V值

可以把TD看成是这样一种情况:从A状态,经过1步,到B状态。什么都不管就当B状态是最终状态了。

但B状态本身就带有一定的价值,也就是V值。其意义就是从B状态到最终状态的总价值期望。

但是有一个问题,一开始B状态也是没有值的,怎么办:多走几次,整个系统就会慢慢建立起来了。

更新公式

V ( S t ) ← V ( S t ) + α [ R t + 1 + γ V ( S t + 1 ) − V ( S t ) ] V(S_t){\leftarrow}V(S_t)+\alpha[R_{t+1}+{\gamma}V(S_{t+1})-V(S_t)] V(St)V(St)+α[Rt+1+γV(St+1)V(St)]

与MC的区别:

  • MC公式里更新目标是 G t G_t Gt
  • TD公式里更新目标换成 R t + 1 + γ V ( S t + 1 ) R_{t+1}+{\gamma}V(S_{t+1}) Rt+1+γV(St+1)

TD更厉害的是,在很多时候,并不需要一直到最后,可以先用后面的估算,然后调整当前状态。

Qlearning

TD之于Q值估算

  1. 问题转换

    V ( S t + 1 ) V(S_{t+1}) V(St+1)的意义是,在 S t + 1 S_{t+1} St+1到最终状态获得的奖励期望值。

    Q ( S t , A t ) Q(S_t,A_t) Q(St,At)的意义是,在 Q ( S t , A t ) Q(S_t,A_t) Q(St,At)到最终状态获得的奖励期望值。

    所以可以把 V ( S t + 1 ) V(S_{t+1}) V(St+1)看成是下山途中的一个路牌,这个路牌告诉我们下山到底还有多远,然后加上R这一段路,就知道 Q ( S t , A t ) Q(S_t,A_t) Q(St,At)离山脚有多长的路。

    但在实际操作的时候,会有一个问题。 在这里我们要估算两个东西,一个是V值,一个是Q值。

    人们想出的办法就是,用下一个动作的Q值,代替V值。(这边的解释去看看博客的图)

    因为从状态 S t + 1 S_{t+1} St+1到动作 A t + 1 A_{t+1} At+1之间没有奖励反馈,所以我们直接用 A t + 1 A_{t+1} At+1的Q值,代替 S t + 1 S_{t+1} St+1的V值。

  2. 麻烦的解决

    麻烦来了:关键是马可洛夫链不是链,是树!

    S t + 1 S_{t+1} St+1下,可能有很多动作 A t + 1 A_{t+1} At+1。不同动作的Q值自然是不同的。 所以 Q ( S t + 1 , A t + 1 ) Q(S_{t+1},A_{t+1}) Q(St+1,At+1)并不能等价于 V ( S t + 1 ) V(S_{t+1}) V(St+1)

    虽然不相等,但不代表不能用其中一个来代表 V ( S t + 1 ) V(S_{t+1}) V(St+1)

  3. 采用方法

    相同策略下产生的动作 A t + 1 A_{t+1} At+1。这就是SARSA。

    选择能够产生最大Q值的动作 A t + 1 A_{t+1} At+1。这就是Qlearning。

SARSA

Q ( S , A ) ← Q ( S , A ) + α [ R + γ Q ( S ′ , A ′ ) − Q ( S , A ) ] Q(S,A){\leftarrow}Q(S,A)+\alpha[R+{\gamma}Q(S',A')-Q(S,A)] Q(S,A)Q(S,A)+α[R+γQ(S,A)Q(S,A)]

其实SARSA和前面说的TD估算V值几乎一模一样,只不过挪了一下,从V改成Q了。

注意,这里的 A t + 1 A_{t+1} At+1是在同一策略产生的。也就是说, S t S_t St A t A_t At的策略和 S t + 1 S_{t+1} St+1 A t + 1 A_{t+1} At+1是同一个策略。这也是SARSA和Qlearning的唯一区别

Qlearning

Q ( S , A ) ← Q ( S , A ) + α [ R + γ max ⁡ α Q ( S ′ , A ′ ) − Q ( S , A ) ] Q(S,A){\leftarrow} Q(S,A)+\alpha[R+{\gamma} \mathop{\max}\limits_{\alpha} Q(S',A')-Q(S,A)] Q(S,A)Q(S,A)+α[R+γαmaxQ(S,A)Q(S,A)]

道理其实也很简单:因为需要找的是能获得最多奖励的动作,Q值就代表我们能够获得今后奖励的期望值。所以我们只会选择Q值最大的,也只有最大Q值能够代表V值。

总结

  • Qlearning和SARSA都是基于TD的。不过在之前的介绍中,用TD估算状态的V值。而Qlearning和SARSA估算的是动作的Q值。
  • Qlearning和SARSA的核心原理,是用下一个状态 S t + 1 S_{t+1} St+1的V值,估算Q值。
  • 既要估算Q值,又要估算V值会显得比较麻烦。所以用下一状态下的某一个动作的Q值,来代表 S t + 1 S_{t+1} St+1的V值。
  • Qlearning和SARSA唯一的不同,就是用什么动作的Q值替代 S t + 1 S_{t+1} St+1的V值。
  • SARSA 选择的是在 S t S_t St同一个策略产生的动作。Qlearning 选择的是能够产生最大的Q值的动作。

Qlearning算法也有很大的局限性,无论现实世界还是游戏世界,很多时候状态都是连续的,像表格这种方式,只能解决状态有限且离散的任务。

DQN算法应运而生!用深度网络,解决了连续状态的问题。

DQN

Deep network + Qlearning = DQN

  • Qlearning中的Qtable在遇到连续的情况下就没办法了。但是函数就允许连续状态的表示。于是神经网络就派上用场了。

  • 其实Qlearning和DQN并没有根本的区别。只是DQN用神经网络,也就是一个函数替代了原来Qtable而已。

Q ( S , A ) ← Q ( S , A ) + α [ R + γ max ⁡ α Q ( S ′ , a ) − Q ( S , A ) ] Q(S,A){\leftarrow} Q(S,A)+\alpha[R+{\gamma} \mathop{\max}\limits_{\alpha} Q(S',a)-Q(S,A)] Q(S,A)Q(S,A)+α[R+γαmaxQ(S,a)Q(S,A)]

算法流程

假设需要更新当前状态 S t S_t St下的某动作A的Q值: Q ( S , A ) Q(S,A) Q(S,A),可以:

  1. 执行A,往前一步,到达 S t + 1 S_{t+1} St+1
  2. S t + 1 S_{t+1} St+1输入Q网络,计算 S t + 1 S_{t+1} St+1下所有动作的Q值;
  3. 获得最大的Q值加上奖励R作为更新目标;
  4. 计算损失:logits( Q ( S , A ) Q(S,A) Q(S,A)),labels( max ⁡ Q ( S t + 1 ) + R \mathop{\max}Q(S_{t+1})+R maxQ(St+1)+R
  5. 用loss更新Q网络。

总结

  • 其实DQN就是Qlearning扔掉Qtable,换上深度神经网络。
  • 解决连续型问题,如果表格不能表示,就用函数,而最好的函数就是深度神经网络。
  • 和有监督学习不同,深度强化学习中,需要自己找更新目标。通常在马尔科夫链体系下,两个相邻状态状态差一个奖励r经常能被利用。

代码

  • Epsilon-greedy用大白话说就是:如果随机出来的值小于Epsilon这个门槛,就用greedy算法吧!如果大于,就随机。(跟Qlearning中说到的noisy-greedy差不多,都是让其有一个随机性,而不至于都是最大的Q)
  • 建议看博客

Double DQN与Dueling DQN

经验回放(Experience replay)

  • 强化学习中,相比于网络训练的速度,数据采集总是太慢,因为采集是在游戏过程中的。

  • 如果能把互动过程中的数据,都存起来,全部存在一个叫回放缓存的地方(replay buffer),当数据最够多的时候(如达到一个batch),再训练网络,那么就快很多了。

  • 训练之后继续进行游戏,继续把新产生的数据添加到回放缓存里…

  • 就这样,每次都随机抽出一个batch大小的数据训练智能体。这样,以前产生的数据同样也能用来训练数据了,效率自然更高。

固定Q目标(Fixed Q-targets)

  • DQN目标: γ max ⁡ Q ( S ′ ) + r \gamma\mathop{\max}Q(S')+r γmaxQ(S)+r

  • 目标本身包含一个Q网络,这样理论上没有问题,但是会造成Q网络的学习效率比较低,而且不稳定。

  • 如果把训练神经网络比喻成射击游戏,在target中有Q网络的话,就相当于在射击一个移动靶,因为每次射击一次,靶就会挪动一次。相比起固定的靶,无疑加上了训练的难度。

  • 那怎么解决这个问题呢?既然现在是移动靶,那么就把它弄成是固定的靶,先停止10秒。10后挪动靶再打新的靶。这就是Fixed Q-targets的思路。

在实做的时候,其实和原来的DQN一样,唯一不同点是,用两个Q网络:

  1. 原来的Q网络,用于估算 Q ( s ) Q(s) Q(s)
  2. targetQ网络, targetQ自己并不会更新,也就是它在更新的过程中是固定的,用于计算更新目标。
  3. y = r + γ max ⁡ ( t a r g e t Q ( S ′ ) ) y=r+\gamma\mathop{\max}(targetQ(S')) y=r+γmax(targetQ(S))
  4. 进行N次更新后,就把新Q的参数赋值给旧Q。

Double DQN

DQN有一个显著的问题,就是DQN估计的Q值往往会偏大。这是由于Q值是以下一个 s ′ s' s的Q值的最大值来估算的,但下一个state的Q值也是一个估算值,也依赖它的下一个state的Q值…,这就导致了Q值往往会有偏大的的情况出现。两个办法可以缓解:

  1. 第一种:形象说,如果只有一个Q网络,它经常吹牛。那就用两个Q网络,因为两个Q网络的参数有差别,所以对于同一个动作的评估也会有少许不同。选取评估出来较小的值来计算目标。这样就能避免Q网络吹牛的情况发生。
  2. 第二种:也需要用到两个Q网络。Q1网络推荐能够获得最大Q值的动作;Q2网络计算这个动作在Q2网络中的Q值。

恰好,如果用上Fixed Q-targets,不就是有两个Q网络了吗?

所以可以看到,这个优化在DQN上很容易实现。这就是doubleDQN和DQN的唯一的变化。

以上说到的经验回放等建议看原博客和[代码]!!

Dueling DQN

建议直接看博客

策略梯度(Policy Gradient)

  • DQN=TD+神经网络
  • PG=蒙地卡罗+神经网络

在神经网络出现之前,当遇到非常复杂的情况时,很难描述遇到每一种状态应该如何应对。但现在有了神经网络这么强大的武器,就可以用一个magic函数直接代替想要努力描述的规则。

如果智能体的动作是对的,那么就让这个动作获得更多被选择的几率;相反,如果这个动作是错的,那么这个动作被选择的几率将会减少。

问题在于,怎么衡量对和错呢?PG的想法非常简单粗暴:蒙地卡罗的G值!(还记得小猴子吗?)

直观感受PG算法

假设从某个state出发,可以采用三个动作,一开始智能体对动作好坏一无所知,假如采用平均策略[33%,33%,33%]

  • 选择动作A,达到最终状态后回溯,得到 G = 1 G=1 G=1
  • 让A概率,BC降低,得到[50%,25%,25%]
  • 选择B,计算得到 G = − 1 G=-1 G=1
  • 对B的评价较低,所以降低B概率,得到[55%,15%,30%]
  • 最后随机到C,得到 G = 5 G=5 G=5
  • C比A还要多得多。因此这一次更新,C的概率需要大幅提升,相对地,AB概率降低,得到[20%,5%,75%]

Actor-Critic

PG算法用到蒙地卡罗,需要完成整个游戏过程,太慢了,改成TD快一点。

Actor-Critic其实用了两个网络,两个网络有一个共同点,输入状态S:

  • 一个输出策略,负责选择动作,这个网络叫Actor;
  • 一个负责计算每个动作的分数,这个网络叫Critic。

Actor在台上跳舞,一开始舞姿并不好看,Critic根据Actor的舞姿打分。Actor通过Critic给出的分数,去学习:如果Critic给的分数高,那么Actor会调整这个动作的输出概率;相反,如果Critic给的分数低,那么就减少这个动作输出的概率。

TD-error

  • 为了避免正数陷阱,希望Actor的更新权重有正有负。因此,把Q值减去他们的均值V。有: Q ( s , a ) − V ( s ) Q(s,a)-V(s) Q(s,a)V(s)。(这步理解很关键)
  • 为了避免需要预估V值和Q值,我们希望把Q和V统一。 Q ( s , a ) = γ V ( s ′ ) + r Q(s,a) = \gamma V(s') + r Q(s,a)=γV(s)+r
  • 所以: T D − e r r o r = γ V ( s ′ ) + r − V ( s ) TD-error=\gamma V(s') + r-V(s) TDerror=γV(s)+rV(s)
  • TD-error就是Actor更新策略时,带权重更新中的权重值。
  • 现在Critic不再需要预估Q,而是预估V。而根据马可洛夫链所学,我们知道TD-error就是Critic网络需要的loss,也就是说,Critic函数需要最小化TD-error。
  • (主要看看代码理解)

PPO

AC问题一:离散到连续

PPO是基于AC架构的,也就是说,PPO也有两个网络,分别是Actor和Critic,这是因为AC架构有一个好处。这个好处就是解决了连续动作空间的问题。

  • 离散动作:就像一个个的按钮,按一个按钮就能智能体就做一个动作。就像在CartPole游戏里的智能体,只有0,1两个动作分别代表向左走,向右走。
  • 连续动作:相当于这些按钮不但有开关的概念,而且还有力度大小的概念。就像开车,不但是前进后退转弯,并且要控制油门踩多深,刹车踩多少的,转弯时候转向转多少的问题。

但这就有个问题,用神经网络预测输出的策略是一个固定的shape,而不是连续的。那又什么办法可以表示连续型的概率呢?

先假定策略分布函数服从一个特殊的分布,这个特殊的分布可以用一两个参数表示它的图像。

正态分布就是这样一个分布,他只需要两个参数,就可以表示了。

AC问题二:数据浪费

AC产生的数据,只能进行1次更新,更新完就只能丢掉,等待下一次跑游戏的数据。这可是天大的浪费。

那为什么只能用一次呢,像DQN也可以用经验回放,把以前的数据存起来,更新之后用?AC为什么就不行呢?

先清楚以下概念:

  • 行为策略:不是当前策略,用于产出数据
  • 目标策略:会更新的策略,需要被优化的策略
  • 如果两个策略同一个策略,那么称为在线策略(On Policy)
  • 如果两个策略不是同一个策略,那么称为离线策略(Off Policy)

举例:

  • 如果在智能体和环境进行互动时产生的数据打上一个标记。标记这是第几版本的策略产生的数据,例如1,2… 10
  • 现在智能体用的策略 10,需要更新到11。
  • 如果算法只能用 10版本的产生的数据来更新,那么这个就是在线策略;如果算法允许用其他版本的数据来更新,那么就是离线策略。
  • PG,就是一个在线策略。因为PG用于产生数据的策略(行为策略),和需要更新的策略(目标策略)是一致。
  • DQN则是一个离线策略。智能体在环境互动一定次数,获得数据。用这些数据优化策略后,继续跑新的数据。但老版本的数据仍然是可以用的。也就是说,产生数据的策略,和要更新的目标策略不是同一个策略。

但为什么PG和AC中的Actor更新,就不能像DQN一样,把数据存起来,更新多次呢?

答案是在一定条件下,能。PPO做的工作就是这个。在了解在什么条件下可以的时候,需要先了解一下,为什么不能。看看博客吧。

Important-sampling

PPO通过**重要性采样技术(Important-sampling)**做到离线更新策略。

N步更新

把之前的TD叫做TD(0),而N步更新为TD(n)。可以看成TD(0)其实是TD(n)的一种特殊情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

damonzheng46

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值