找回密码
 立即注册
查看: 202|回复: 0

强化学习笔记 -5 DQN与其改进算法

[复制链接]
发表于 2022-8-7 16:10 | 显示全部楼层 |阅读模式
一.深度强化学习

在传统的强化学习方法中存在着几点缺点:

  • 对于连续的状态与较大的状态空间,会导致传统的QLearning算法的维度灾难(表格太大,画不下,占用存储空间)
  • 对于没有见过的状态,会产生错误的判断(现实应用中,以游戏为例,总是出现之前未出现过的画面)
为了解决以上的问题,让强化学习应用更加广泛,提出了利用神经网络代替表格的方法(查表是输入一个状态值,输出一个动作,神经网络也是这样的),带领强化学习进入一个新的高度。
二.利用神经网络代替表格

对一个神经网络来说,最重要的就是网络结构与其对应功能和代价函数。
1.价值网络的建立——功能代替

我们想要神经网络实现的功能:输入一个状态,获得该状态对应的所有动作的价值
对于一个神经网络来说最重要的两个要素:网络结构和代价函数,接下来我将展示怎么构建价值网络
class Qnet(torch.nn.Module):
    def __init__(self, state_dim, hidden_dim, action_dim):
        super(Qnet, self).__init__()
        self.fc1 = torch.nn.Linear(state_dim, hidden_dim)
        self.fc2 = torch.nn.Linear(hidden_dim, action_dim)

    def forward(self, x):
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x)
        return x此处将价值网络定义为简单的全连接神经网络,其中输入为状态的维度,输出为动作的维度。
2.价值网络的更新——更新方法代替

