《Easy RL:强化学习教程》读书笔记04
DQN基本概念
Deep Q-Network是基于深度学习的Q-learning算法,其结合了 Value Function Approximation(价值函数近似)与神经网络技术,并采用了目标网络(Target Network)和经验回放(Experience Replay)的方法进行网络的训练。
状态价值函数
在基于价值的算法中,学到的不是策略,而是critic,即进行策略评估,衡量状态价值函数有两种不同的方法:基于蒙特卡洛的方法和基于时序差分的方法。基于蒙特卡洛的方法就是通过让actor与environment做交互,来让critic评价,其评价主要根据累积奖励值来的。第二种是时序差分的方法,即基于时序差分的方法。在基于蒙特卡洛的方法中,每次我们都要计算累积奖励,也就是从某一个状态一直到游戏结束的时候,得到的所有奖励的总和。但这样很受限制,得游戏结束才能更新网络,而时序差分是让前后两个状态价值函数值V(s_t)和V(s_t+1)的损失和r_t接近。
动作价值函数
这种critic称为Q函数,其输入的是一个state-action pair,输出是累积奖励的期望值。我们可以估计某一个策略的Q函数,接下来就可以找到另外一个策略π′ 比原来的策略π还要更好。
DQN的技巧
目标网络
在实现的时候,我们会把左边的 Q 网络更新多次,再用更新过的 Q 网络替换目标网络。但这两个网络不要一起更新,一起更新,结果会很容易不好。一开始这两个网络是一样的,在训练的时候,我们会把右边的 Q 网络固定住,在做梯度下降的时候,只调整左边Q网络的参数。我们可能更新 100 次以后才把参数复制到右边的网络中,把右边网络的参数覆盖,目标值就变了。就好像我们本来在做一个回归问题,训练后把这个回归问题的损失降下去以后,接下来我们把左边网络的参数复制到右边网络,这样训练更加稳定。
探索
探索是指agent对新action的探索过程。有两个方法可以解决探索-利用窘境(exploration-exploitation dilemma)问题:ε-贪心和玻尔兹曼探索(Boltzmann exploration)。
ε-贪心是指我们有 1−ε的概率会按照Q函数来决定动作,ε 的概率进行随机决定动作。
玻尔兹曼探索就比较像是 policy gradient。在 policy gradient 里面network 的output 是一个 expected action space 上面的一个的 probability distribution。再根据 probability distribution 去做 sample。所以也可以根据Q value 去定一个 probability distribution,假设某一个 action 的 Q value 越大,代表它越好,我们采取这个 action 的机率就越高。这是Boltzmann Exploration。
经验回放
经验回放会构建一个回放缓冲区(replay buffer),回放缓冲区又被称为回放内存(replay memory)。回放缓冲区是指现在有某一个策略π与环境交互,它会去收集数据,我们把所有的数据放到一个数据缓冲区(buffer)里面,数据缓冲区里面存储了很多数据。回放缓冲区只有在它装满的时候,才会把旧的数据丢掉。所以回放缓冲区里面其实装了很多不同的策略的经验。
有了回放缓冲区以后,我们怎么训练 Q 模型、怎么估 Q 函数呢?我们会迭代地训练 Q 函数,在每次迭代里面,从回放缓冲区中随机挑一个批量(batch)出来,即与一般的网络训练一样,从训练集里面挑一个批量出来。我们采样该批量出来,里面有一些经验,我们根据这些经验去更新Q函数。这与时序差分学习要有一个目标网络是一样的。我们采样一个批量的数据,得到一些经验,再去更新 Q 函数。
这么做有两个好处。第一个好处是,在进行强化学习的时候, 往往最花时间的步骤是与环境交互,训练网络反而是比较快的。因为我们用 GPU 训练其实很快,真正花时间的往往是与环境交互。用回放缓冲区可以减少与环境交互的次数,因为在做训练的时候,经验不需要通通来自于某一个策略。一些过去的策略所得到的经验可以放在回放缓冲区里面被使用很多次,被反复的再利用,这样可以比较高效地采样经验。第二个好处是,在训练网络的时候,其实我们希望一个批量里面的数据越多样(diverse)越好。如果批量里面的数据都是同样性质的,我们训练下去,训练结果是容易不好的。如果批量里面都是一样的数据,训练的时候,性能会比较差。我们希望批量里的数据越多样越好。如果回放缓冲区里面的经验通通来自于不同的策略,我们采样到的一个批量里面的数据会是比较多样的。
双深度 Q 网络(Double DQN)
在实现上,Q 值往往是被高估的。而Double DQN 可以让估测的值跟实际的值是比较接近的。DDQN 里面有两个 Q 网络,第一个 Q 网络 Q 决定哪一个动作的 Q 值最大(我们把所有的 a 代 入 Q 函数中,看看哪一个 a 的 Q 值最大)。我们决定动作以后,Q 值是用 Q′ 算出来的。假设我们有两个 Q 函数——Q和 Q′,如果Q 高估了它选出来的动作 a,只要 Q′没有高估动作 a 的值,算出来的就还是正常的值。假设 Q′高估了某一个动作的值,也是没问题的,因为只要Q不选这个动作就可以,这就是 DDQN 神奇的地方。
竞争深度 Q 网络(Dueling DQN)
其实 Dueling DQN 也蛮好做的,相较于原来的 DQN,它唯一的差别是改了网络的架构。Q-network 就是输入状态,输出就是每一个动作的 Q 值。Dueling DQN 唯一做的事情是改了网络的架构,其它的算法都不需要动。
原来的深度 Q 网络直接输出 Q 值,竞争深度 Q 网络不直接输出 Q 值,而是分成两条路径运算。第一条路径会输出一个标量V (s),因为它与输入s是有关系的,所以称为 V(s)。第二条路径会输出一个向量 A(s,a),它的每一个动作都有一个值。我们再把 V (s) 和 A(s,a) 加起来就可以得到 Q 值Q(s, a)。
优先级经验回放(Prioritized Experience Replay)
在蒙特卡洛方法和时序差分方法中取得平衡(Balance between MC and TD)
该方法也被称为多步方法,多步方法就是蒙特卡洛方法与时序差分方法的结合,因此它不仅有蒙特卡洛方法的好处与坏处,还有时序差分方法的好处与坏处。我们先看看多步方法的好处,之前只采样了某一个步骤,所以得到的数据是真实的,接下来都是 Q 值估测出来的。现在采样比较多的步骤,采样 N 个步骤才估测值,所以估测的部分所造成的影响就会比较小。当然多步方法的坏处就与蒙特卡洛方法的坏处一样,因为 r 有比较多项,所以我们把 N 项的 r 加起来,方差就会比较大。但是我们可以调整 N 的值,在方差与不精确的 Q 值之间取得一个平衡。N 就是一个超参数,我们可以对其进行调整。
噪声网络(Noisy Net)
我们还可以改进探索。ε-贪心这样的探索就是在动作的空间上加噪声,但是有一个更好的方法称为噪声网络(noisy net),它是在参数的空间上加噪声。噪声网络是指,每一次在一个回合开始的时候,在智能体要与环境交互的时候,智能体使用 Q 函数来采取动作,Q 函数里面就是一个网络,我们在网络的每一个参数上加上一个高斯噪声(Gaussian noise)。噪声在一个回合中是不能被改变的。
分布式 Q 函数(Distributional Q-function)
我们可以不只是估测得到的期望 reward 平均值的值。我们其实是可以估测一个分布的。
彩虹(Rainbow)
最后一个技巧叫做 rainbow,把刚才所有的方法都综合起来就变成 rainbow 。因为刚才每一个方法,就是有一种自己的颜色,把所有的颜色通通都合起来,就变成 rainbow。
演员-评论员算法
演员-评论员算法是一种结合策略梯度和时序差分学习的强化学习方法,其中,演员是指策略函数 πθ(a|s),即学习一个策略以得到尽可能高的回报。评论员是指价值函数 Vπ(s),对当前策略的值函数进行 估计,即评估演员的好坏。借助于价值函数,演员-评论员算法可以进行单步参数更新,不需要等到回合结束才进行更新。在演员-评论员算法里面,最知名的算法就是异步优势演员-评论员算法。如果我们去掉异步,则为优势演员-评论员(advantage actor-critic,A2C)算法。A2C算法又被译作优势演员-评论员算法。如果我们加了异步,变成异步优势演员-评论员算法。
优势演员-评论员算法
优势演员-评论员算法的流程如图所示,我们有一个 π,有个初始的演员与环境交互,先收集资料。在策略梯度方法里收集资料以后,就来更新策略。但是在演员-评论员算法里面,我们不是直接使用那些资料来更新策略。我们先用这些资料去估计价值函数,可以用 时序差分方法 或 蒙特卡洛方法 来估计价值函数。接下来,我们再基于价值函数,有了新的 π 以后,再与环境交互,收集新的资料,去估计价值函数。再用新的价值函数更新策略,更新演员。整个优势演员-评论员算法就是这么运作的。
异步优势演员-评论员算法
异步优势演员-评论员算法同时使用很多个进程(worker),如果我们没有很多 CPU,不好实现异步优势演员-评论员算法,但可以实现优势演员-评论员算法。
异步优势演员-评论员算法的运作流程如图所示,异步优势演员-评论员算法一开始有一个全局网络(global network)。全局网络包含策略网络和价值网络,这两个网络是绑定(tie)在一起的,它们的前几个层会被绑在一起。 我们使用多个进程,每个进程用一张 CPU 去跑。比如我们有 8 个进程,则至少 8 张 CPU。每一个进程在工作前都会把全局网络的参数复制过来。接下来演员就与环境交互,每一个演员与环境交互的时候,都要收集到比较多样的数据。例如,如果是走迷宫,可能每一个演员起始的位置都会不一样,这样它们才能够收集到比较多样的数据。每一个演员与环境交互完之后,我们就会计算出梯度。计算出梯度以后,要用梯度去更新参数。我们就计算一下梯度,用梯度去更新全局网络的参数。就是这个进程算出梯度以后,就把梯度传回给中央的控制中心,中央的控制中心就会用这个梯度去更新原来的参数。
注意,A3C使用了平行探索的方法,所有的演员都是平行跑的,每一个演员各做各的,不管彼此。所以每个演员都是去要了一个参数以后,做完就把参数传回去。
路径衍生策略梯度
一开始会有一个策略 π,它与环境交互并估计 Q 值。估计完 Q 值以后,我们就把 Q 值固定,只去学习一个演员。假设这个 Q 值估得很准,它知道在某一个状态采取什么样的动作会得到很大的Q值。接下来就学习这个演员,演员在给定 s 的时候,采取了a,可以让最后Q函数算出来的值越大越好。我们用准则(criteria)去更新策略 π,用新的 π 与环境交互,再估计 Q值,得到新的 π 去最大化 Q值的输出。深度Q网络 里面的技巧,在这里也几乎都用得上,比如经验回放、探索等技巧。
第六章习题:https://datawhalechina.github.io/easy-rl/#/chapter6/chapter6_questions&keywords
第七章习题:https://datawhalechina.github.io/easy-rl/#/chapter7/chapter7_questions&keywords
第八章习题:https://datawhalechina.github.io/easy-rl/#/chapter8/chapter8_questions&keywords
第九章习题:https://datawhalechina.github.io/easy-rl/#/chapter9/chapter9_questions&keywords