Dyna-Q 算法,添加模拟体验时遇到问题

人工智能 强化学习
2021-11-15 01:55:12

我正在尝试在 python 中创建一个简单的 Dyna-Q 代理来解决小迷宫。对于 Q 函数 Q(s, a),我只是使用一个矩阵,其中每一行代表一个状态值,每一列代表 4 个动作之一(上、下、左、右)。

我已经实现了“真实体验”部分,基本上就是直截了当的 SARSA。它在 2000-8000 步中解决了一个中等难度(即必须绕过一些障碍)的迷宫(在第一集中,它无疑会随着更多而减少)。所以我知道那部分工作可靠。

现在,根据它对模型的了解添加模拟体验的部分以更多地更新 Q 值,我遇到了麻烦。我这样做的方式是保留一个experiences列表(很像经验回放),每次我采取实际行动时,我都会将其(S,A,R,S')添加到该列表中。

然后,当我想模拟一种体验时,我从该列表中随机抽取一个 (S, A, R, S') 元组(David Silver 在他的讲座 (#8) 中提到,您可以更新您的转移概率矩阵P 和奖励矩阵 R 通过改变它们的值或者只是从经验列表中采样,这应该是等价的)。就我而言,对于给定的 S 和 A,由于它是确定性的,因此 R 和 S' 也将与我从元组中采样的相同。然后我计算 Q(S, A) 和 max_A'(Q(S', A')),得到 TD 误差(同上),并用它做随机梯度下降来改变 Q(S, A)正确的方向。

但它不起作用。当我添加模拟体验时,它永远找不到目标。我试着四处寻找原因,我所看到的奇怪的是 Q 值随着时间的推移不断增加(而没有经验,它们会适应正确的值)。

有人对我可以尝试的事情有任何建议吗?我查看了采样体验、体验循环中的 Q 值、渐变等……除了 Q 值增长之外,没有什么特别突出的。

编辑:这是代码。第一部分(一步 TD 学习)效果很好。添加计划循环部分搞砸了。

def dynaQ(self, N_steps=100, N_plan_steps=5):

    self.initEpisode()
    for i in range(N_steps):
        #Get current state, next action, reward, next state
        s = self.getStateVec()
        a = self.epsGreedyAction(s)
        r, s_next = self.iterate(a)
        #Get Q values, Q_next is detached so it doesn't get changed by the gradient
        Q_cur = self.Q[s, a]
        Q_next = torch.max(self.Q[s_next]).detach().item()
        TD0_error = (r + self.params['gamma']*Q_next - Q_cur).pow(2).sum()
        #SGD
        self.optimizer.zero_grad()
        TD0_error.backward()
        self.optimizer.step()
        #Add to experience buffer
        e = Experience(s, a, r, s_next)
        self.updateModel(e)

        for j in range(N_plan_steps):

            xp = self.experiences[randint(0,len(self.experiences)-1)]
            Q_cur0 = self.Q[xp.s, xp.a]
            Q_next0 = torch.max(self.Q[xp.s_next]).detach().item()
            TD0_error0 = (xp.r + self.params['gamma']*Q_next0 - Q_cur0).pow(2).sum()

            self.optimizer.zero_grad()
            TD0_error0.backward()
            self.optimizer.step()
0个回答
没有发现任何回复~