在传统的表格型方法中(以QLearning为例),在作出一个动作 a 后,环境给与奖励 r 与下一状态 s' 后,可以利用该三元素,通过bootstrapping的迭代公式 进行表格的更新
Q(s, a)\leftarrow Q(s,a)+ \alpha(r+\gamma Q(s', a^*)-Q (s,a)),a* = argmax_a(Q(s', a))
其中,td-target为 r + \gamma Q(s', a*) (相较于当前的价值函数更接近现实,因为增加了准确的 r ,未知+正确>未知),td-error为 Q(s,a)-td target ,我们为了让当前的价值更加接近target,就会让td-error更小。
为了达到这种效果,我们将神经网络的代价函数(损失函数)构造为均方误差的形式
L_\theta=\frac{1}{2} \frac{1}{N}\sum_{i=0}^N [Q(s, a|\theta)-\alpha(r+\gamma Q(s',a^*))]^2  (其中二分之一纯纯的是形式,无实际意义,要是说有意义大概就是简化后续计算,和求梯度得到的2乘没了,N是batchsize,采N次数据进行一次梯度回传)
这样,就可以更新价值网络。
3.DQN流程伪代码

随机初始化网络参数theta,state
重复进行:
    利用当前状态,当前Q网络与环境进行交互N次,得到(s, a, r, s_next)*N
    更新网络三.传统算法存在的问题

1.传统DQN存在问题——非均匀高估




不同环境中,传统算法产生的高估

高估,指的是对于Q(s,a)的Q-learning估计值往往高于真实值。如果大家都被均匀的高估了,也没关系,选择的最优动作还是原来的,如果被非均匀高估,则会该选择带来影响,如下图磨菇书中举例,非均匀高估会造成实际Q值较大的反而估计出来较小 。                           


产生非均匀高估的原因有两点,噪声+max操作时起因,bootstrapping放大了影响
神经网络进行拟合时往往会出现误差,假设其为高斯分布误差。
(1)max操作产生的高估
我们希望通过bootstrapping的方法得到符合贝尔曼最优方程的Qnet/table满足: Q_*(s,a)=\sum_{s',r}p(s',r|s,a)[r+\gamma max_{a'}Q_*(s',a')] ,存在误差时,价值函数变为期望形式 Q_*(s,a)=\sum_{s',r}p(s',r|s,a)[r+\gamma max_{a'}E[Q_*(s',a')+\epsilon]]=\sum_{s',r}p(s',r|s,a)[r+\gamma max_{a'}E[Q_*(s',a')]] 由于 \epsilon 是服从高斯的(无偏的)不改变原值。但是根据原始的Q-Learning通过采样方法更新时,采样N个样本 (s,a,r,s_{next}) ,假设其中有M个 (s_1, a_1, r, a_{next1}) ,在利用其更新Q-tabel时,取得Q的估计数值是 \frac{1}{N}(max_a(Q(s_{next1},a)+\epsilon))=E[max_a(Q(s_{next_1},a)+\epsilon]<max_aE[Q(s_{next1}, a)+\epsilon]
在进行max操作时,噪声会影响取值,造成
E[min(a+\epsilon)]\leq minE[a+\epsilon]=maxE[a+\epsilon]\leq E[max(a+\epsilon)]
max放大了正值噪声的作用,使得拥有正值噪声的Q值被高估
所以,想要减少高估,就要优化max这一操作
(2)bootstapping放大高估作用
众所周知,使用bootstrapping方法更新参数会利用之前的数据,但是之前的数据已经存在高估的问题,并且这一问题会随着迭代而慢慢积累,造成极度的非均匀高估,通过避免bootstapping也可以减少高估问题。
2.交互资源的浪费

强化学习需要大量的交互数据,但是传统的DQN将用过的数据直接舍弃,造成了不必要的浪费.
四.改进的DQN算法

1.replaybuffer

为了解决DQN存在的资源浪费情况,我们会使用一个缓冲区来储存很多的 (s, a, r, s_{next}) ,每进行一步交互,得到一份数据之后,将其放入缓冲区内,更新网络时拿出batchsize条数据(N)进行上述形式的loss计算与网络的更新。这样的操作节省了很多智能体与环境进行交互的时间,大大提升了资源的利用效率与训练的速度。
2.优先经验回放

对于计算出loss较大的数据,我们增加他们的抽取概率
3.target-network

QLearning,包括DQN,目的是需要让当前的估计 Q(s,a) 不断接近 td-target:r+\gamma Q(s',a^*) ,是一个追逐的过程,追踪一个固定的目标和追踪一个不停运动的目标相比,往往更加能够找到方向。拿《Easy RL》上的例子举例:
我们可以通过猫追老鼠的例子来直观地理解固定目标网络的目的。猫是 Q 估计,老 鼠是 Q 目标。一开始,猫离老鼠很远,所以我们想让猫追上老鼠。如图 6.10b 所示,因为 Q 目标也是与 模型参数相关的,所以每次优化后,Q 目标也会动。这就导致一个问题,猫和老鼠都在动。如图 6.10c 所 示,猫和老鼠会在优化空间里面到处乱动,这会产生非常奇怪的优化轨迹,使得训练过程十分不稳定。所 以我们可以固定 Q 网络,让老鼠动得不那么频繁,可能让它每 5 步动一次,猫则是每一步都在动。如果 老鼠每 5 次动一步,猫就有足够的时间来接近老鼠,它们之间的距离会随着优化过程越来越小,最后它们 就可以拟合,拟合后就可以得到一个最好的 Q 网络。


因为这点,我们就想要暂时固定所谓的猫:td-target,即需要利用另外一个神经网络,我们称之为target-network保存过去的Q(s,a)并生成数据 Q(s',a^*) ,并且每隔C步就进行一次更新,将当前的target-network的参数更新为当前的Q-net。
所以现在我们要维护两个网络,分别是Qnet Q(s,a|\theta) 与targetnet Q(s,a|\theta')
并且,这样的方法其实并没有使用bootstapping,可以缓解产生的高估问题。
4.doubleDQN
我们在进行更新网络时利用的公式 Q(s, a)\leftarrow Q(s,a)+ \alpha(r+\gamma Q(s', a^*)-Q (s,a)),a* = argmax_a(Q(s', a)) 可以分为两个部分,分别是最优动作 a^* 的选择和target的求值,在这里我们总结一下传统DQN,targetnetwork并提出新的doubleDQN,原理稍后介绍

  • 对于传统的DQN来说
a^* = \mathop{\mathrm{argmax}}\limits_{a\in \mathcal{A}}Q(s,a|\theta)
target = r + \gamma Q(s', a^*|\theta)
存在的问题:高估,收敛困难
2. target network中:
a^* = \mathop{\mathrm{argmax}}\limits_{a\in \mathcal{A}}Q(s,a|\theta’)
target = r + \gamma Q(s', a^*|\theta ’)
不再使用bootstrapping,能够减轻高估问题;间接固定target,快速收敛
3.  DDQN中:
a^* = \mathop{\mathrm{argmax}}\limits_{a\in \mathcal{A}}Q(s,a|\theta ’)
target = r + \gamma Q(s', a^*|\theta)
解决了max导致的高估问题
先说下蘑菇书《easy rl》里面的解释,虽然我认为不严谨,甚至是错误的,如果有大佬能够理解他所说的,能用更严谨的话总结欢迎在评论区提出自己的看法。
原理:如果Qnet存在高估,会选择出动作a,但是在计算target时利用的是targetnet,其中的值是正确的,所以算出结果也不会存在高估问题
如果Qnet正常选择到一个最优动作a,targetnet存在高估,但是我们选择到的a可能不会是发生高估的a
其次是我比较信服的一种说法:
{Q(s',a^*|\theta') }\leq {max\\a}Q(s',a|\theta') (因为 a^* 是从 Q_{\theta} 中取出,可能会存在高估或者噪声,可能会与targetnet中的最佳动作不同,非最佳动作的价值函数小于最佳动作,所以不等式恒成立),左面是DDQN得到的,右面是targetnetwork得到的,这一缩小就减小了高估的影响。
但是,这两种方法尽管从自举与max操作的角度抑制了高估,但是并未完全消除
4.dueling-network

在这之前,价值网络输出为动作价值函数 Q(s,a) ,在本节,将网络进行改造,使其输出状态价值函数 V(s) 和优势函数 A(s,a) 。优势函数代表了同一状态下,不同动作的相对优劣。二者相加即为状态价值函数。


上面图片中,第一个网络代表着原来的naturalQnet,下面的就是我们将其改变后的样子。
在这种情况下,原来进行一次梯度回传只能够改变一个值Q,但是现在可以同时改变优势函数和状态价值函数。这样做有什么好处?在假又是函数不变的情况下,仅仅改变状态价值函数的值,就可以更新在该状态下所有动作价值函数,这意味着我们即使不能够采样到所有的动作-价值对,也可以高效的估计Q值。
但是会出现一种极端的情况,就是V==0,Q=A。为了避免该情况发生,我们要对A添加约束。最直观的就是同一状态下,所有动作的优势加起来为0,即计算Q时构造 A(s,a)\leftarrow A(s,a)-meanA(s,a) ,减去均值即可实现上述。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-5 15:40 , Processed in 0.089875 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表