因此,即使先前状态的资格跟踪值不为零,在上述情况下,delta 的值也将为零(因为最初的奖励和效用函数被初始化为 0)。那么先前的状态如何在第一次更新时获得除零以外的其他效用值?
你说得对,第一次更新,所有奖励和更新仍然是0(除非我们已经设法一步达到目标,那么奖励就赢了'不要是0)。
但是,资格跟踪e_t 将继续“记住”或“记住”我们之前访问过的所有状态。因此,一旦我们确实设法达到目标状态并获得非零奖励,资格跟踪仍将记住我们经历的所有状态。这些州在资格跟踪表中仍将有非零条目,因此一旦您观察到您的第一个奖励,就会立即获得非零更新。
资格跟踪表在每个时间步都衰减(乘以gamma * lambda_),因此很久以前访问过的状态的更新量将小于更新量对于我们最近访问过的状态,但我们将继续记住所有这些状态,它们将具有非零条目(假设 gamma > 0 和 lambda_ > 0)。这允许更新所有访问过的状态的值,不是在我们到达这些状态时,而是在我们观察到非零奖励时 /strong>(或者,在第一个 epoch 之后的 epoch 中,一旦我们达到我们已经有一个现有的非零预测值的状态)在某个较早的时间点访问过它们之后 .
同样在给定的python实现中,单次迭代后给出以下输出:
[[ 0. 0.04595 0.1 0. ]
[ 0. 0. 0. 0. ]
[ 0. 0. 0. 0. ]]
这里只更新了 2 个值,而不是如图所示的所有 5 个之前的状态。我在这里缺少什么?
他们的代码的第一部分如下所示:
for epoch in range(tot_epoch):
#Reset and return the first observation
observation = env.reset(exploring_starts=True)
因此,每个新纪元,他们首先使用exploring_starts 标志重置环境。如果我们查看the implementation of their environment,我们会看到该标志的使用意味着我们总是以随机初始位置开始。
因此,我怀疑,当运行代码以生成该输出时,初始位置只是随机选择为目标左侧两步的位置,而不是左下角的位置。如果初始位置被随机选择为已经更接近目标,则代理只会访问您看到非零更新的那两个状态,因此这些也是资格表中唯一具有非零条目的状态跟踪,因此是唯一具有非零更新的状态。
如果初始位置确实是左下角的位置,那么算法的正确实现确实会更新该路径上所有状态的值(假设没有添加额外的技巧,例如将条目设置为 @987654333 @如果他们碰巧因为衰减而“足够接近”0)。
我还想指出,该页面上的代码实际上存在错误:在重置环境/开始新纪元时,他们没有将资格跟踪表的所有条目重置为 0 .应该这样做。如果不这样做,资格跟踪仍将记住在先前 epoch 期间访问过的状态,并且仍然更新所有这些状态,即使它们在新 epoch 中没有再次访问。这是不正确的。他们的代码的正确版本应该是这样开始的:
for epoch in range(tot_epoch):
#Reset and return the first observation
observation = env.reset(exploring_starts=True)
trace_matrix = trace_matrix * 0.0 # IMPORTANT, added this
for step in range(1000):
...