python - 简单强化学习算法的损失函数
问题描述
这个问题来自于观看 Google I/O 18 上有关 TensorFlow 和强化学习的以下视频:https ://www.youtube.com/watch?v=t1A3NTttvBA
在这里,他们训练了一个非常简单的 RL 算法来玩 Pong 游戏。
在他们使用的幻灯片中,损失定义如下(大约 @ 11m 25s):
loss = -R(sampled_actions * log(action_probabilities))
他们进一步显示以下代码(大约@ 20m 26s):
# loss
cross_entropies = tf.losses.softmax_cross_entropy(
onehot_labels=tf.one_hot(actions, 3), logits=Ylogits)
loss = tf.reduce_sum(rewards * cross_entropies)
# training operation
optimizer = tf.train.RMSPropOptimizer(learning_rate=0.001, decay=0.99)
train_op = optimizer.minimize(loss)
现在我的问题是这个;他们使用 +1 表示获胜,使用 -1 表示失败作为奖励。在提供的代码中,任何乘以负奖励的交叉熵损失都会非常低?如果训练操作是使用优化器来最小化损失,那么算法是否被训练为失败?
还是我缺少一些基本的东西(可能是因为我的数学技能非常有限)
解决方案
好问题科里。我也想知道 RL 中这种流行的损失函数到底意味着什么。我见过很多它的实现,但很多都是相互矛盾的。据我了解,这意味着:
损失 = - log(pi) * A
其中 A 是与基线案例相比的优势。在谷歌的例子中,他们使用了 0 的基线,所以 A = R。这是乘以那个特定时间的特定动作,所以在你上面的例子中,动作是一个热编码为 [1,0,0]。我们将忽略 0,只取 1。因此我们有上面的等式。
如果您直观地计算此损失以获得负奖励:
损失 = - (-1) * log(P)
但是对于任何小于 1 的 P,该值的 log 将为负数。因此,您有一个负损失,可以解释为“非常好”,但实际上没有物理意义。
正确的方法:
但是在我看来,如果我错了,请其他人纠正我,你不直接计算损失。你取损失的梯度。也就是说,你取 -log(pi)*A 的导数。
因此,您将拥有:
-(d(pi) / pi) * A
现在,如果你有一个很大的负奖励,它将转化为一个非常大的损失。
我希望这是有道理的。
推荐阅读
- kotlin - 在我的 Gradle Kotlin 项目中配置 protobuf 时遇到问题
- javascript - 本机模块不能为空(ios)-世博会
- java - 如何使用 Selenium 和 Java 从非选择下拉列表中单击并选择一个选项
- bash - 如何进入 docker bash 并在一个命令中导航到日志目录
- java - 在我的滚动面板中时,JLabels 的坐标不正确
- java - 当 mock 返回无序集合 Map 时如何测试 API 行为?
- javascript - 如何优化或清理这个简单的骰子滚轮?
- elixir - Phoenix:混合 ecto.create 失败
- python - 用 BeautifulSoup 找到“属于”的东西
- kubernetes - 在 EKS 中分离/附加持久卷