Skip to content

DDQN 的代码实现不正确 #7

@RocStone

Description

@RocStone

以下是 repo 中 DDQN 的实现,可以看到target NN 在计算下一个状态的 next Q value的时候,使用的 action 并不是用self.model得到的,而是直接用 target NN 在下一个状态时最大的价值的动作,这种实现方式是基本的target network + DQN 而不是真正的 DDQN

class DoubleDQN:
    def __init__(self, dim_obs=None, num_act=None, discount=0.9):
        self.discount = discount
        self.model = QNet(dim_obs, num_act)
        self.target_model = QNet(dim_obs, num_act)
        self.target_model.load_state_dict(self.model.state_dict())

    def get_action(self, obs):
        qvals = self.model(obs)
        return qvals.argmax()

    def compute_loss(self, s_batch, a_batch, r_batch, d_batch, next_s_batch):
        # Compute current Q value based on current states and actions.
        qvals = self.model(s_batch).gather(1, a_batch.unsqueeze(1)).squeeze()
        # next state的value不参与导数计算,避免不收敛。
        next_qvals, _ = self.target_model(next_s_batch).detach().max(dim=1)
        loss = F.mse_loss(r_batch + self.discount * next_qvals * (1 - d_batch), qvals)
        return loss

真正的 DDQN 应该改写成

    def ddqn_compute_loss(self, s_batch, a_batch, r_batch, d_batch, next_s_batch):
        # Compute current Q value based on current states and actions.
        qvals = self.model(s_batch).gather(1, a_batch.unsqueeze(1)).squeeze()
        next_s_action = self.model(next_s_batch).argmax(dim=1)
        next_qvals, _ = self.target_model(next_s_batch).gather(1, next_s_action.unsqueeze(1)).detach().max(dim=1)
        loss = F.mse_loss(r_batch + self.discount * next_qvals * (1 - d_batch), qvals)
        return loss

经过原始代码测试,eval 时前者平均 reward 是-142.57142857142858,后者是-138.25
可见确实是 DDQN 的效果更好,但是经过观察,DDQN 训练可能需要更多的时间,如果我把max step 设置成 20W
结果反而是 DDQN 更差,这非常诡异
诡异 2:我重新测试了一次 max step = 10w,结果发现这次原compute loss 的方法直接训崩了,avg reward = -200,DDQN 的 avg reward 高达-136,这得出第二个结论,DQN 的训练太不稳定了

我把 ER 改成 PER,结果依然非常不稳定,有时候 PER 更好,有时候 ER 更好,就离谱,RL 真的太不稳定了,哪怕是我这里的 DDQN 也不一定比前面那个版本更好

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions