Keras 中的策略梯度
Posted
技术标签:
【中文标题】Keras 中的策略梯度【英文标题】:Policy Gradients in Keras 【发布时间】:2017-03-19 05:19:18 【问题描述】:我一直在尝试使用“深度 Q 学习”构建一个模型,其中我有大量动作 (2908)。在使用标准 DQN 取得了一些有限的成功之后: (https://www.cs.toronto.edu/~vmnih/docs/dqn.pdf),我决定做更多的研究,因为我认为行动空间太大而无法进行有效的探索。
然后我发现了这篇论文:https://arxiv.org/pdf/1512.07679.pdf,他们使用了actor-critic 模型和策略梯度,然后我发现:https://arxiv.org/pdf/1602.01783.pdf,他们使用策略梯度来获得比 DQN 整体更好的结果。
我发现一些网站在 Keras 中实施了策略梯度,https://yanpanlau.github.io/2016/10/11/Torcs-Keras.html 和 https://oshearesearch.com/index.php/2016/06/14/kerlym-a-deep-reinforcement-learning-toolbox-in-keras/ 但是我对它们的实施方式感到困惑。在前者中(当我阅读论文时),似乎不是为参与者网络提供输入和输出对,而是为所有权重提供梯度,然后使用网络对其进行更新,而在后者中他们只是计算一个输入-输出对。
我是不是把自己弄糊涂了?我只是应该通过提供输入输出对并使用标准的“拟合”来训练网络,还是我必须做一些特别的事情?如果是后者,我该如何使用 Theano 后端呢? (以上示例使用 TensorFlow)。
【问题讨论】:
你见过github.com/matthiasplappert/keras-rl吗? 不放入状态动作对的一个原因是如果你有大量的动作会花费很长时间。相反,让网络一次预测所有动作的值然后在此之后进行动作选择通常很有用 【参考方案1】:TL;DR
-
了解如何使用 Keras.backend 实现自定义损失函数和梯度。您将需要它来实现更高级的算法,一旦掌握了它,它实际上会容易得多
一个使用 keras.backend 的 CartPole 示例可能是 https://gist.github.com/kkweon/c8d1caabaf7b43317bc8825c226045d2(尽管它的后端使用了 Tensorflow,但如果不相同,它应该非常相似)
问题
播放时,
代理需要一个策略,该策略基本上是将状态映射到策略的函数,该策略是每个动作的概率。因此,代理将根据其策略选择一个动作。
即策略 = f(state)
训练时,
Policy Gradient 没有损失函数。相反,它试图最大化奖励的预期回报。而且,我们需要计算 log(action_prob) * 优势的梯度
-
优势是奖励的函数。
优势 = f(奖励)
action_prob 是 states 和 action_taken 的函数。例如,我们需要知道我们采取了哪些行动,以便我们可以更新参数以增加/减少我们采取行动的概率。
action_prob = sum(policy * action_onehot) = f(states, action_taken)
我假设是这样的
政策 = [0.1, 0.9] action_onehot = action_taken = [0, 1] 那么 action_prob = sum(policy * action_onehot) = 0.9总结
我们需要两个函数
更新函数:f(state, action_taken, reward) 选择动作函数:f(state)你已经知道它不像典型的分类问题那样容易实现,你可以只用 model.compile(...) -> model.fit(X, y)
然而,
为了充分利用 Keras,您应该熟悉定义自定义损失函数和梯度。这与前一篇的作者所采用的方法基本相同。
您应该阅读更多有关 Keras 功能 API 和 keras.backend 的文档
另外,策略梯度有很多种。
前一种称为 DDPG,实际上与常规策略梯度有很大不同 我看到的后一个是基于 Kapathy 的策略梯度示例的传统 REINFORCE 策略梯度 (pg.py)。但它非常简单,例如它只假设一个动作。这就是为什么它可以使用 model.fit(...) 以某种方式实现。参考文献
舒尔曼,“策略梯度方法”,http://rll.berkeley.edu/deeprlcourse/docs/lec2.pdf【讨论】:
【参考方案2】:您遇到的看似冲突的实现都是有效的实现。它们是两种实现策略梯度的等效方式。
在 vanilla 实现中,您计算策略网络 w.r.t 的梯度。奖励并直接更新梯度方向的权重。这需要您执行 Mo K 描述的步骤。
第二个选项可以说是 keras/tensorflow 等 autodiff 框架更方便的实现。这个想法是实现一个输入-输出(状态-动作)函数,如监督学习,但使用梯度与策略梯度相同的损失函数。对于 softmax 策略,这仅仅意味着预测“真实动作”并将(交叉熵)损失与观察到的回报/优势相乘。 Aleksis Pirinen 对此 [1] 有一些有用的说明。
Keras 中选项 2 的修改后的损失函数如下所示:
import keras.backend as K
def policy_gradient_loss(Returns):
def modified_crossentropy(action,action_probs):
cost = K.categorical_crossentropy(action,action_probs,from_logits=False,axis=1 * Returns)
return K.mean(cost)
return modified_crossentropy
其中“动作”是剧集的真实动作 (y),action_probs 是预测概率 (y*)。这是基于另一个 *** 问题 [2]。
参考文献
-
https://aleksispi.github.io/assets/pg_autodiff.pdf
Make a custom loss function in keras
【讨论】:
这很有帮助。一个问题,是否应该有一个 K.mean() 成本?成本最终需要是标量的,我假设 action 和 action-probs 代表了一个完整的轨迹(游戏运行)随着时间的推移?更重要的是,您假设输入的维度是什么,包括退货? @Mastiff action 和 action_probs 的维度是 (batch_size,n_categories)。对这些变量使用 K.categorical_crossentropy 会产生一个长度向量(批量大小),并将其与具有相同维度(批量大小)的返回向量逐元素相乘。因此,该函数返回一个损失向量,其中一个元素反映一个样本,我认为不需要 K.mean。 @Mastiff 我看过它,实际上通常你会取平均值。所以我在自己的 RL 算法上对其进行了测试,使用 K.mean() 给出了相同的结果。我更新了我的答案。感谢您的提示。以上是关于Keras 中的策略梯度的主要内容,如果未能解决你的问题,请参考以下文章
无法从 tensorflow/keras 中的加载模型中获取梯度
在 keras(tensorflow 后端)中计算梯度时出错