簡體   English   中英

演員評論家政策損失歸零(沒有改善)

[英]actor critic policy loss going to zero (with no improvement)

我創建了一個演員評論模型來測試一些OpenAI健身房環境。 但是,我在某些環境中遇到問題。

CartPole:該模型最終收斂並獲得最大獎勵。 但是,由於某些原因,如果我只使用策略梯度方法而不是值函數/優勢,它會收斂得更快。

MountainCar,Acrobot:這兩個型號都有負面獎勵。 如果你的經紀人需要10秒來解決任務,你的獎勵將是-10。 出於某種原因,當我試圖解決負面回報的環境時,我的政策從負值開始並慢慢收斂到0.價值損失開始荒謬地高並且開始減少,盡管它在某個時候(當政策崩潰時)處於平穩狀態。 任何人都可以幫我診斷問題嗎? 我添加了一些帶有相關情節值的日志記錄語句。

from scipy.signal import lfilter
import numpy as np
import gym
import tensorflow as tf

layers = tf.keras.layers

tf.enable_eager_execution()


def discount(x, gamma):
    return lfilter([1], [1, -gamma], x[::-1], axis=0)[::-1]


def boltzmann(probs):
    return tf.multinomial(tf.log(probs), 1)


def greedy(probs):
    return tf.argmax(probs)


def gae(bval, vals, rews):
    vboot = np.hstack((vals, bval))
    return rews * vboot[1:] - vals


class PG(tf.keras.Model):

    def __init__(self, n_actions, selection_strategy=boltzmann, lr=0.001):
        super(PG, self).__init__()
        self.fc1 = layers.Dense(64, activation='relu', kernel_initializer=tf.initializers.orthogonal(1))
        self.fc2 = layers.Dense(64, activation='relu', kernel_initializer=tf.initializers.orthogonal(1))
        self.pol = layers.Dense(n_actions, kernel_initializer=tf.initializers.orthogonal(0.01))
        self.val = layers.Dense(1, kernel_initializer=tf.initializers.orthogonal(1))
        self.optimizer = tf.train.AdamOptimizer(learning_rate=lr)
        self.selection_strategy = selection_strategy


    def call(self, input):
        x = tf.constant(input, dtype=tf.float32)
        x = self.fc1(x)
        x = self.fc2(x)
        return self.pol(x), self.val(x)


    def select_action(self, logits):
        probs = tf.nn.softmax(logits)
        a = self.selection_strategy(probs)
        return tf.squeeze(a, axis=[0, 1]).numpy()


def sample(env, model):
    obs, act, rews, vals = [], [], [], []
    ob = env.reset()
    done = False

    while not done:
        # env.render()
        logits, value = model([ob])
        a = model.select_action(logits)
        value = tf.squeeze(value, axis=[0, 1])

        next_ob, r, done, _ = env.step(a)
        obs.append(ob)
        act.append(a)
        rews.append(r)
        vals.append(value.numpy())

        ob = next_ob

    return np.array(obs), np.array(act), np.array(rews), np.array(vals)


# Hyperparameters
GAMMA = 0.99
SAMPLES = 10000000
MAX_GRAD_NORM = 20
UPDATE_INTERVAL = 20


env = gym.make('MountainCar-v0')
model = PG(env.action_space.n)


for t in range(1, SAMPLES + 1):
    obs, act, rews, vals = sample(env, model)
    d_rew = discount(rews, GAMMA)
    d_rew = (d_rew - np.mean(d_rew)) / np.std(d_rew)

    advs = d_rew - vals


    with tf.GradientTape() as tape:

        logits, values = model(obs)
        values = tf.squeeze(values)
        one_hot = tf.one_hot(act, env.action_space.n, dtype=tf.float32)
        xentropy = tf.nn.softmax_cross_entropy_with_logits_v2(labels=one_hot, logits=logits)
        policy_loss = tf.reduce_mean(xentropy * advs)

        diff = d_rew - values

        value_loss = tf.reduce_mean(tf.square(diff))

        policy = tf.nn.softmax(logits)
        entropy = tf.reduce_mean(policy * tf.log(policy + 1e-20))

        total_loss = policy_loss + 0.5 * value_loss - 0.01 * entropy


    grads = tape.gradient(total_loss, model.trainable_weights)
    grads, gl_norm = tf.clip_by_global_norm(grads, MAX_GRAD_NORM)
    model.optimizer.apply_gradients(zip(grads, model.trainable_weights))


    if t % UPDATE_INTERVAL == 0 and not t is 0:
        print("BR: {0}, Len: {1}, Pol: {2:.4f}, Val: {3:.4f}, Ent: {4:.4f}"
              .format(np.sum(rews), len(rews), policy_loss, value_loss, entropy))

ER =總獎勵,Len =劇集長度,Pol =政策損失,Val =價值損失,Ent =熵,Grad Norm = Gradient Norm

