进阶篇---DQN的改良

进阶篇—DQN的改良

代码参见我的GitHub

DDQN

也叫 Double DQN。之前我们提到的DQN方法目标Q值是通过贪婪法直接得到的,虽然使用max虽然可以快速让Q值向可能的优化目标靠拢,但是很容易过犹不及,导致过度估计。为了解决这个问题, DDQN通过解耦目标Q值动作的选择和目标Q值的计算这两步,来达到消除过度估计的问题。

简单来说,就是通过多增加一个网络来降低迭代过程中Q网络的关联性,其余步骤和传统DQN方法基本没有区别。
这是传统的DQN方法

这是DDQN方法
reward和loss

Prioritized Replay DQN

之前的DQN方法中,我们在replay buffer中进行随机采样,这意味着无论经验好坏新旧,对于这些经验我们一视同仁。但是在经验回放池里面的不同的样本由于TD误差的不同,对我们反向传播的作用是不一样的。TD误差越大,那么对我们反向传播的作用越大。而TD误差小的样本,由于TD误差小,对反向梯度的计算影响不大。在Q网络中,TD误差就是目标Q网络计算的目标Q值和当前Q网络计算的Q值之间的差距。如果我们总是能采样到TD误差较大的样本,那么我们的网络收敛速度不就可以更快了嘛。
Prioritized Replay DQN根据每个样本的TD误差绝对值,给定该样本的优先级。因此,损失函数多了一个系数 w j w_j wj
在这里插入图片描述
其中 w j w_j wj计算方法如下
在这里插入图片描述


class NaivePrioritizedBuffer(object):
    def __init__(self, capacity, prob_alpha=0.6):
       ... 
    def push(self, state, action, reward, next_state, done):
       ... 
    def sample(self, batch_size, beta=0.4):
        if len(self.buffer) == self.capacity:
            prios = self.priorities
        else:
            prios = self.priorities[:self.pos]
        probs  = prios ** self.prob_alpha
        probs /= probs.sum() 
        indices = np.random.choice(len(self.buffer), batch_size, p=probs)
        samples = [self.buffer[idx] for idx in indices]
        #权重的计算部分
        total    = len(self.buffer)
        weights  = (total * probs[indices]) ** (-beta)
        weights /= weights.max()
        weights  = np.array(weights, dtype=np.float32)
        
        batch       = zip(*samples)
        states      = np.concatenate(batch[0])
        actions     = batch[1]
        rewards     = batch[2]
        next_states = np.concatenate(batch[3])
        dones       = batch[4]
        return states, actions, rewards, next_states, dones, indices, weights
    
    def update_priorities(self, batch_indices, batch_priorities):
        ...
    def __len__(self):
        ...

Dueling-DQN

DDQN优化目标Q值,Prioritized Replay DQN优化replay buffer, 而Dueling DQN中,则是尝试通过优化神经网络的结构来优化算法
思路很简单,将原来的Q函数拆分为两部分----价值函数 V ( S , w , α ) V(S,w, \alpha) V(S,w,α)和优势函数 A ( S , A , w , β ) A(S,A,w, \beta) A(S,A,w,β)其中 w w w是公共部分的网络参数,而 α \alpha α是价值函数独有部分的网络参数,而 β \beta β是优势函数独有部分的网络参数。

需要改动的代码也很少

class DuelingDQN(nn.Module):
    def __init__(self, observation_space, action_sapce):
        super(DuelingDQN, self).__init__()
        self.observation_space = observation_space
        self.action_sapce = action_sapce
        #######################改动部分#############################
        self.feature = nn.Sequential(
            nn.Linear(observation_space,128),
            nn.ReLU()
        )
        self.advantage = nn.Sequential(
            nn.Linear(128, 128),
            nn.ReLU(),
            nn.Linear(128, action_sapce),
        )
        self.value = nn.Sequential(
            nn.Linear(128,128),
            nn.ReLU(),
            nn.Linear(128,1),
        )
    def forward(self, x):
        ...
    def act(self, state, epsilon):
        ...

可以看到,效果好了很多
在这里插入图片描述

D3QN

Dueling DQN 与Double DQN相互兼容,一起用效果很好。简单,泛用,没有使用禁忌。任何一个刚入门的人都能独立地在前两种算法的基础上改出D3QN。
在这里插入图片描述

NoisyNet

一种将参数化的噪音加入到神经网络权重上去的方法来增加强化学习中的探索,称为 NoisyNet
噪音的参数可以通过梯度来进行学习,非常容易就能实现,而且只增加了一点计算量,在 A3C ,DQN 算法上效果不错。其思想很简单,就是在神经网络的权重上增加一些噪音来起到探索的目的。
在这里插入图片描述

Rainbow DQN

各种DQNtrick的集大成者

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值