GAE: почему GAE работает хуже, чем нормализованный доход и преимущества - PullRequest
0 голосов
/ 05 февраля 2019

Я внедряю PPO с GAE в качестве преимуществ.В следующем коде я вычисляю 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

Стоит отметить, что values имеет на один элемент больше, чем другие массивы, такие как rewards, так что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+ в gym среде LunarLanderContinuous-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

1 Ответ

0 голосов
/ 07 февраля 2019

Ваш код для вычисления преимущества кажется правильным.Что делает 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
...