ER: -200.0, Len: 200, Pol: 0.0656, Val: 1.0032, Ent: -0.3661, Grad Norm: 0.0901
ER: -200.0, Len: 200, Pol: -0.0384, Val: 1.0006, Ent: -0.3640, Grad Norm: 0.1186
ER: -200.0, Len: 200, Pol: -0.0585, Val: 1.0034, Ent: -0.3605, Grad Norm: 0.0963
ER: -200.0, Len: 200, Pol: -0.0650, Val: 1.0021, Ent: -0.3595, Grad Norm: 0.1149
ER: -200.0, Len: 200, Pol: 0.0007, Val: 1.0011, Ent: -0.3581, Grad Norm: 0.0893
ER: -200.0, Len: 200, Pol: 0.0024, Val: 1.0007, Ent: -0.3556, Grad Norm: 0.0951
ER: -200.0, Len: 200, Pol: 0.0114, Val: 1.0006, Ent: -0.3529, Grad Norm: 0.0954
ER: -200.0, Len: 200, Pol: 0.0310, Val: 1.0006, Ent: -0.3493, Grad Norm: 0.1060
ER: -200.0, Len: 200, Pol: -0.0187, Val: 0.9997, Ent: -0.3449, Grad Norm: 0.1111
ER: -200.0, Len: 200, Pol: -0.0367, Val: 0.9975, Ent: -0.3348, Grad Norm: 0.1302
ER: -200.0, Len: 200, Pol: -0.0349, Val: 0.9988, Ent: -0.3250, Grad Norm: 0.0884

我不確定我是否可以完全回答你的問題,但我會提供2美分,希望其他人來,並填寫其余的!

該模型最終收斂並獲得最大獎勵。 但是,由於某些原因,如果我只使用策略梯度方法而不是值函數/優勢,它會收斂得更快。

這是因為CartPole有一個非常簡單的動作空間,無論是向左還是向右。 這個問題的解決方案非常簡單,系統中添加的基本噪聲足以讓系統探索其狀態空間。 在演員評論方法中,需要調整更多權重和偏見。 並且因為需要調整更多參數,所以訓練時間更長。

出於某種原因,當我嘗試解決具有負獎勵的環境時,我的策略從負值開始並慢慢收斂到0。

xentropy = tf.nn.softmax_cross_entropy_with_logits_v2(labels=one_hot, logits=logits)
    policy_loss = tf.reduce_mean(xentropy * advs)

至於這部分,我認為實際的虧損表述是

Loss = - log(policy) * Advantage

哪里有否定,例如我https://math.stackexchange.com/questions/2730874/cross-entropy-loss-in-reinforcement-learning 在你的表述中,我不確定你是否將這個負面信息包括在你的損失函數中。 我在構建Policy Gradient時親自編寫了自己的損失函數,但也許你的Tensorflow功能會考慮到這一點。

至於價值,預計會在開始時出現高損失,因為它基本上是在猜測最優值是什么。

一些額外的提示和技巧是為你的狀態,行動,獎勵和s2使用重播記憶。 通過這種方式,您可以對您的軌跡進行去相關,並允許“均勻”學習。 如果您的州是相關的,那么它往往會過度適應您最近的事件。

你現在也在網上學習,這對於更困難的RL任務來說非常不穩定。 幫助這一點的一種方法是通過上面的重放記憶。 另一種方法是以小批量學習。 我相信這是David Silver在他的論文中使用的方法。 基本上,你想要運行許多軌跡。 在每個軌跡之后,執行反向傳播以通過TensorFlow中的tf.gradients方法計算策略梯度的損失。 存儲這些漸變,並在接下來的幾個軌跡中再次執行此操作。 在“小批量”軌跡量之后,您可以平均所有運行中的所有梯度,然后執行梯度下降以更新參數。 使用tf.apply_gradients方法,梯度下降與您在代碼中的操作完全相同。 你這樣做是因為環境有很多噪音,通過模擬許多軌跡,我們的想法是,迷你投影的平均軌跡是一個更具概率的表示,而不是一個軌跡。 我個人使用64個迷你批次。

為了增強您在州空間的探索,我建議使用Ornstein Ulhenbeck隨機過程。 基本上,這是一個穩定的相關噪聲系統。 因為它是相關噪聲,所以與使用去相關噪聲(即高斯噪聲)相比,它允許您走遠離初始狀態。 因為如果使用去相關噪聲,則長期平均值為0,因為它是0均值,單位方差。 基本上,如果你使用去相關的噪音,你最終會到達你開始的地方。 可以在這里找到一個很好的解釋: https//www.quora.com/Why-do-we-use-the-Ornstein-Uhlenbeck-Process-in-the-exploration-of-DDPG,Python中的代碼可以是在這里找到: https//github.com/openai/baselines/blob/master/baselines/ddpg/noise.py位於代碼的最底部。 只需將此噪音添加到您的操作中即可改善探索。

摘要

您的保單的損失功能標志可能不正確。 為了改善學習,在線學習困難問題非常困難。 兩種易於實現的解決方法是:

  • 重播記憶
  • 小批量梯度下降,而不是代碼中當前的隨機梯度下降

要增加更多穩定性,您還可以使用目標網絡。 目標網絡的想法是,因為在初始階段,您的權重將非常快速地更新。 目標網絡將在系統中,而不是使問題成為“非移動目標”問題。 目標網絡的權重被凍結,因此問題不會移動,並且在每一集之后,“真實”網絡被更新。 在x次迭代之后,將目標網絡更新為真實網絡。 但這需要更長的時間來實施。 我先建議以上兩點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM