GAE:为什么GAE的表现比标准化的回报和优势更差

问题描述 投票:2回答:2

我正在用GAE实现PPO作为优势。以下代码是我计算GAE的方式,并根据OpenAI的基线实现返回。

advantages = np.zeros_like(rewards)
last_adv = 0
for i in reversed(range(len(rewards))):
    delta = rewards[i] + nonterminals[i] * self._gamma * values[i+1] - values[i]
    advantages[i] = last_adv = delta + nonterminals[i] * gamma * lam * last_adv
returns = advantages + values[:-1]
advantages = normalize(advantages) # normalize advantages

值得注意的一点是,valuesrewards等其他数组还有一个元素,因此values[-1]可以用作额外的下一个状态。然而,这种实现方式比简单归一化的返回和下面给出的优点更糟糕

returns = rewards
next_return = 0
for i in reversed(range(len(rewards))):
    returns[i] = rewards[i] + nonterminals[i] * gamma * next_return
    next_return = returns[i]

# normalize returns and advantages
values = normalize(values[:-1], np.mean(returns), np.std(returns))
advantages = normalize(returns - values)
returns = normalize(returns)

在不改变任何其他内容的情况下,上述实施不断达到270+环境gymLunarLanderContinuous-v2的平均得分。另一方面,GAE实施从未达到超过100得分。请参阅下图中的示例,其中使用规范化实现enter image description here运行更好的示例

我的实施有什么问题?

另外,这是normalize的代码

def normalize(x, mean=0., std=1., epsilon=1e-8):
    x = (x - np.mean(x)) / (np.std(x) + epsilon)
    x = x * std + mean

    return x
python numpy reinforcement-learning
2个回答
0
投票

您计算优势的代码似乎是正确的。 normalize做什么?通常,您将数据标准化,这意味着您减去其平均值并除以其标准差。我问,因为在你的代码的第二部分你传递返回函数normalize的均值和标准差,而在第一部分你没有。

另外,为什么在代码的第二部分使用values规范化returns?这对我来说似乎很奇怪。

最后,你如何培养你的V功能? (我假设values包含V值)。我发现学习如下

    for epoch in range(epochs_v):
        v_values = ... # compute your values using V
        a_values = ... # compute A as in your code
        target_values = v_values + a_values # generalized Bellman operator
        # optimize V on your dataset with minibatches and ADAM

效果比“一次性”更好

    v_values = ... # compute your values using V
    a_values = ... # compute A as in your code
    target_values = v_values + a_values # generalized Bellman operator
    # fit V to target_values

0
投票

我认为您的折扣退货或GAE代码没有任何问题。但是,我不明白在打折返回或GAE计算之后是否有必要使用normalize函数。我会建议如下:

1)您可以在计算折扣退货或GAE之前直接尝试对rewards进行标准化。

2)您可以使用来自OpenAI基线的类running_mean_std进行方差计算,您可以将奖励标准化,然后在将处理后的奖励传递给折扣退货或GAE函数之前,通过在特定时间间隔内对其进行标准化来对它们进行标准化。

例:

假设running_stats_r是类RunningMeanStd的对象。

running_stats_r.update(np.array(buffer_r))

buffer_r = np.clip( (np.array(buffer_r) - running_stats_r.mean) / running_stats_r.std, -stats_CLIP, stats_CLIP )

[-stats_CLIP, stats_CLIP]可以是间隔,比如介于-10到10之间。

© www.soinside.com 2019 - 2024. All rights reserved.