这个问题涉及到普通的、非批量处理的强化学习。基本上是这里在Sutton的书中定义的。我的模型在训练(太棒了!),但有一个元素让我感到困惑。
背景:
在一个奖励持续时间的环境中(比如平衡杆),我们每一步得到的奖励是(比如说)1。在一集结束后,在将这一连串的1发送到训练步骤之前,我们会进行标准的折扣和标准化以获得回报:
returns = self.discount_rewards(rewards)returns = (returns - np.mean(returns)) / (np.std(returns) + 1e-10) // 通常的标准化
discount_rewards 是常规方法,如果你好奇,这里有代码。
所以一个奖励数组 [1,1,1,1,1,1,1,1,1] 变成了一个回报数组 [1.539, 1.160, 0.777, 0.392, 0.006, -0.382, -0.773, -1.164, -1.556]。
有了这个基本背景,我可以问我的问题了:
如果鼓励正回报,并在优化步骤中抑制负回报,那么无论一集的长度如何,大约前半部分的行动会被鼓励,而后半部分的行动会被抑制。这是真的吗,还是我误解了什么?
如果这不是真的,我很想了解我哪里错了。
如果这是真的,那么我不明白为什么模型能训练,因为即使是一集表现良好的情况下,其后半部分的行动也会被抑制。
重申一下,这是非批量学习(所以回报不是相对于训练步骤中另一集的回报)。每集结束后,模型都会训练,而且再次,它训练得很好 🙂
希望这有意义,并且足够简短以便成为一个清晰的问题。
回答:
背景
- 是的,正奖励比负奖励好
- 不是,正奖励在绝对尺度上不好
- 不是,负奖励在绝对尺度上不坏
如果你增加或减少所有奖励(好的和坏的)同样地,实际上没有什么变化。
优化器试图最小化损失(最大化奖励),这意味着它只对值之间的差异(梯度)感兴趣,而不是它们的绝对值或符号。
强化学习
假设你的图表看起来像这样:
...logits = tf.nn.softmax(...)labels = tf.one_hot(q_actions, n_actions)loss = tf.losses.softmax_cross_entropy(labels, logits, weights=q_rewards)
各个“类别”的损失通过weights
缩放,在这种情况下是q_rewards
:
loss[i] = -q_rewards[i] * tf.log( tf.nn.softmax( logits[i] ) )
损失是奖励的线性函数,梯度在线性变换下保持单调性。
奖励标准化
- 不会干扰梯度的符号
- 使远离均值的奖励的梯度变得更陡峭
- 使接近均值的奖励的梯度变得更平缓
当代理表现得相当糟糕时,它会收到更多的坏奖励而不是好奖励。标准化使好奖励的梯度变得更陡峭(增加权重),而使坏奖励的梯度变得更平缓(减少权重)。
当代理表现得相当好时,情况正好相反。
你的问题
如果鼓励正回报,并在优化步骤中抑制负回报…
这不是关于符号(绝对值)而是关于差异(相对值)。
…那么无论一集的长度如何,大约前半部分的行动会被鼓励,而后半部分的行动会被抑制。
如果有更多高奖励或更多低奖励值,那么你会有一个较小的半部分具有更陡峭的梯度(更大的权重)和一个较大的半部分具有更平缓的梯度(较小的权重)。
如果这是真的,那么我不明白为什么模型能训练,因为即使是一集表现良好的情况下,其后半部分的行动也会被抑制。
你的损失值实际上预计会在某个点保持大致恒定。所以你需要通过运行程序并查看(未标准化)的奖励来衡量你的进展。
作为参考,请参见 Google IO 的示例网络:github.com/GoogleCloudPlatform/tensorflow-without-a-phd/…/tensorflow-rl-pong/… 并搜索 _rollout_reward
然而,这并不是一件坏事。只是你的损失(或多或少地)也被“标准化”了。但网络通过查看每个训练步骤的梯度继续改进。
分类问题通常有一个随时间逐渐下降的“全局”损失。一些优化器保留梯度的历史记录以调整学习率(有效地缩放梯度),这意味着它们在内部也某种程度上“标准化”了梯度,因此不关心我们是否也这样做。
如果你想了解更多关于幕后梯度缩放的信息,我建议查看 ruder.io/optimizing-gradient-descent
重申一下,这是非批量学习(所以回报不是相对于训练步骤中另一集的回报)。每集结束后,模型都会训练,而且再次,它训练得很好 🙂
你的批量大小越大,奖励的分布就越稳定,标准化就越可靠。你甚至可以跨多个集来标准化奖励。