9

我正在从这篇文章中学习时间差异学习。这里 TD(0) 的更新规则对我来说很清楚,但是在 TD(λ) 中,我不明白所有先前状态的效用值是如何在一次更新中更新的。

这是用于比较机器人更新的图表:

在此处输入图像描述

上图解释如下:

在 TD(λ) 中,由于资格跟踪,结果被传播回所有先前的状态。

我的问题是,即使我们使用具有资格跟踪的以下更新规则,如何在一次更新中将信息传播到所有先前的状态?

在此处输入图像描述

在一次更新中,我们只更新单个状态Ut(s)的实用程序,那么之前所有状态的实用程序是如何更新的呢?

编辑

根据答案,很明显,此更新适用于每一步,这就是传播信息的原因。如果是这种情况,那么它再次让我感到困惑,因为更新规则之间的唯一区别是资格跟踪。

因此,即使先前状态的资格跟踪值不为零,在上述情况下,delta 的值也将为零(因为最初奖励和效用函数初始化为 0)。那么,先前的状态如何在第一次更新时获得除零以外的其他效用值?

同样在给定的 python 实现中,在单次迭代后给出以下输出:

 [[ 0.       0.04595  0.1      0.     ]
 [ 0.       0.       0.       0.     ]
 [ 0.       0.       0.       0.     ]]

这里只更新了 2 个值,而不是如图所示的所有 5 个先前状态。我在这里缺少什么?

4

3 回答 3

3

因此,即使先前状态的资格跟踪值不为零,在上述情况下,delta 的值也将为零(因为最初奖励和效用函数初始化为 0)。那么,先前的状态如何在第一次更新时获得除零以外的其他效用值?

你是对的,在第一次更新中,所有的奖励和更新仍然是0(除非我们已经设法一步达到目标,那么奖励将不会是0)。

但是,资格痕迹e_t将继续“记住”或“记住”我们之前访问过的所有状态。因此,一旦我们确实设法达到目标状态并获得非零奖励,资格跟踪仍将记住我们经历的所有状态。这些状态在资格跟踪表中仍将具有非零条目,因此一旦您观察到第一个奖励,就会立即获得非零更新。

资格跟踪表在每个时间步都会衰减(乘以gamma * lambda_),因此很久以前访问过的状态的更新幅度将小于我们最近访问过的状态的更新幅度,但我们将继续记住所有这些状态,它们将有非零条目(假设gamma > 0lambda_ > 0)。这允许更新所有访问状态的值,而不是在我们到达那些状态时,而是在我们观察到非零奖励时(或者,在第一个时期之后的时期中,一旦我们达到一个状态在某个较早的时间点访问它们之后,我们已经有一个现有的非零预测值).


同样在给定的 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标志重置环境。如果我们看一下他们的环境的实现,我们会看到这个标志的使用意味着我们总是从一个随机的初始位置开始。

因此,我怀疑,当运行代码以生成该输出时,初始位置只是随机选择为目标左侧两步的位置,而不是左下角的位置。如果初始位置被随机选择为已经更接近目标,则代理只会访问您看到非零更新的那两个状态,因此这些也是资格表中唯一具有非零条目的状态跟踪,因此是唯一具有非零更新的状态。

如果初始位置确实是左下角的位置,那么算法的正确实现确实会更新沿该路径的所有状态的值(假设没有添加额外的技巧,例如将条目设置为0如果它们碰巧得到“足够接近”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):
        ...
于 2018-09-05T09:39:31.973 回答
2

您缺少一个小而重要的细节,更新规则适用于所有状态,而不仅仅是当前状态。因此,在实践中,您正在更新所有e_t(s)不为零的状态。

编辑

delta不是零,因为是针对当前状态计算的,当情节结束并且代理收到 +1 的奖励时。因此,在计算一个delta与零不同的值之后,您可以使用该值delta和当前的资格跟踪来更新所有状态。

我不知道为什么在 Python 实现中(我没有仔细检查过)输出只更新了 2 个值,但是请验证所有 5 个先前状态的资格跟踪都不是 0,如果不是这样,试着理解为什么。有时您对将迹线保持在非常小的阈值(例如,10e-5)下不感兴趣,因为它在学习过程中的影响非常小并且浪费了计算资源。

于 2018-09-02T13:16:39.333 回答
0

可以看出,使用 δ 来计算状态效用。但是,δ 使用下一个状态的效用,如文章中所示。这意味着对于 TD(0),它将更新所有状态,因为要计算 Ut(s),我们需要计算下一个状态的 U,依此类推。

  • 同时资格跟踪正在使用以前州的资格跟踪
  • 在资格跟踪中,由于 gamma 为 0.999(小于 1),lambda = 0.5 乘以 gamma 和 lamba 使效用大幅下降,
  • 通过仅在当前时间 t 的状态中添加 +1 来获得权重。
  • 这意味着我们越接近当前状态,我们拥有的权重就越大,因此乘数越大
  • 并且越远,乘数越少越小。

在 TD(λ) 中,在计算中添加合格迹线时也会有额外的减少 以上得出的结论是,先前的值在第一次迭代中为 0,因为所有效用在开始时为 0,而在更新时在 TD(λ) 中他们通过资格跟踪得到了更大的减少。你可以说它们非常小,太小而无法计算或考虑。

于 2018-09-06T22:48:16.987 回答