演员批评政策损失将为零(无改善)

2024-05-19 13:32:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个演员-评论家模型来测试一些OpenAI健身房环境。但是,我在某些环境中遇到了问题。在

CartPole:模型最终会收敛并获得最大的回报。但是,由于某些原因,如果我只使用策略梯度方法而不是值函数/优势,它会更快地收敛。在

登山车、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=熵,梯度范数=梯度范数

^{pr2}$

Tags: selfenvmodelreturnvaluelayerstfdef
1条回答
网友
1楼 · 发布于 2024-05-19 13:32:39

我不确定我是否能完全回答你的问题,但我会提供我的2分钱,希望其他人来填补其余的!在

^{bq}$

这是因为CartPole有一个非常简单的动作空间,可以向左或向右。这个问题的解决方法非常简单,加上非常基本的噪声就足以使系统探索其状态空间。在演员批评方法中,需要调整更多的权重和偏差。由于需要调整的参数较多,训练时间较长。在

For some reason, when I try to solve an environment with negative rewards, my policy starts with negative values and slowly converges to 0.

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

至于这一部分,我认为实际损失公式是

^{pr2}$

这里有一个负数,比如ihttps://math.stackexchange.com/questions/2730874/cross-entropy-loss-in-reinforcement-learning。在你的公式中,我不确定你是否把这个负数包括在你的损失函数中。我自己写了我自己的损失函数,当我构建我的政策梯度,但也许你的张量流函数考虑到了这一点。在

至于价值,一开始预计会有很高的损失,因为它基本上是在猜测什么是最佳价值。在

一些额外的提示和技巧是使用重放内存为您的状态,行动,奖励和s2。这样,你可以去相关你的轨迹,它允许“甚至”学习。如果你的状态是相关的,那么它往往会过度适应你最近的事件。在

你现在也在网上学习,这对于更困难的RL任务来说是非常不稳定的。一种帮助这一点的方法是通过上面的重放内存。另一种方法是分批学习。我相信这就是大卫·西尔弗在论文中使用的方法。基本上,你需要运行很多轨迹。在每个轨迹之后,执行反向传播,通过tf.梯度方法。存储这些渐变,然后在接下来的几个轨迹中再次执行此操作。在一个“小批量”数量的轨迹之后,您然后平均所有运行的所有梯度,然后执行渐变下降来更新参数。渐变下降的方式与在代码中使用tf.应用梯度方法。你这样做是因为环境有很多噪音,通过模拟许多轨迹,我们的想法是小批量的平均轨迹是一个更具概率性的表示,而不是只有一个轨迹。我个人使用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次迭代,将目标网络更新为真实网络。但这需要更长的时间实施。我想先建议以上两种。在

相关问题 更多 >