【问题标题】:A2C algorithm in tf.keras: actor loss functiontf.keras 中的 A2C 算法:actor 损失函数
【发布时间】:2020-04-22 09:34:00
【问题描述】:

我正在学习 Action-Critic 强化学习技术,尤其是 A2C 算法。

我在此处找到了对算法简单版本(即没有经验重放、批处理或其他技巧)的良好描述:https://link.medium.com/yi55uKWwV2。那篇文章的完整代码是available on GitHub

我想我明白这里发生了什么,但为了确保我确实做到了,我正在尝试使用更高级别的 tf.keras API 从头开始​​重新实现它。我卡住的地方是如何正确实现训练循环,以及如何制定演员的损失函数。

  1. 将行动和优势传递给损失函数的正确方法是什么?
  2. Actor 的损失函数涉及计算对正态分布采取的行动的概率。如何确保损失函数计算期间正态分布的 mu 和 sigma 与预测期间的实际匹配?
  3. 原来的方式是,actor 的损失函数不关心 y_pred,它只关心与环境交互时选择的动作。这似乎是错误的,但我不确定如何。

我目前的代码:https://gist.github.com/nevkontakte/beb59f29e0a8152d99003852887e7de7

编辑:我想我的一些困惑源于对 Keras/TensorFlow 中梯度计算背后的魔法理解不足,因此任何指针都会受到赞赏。

【问题讨论】:

  • 这是您尝试实现的第一个 RL 算法吗?我建议从基础开始,因为你的问题暗示你对演员评论家的整个事情并不完全清楚。这是一个很好的速成课程lilianweng.github.io/lil-log/2018/04/08/…
  • 感谢 Simon,我想我非常了解它背后的数学和理论,并且我确实为离散动作空间(q-learning 和简单的策略梯度)实现了一些更简单的算法。但我确实缺乏使用 Tensorflow 的经验,因此使用 tf.keras API 表达 A2C 算法(似乎或多或少是两者的综合)结果比我预期的要困难。不过我会研究你的链接,谢谢!

标签: python tensorflow keras reinforcement-learning


【解决方案1】:

首先,应得的功劳:ralf htpSimon 提供的信息有助于我最终找出正确的答案。

在我详细回答我自己的问题之前,here's the original code 我试图用 tf.keras 术语重写,here's my result

在 Keras 中将行动和优势传递给损失函数的正确方法是什么?

原始 TF 优化器所考虑的损失函数与 Keras 所做的有所不同。直接使用优化器时,它只需要一个张量(惰性或急切,具体取决于您的配置),它将在 tf.GradientTape() 下评估以计算梯度并更新权重。

来自https://medium.com/@asteinbach/actor-critic-using-deep-rl-continuous-mountain-car-in-tensorflow-4c1fb2110f7c的示例:

# Below norm_dist is the output tensor of the neural network we are training.
loss_actor = -tfc.log(norm_dist.prob(action_placeholder) + 1e-5) * delta_placeholder
training_op_actor = tfc.train.AdamOptimizer(
    lr_actor, name='actor_optimizer').minimize(loss_actor)

# Later, in the training loop...

_, loss_actor_val = sess.run([training_op_actor, loss_actor],
                             feed_dict={action_placeholder: np.squeeze(action),
                                        state_placeholder: scale_state(state),
                                        delta_placeholder: td_error})

在此示例中,它计算整个图形,包括进行推理、捕获梯度和调整权重。因此,要将您需要的任何值传递到损失函数/梯度计算中,您只需将必要的值传递到计算图中即可。

Keras 有点more formal 损失函数应该是什么样子:

loss:字符串(目标函数的名称),目标函数或 tf.keras.losses.Loss 实例。请参阅 tf.keras.losses。目标函数是任何具有签名 scalar_loss = fn(y_true, y_pred) 的可调用函数。如果模型有多个输出,您可以通过传递字典或损失列表在每个输出上使用不同的损失。模型将最小化的损失值将是所有单个损失的总和。

Keras 将为您进行推理(前向传递)并将输出传递给损失函数。损失函数应该对预测值和y_true标签做一些额外的计算,并返回结果。为了梯度计算,将跟踪整个过程。

虽然对于传统的训练来说很方便,但是当我们想要传入一些额外的数据时,这有点限制,比如 TD error。可以解决这个问题并将所有额外数据推入y_true,然后在损失函数中将其分开(我在网络上的某个地方找到了这个技巧,但不幸的是丢失了源链接)。

最后我是这样重写上面的:

def loss(y_true, y_pred):
    action_true = y_true[:, :n_outputs]
    advantage = y_true[:, n_outputs:]
    return -tfc.log(y_pred.prob(action_true) + 1e-5) * advantage

# Below, in the training loop...

# A trick to pass TD error *and* actual action to the loss function: join them into a tensor and split apart
# Inside the loss function.
annotated_action = tf.concat([action, td_error], axis=1)
actor_model.train_on_batch([scale_state(state)], [annotated_action])

演员的损失函数涉及计算给定正态分布所采取行动的概率。如何确保损失函数计算期间正态分布的 mu 和 sigma 与预测期间的实际匹配?

当我问这个问题时,我对 TF 计算图的工作原理还不够了解。所以答案很简单:每次调用 sess.run() 时,它都必须从头开始计算整个图。只要图输入(例如观察到的状态)和 NN 权重相同(或相似),分布参数将相同(或相似)。

原来的方式是,actor 的损失函数不关心 y_pred,它只关心与环境交互时选择的动作。这似乎是错误的,但我不确定如何。

错误的是假设“演员的损失函数不关心 y_pred”:) 演员的损失函数涉及 norm_dist(这是动作概率分布),在这种情况下它实际上是 y_pred 的模拟。

【讨论】:

    【解决方案2】:

    据我了解 A2C 是 激活剂-抑制剂系统 的机器学习实现,也称为 双组分反应扩散系统 (https://en.wikipedia.org/wiki/Reaction%E2%80%93diffusion_system)。激活剂-抑制剂模型在任何科学领域都很重要,因为它们描述了诸如图灵机制之类的模式形成(只需在网上搜索 激活剂-抑制剂模型,您就会发现大量信息,一个非常常见的应用程序是捕食者-猎物模型)。另请参阅图形 图片来源:https://www.researchgate.net/figure/Activator-Inhibitor-System_fig1_23671770/

    https://towardsdatascience.com/reinforcement-learning-w-keras-openai-actor-critic-models-f084612cfd69中A2C算法的说明图

    激活剂-抑制剂模型与非线性动力系统理论(或“混沌理论”)密切相关,这在比较 https://medium.com/@asteinbach/rl-introduction-simple-actor-critic-for-continuous-actions-4e22afb712 和非线性动力系统的分叉树,例如逻辑图(https://en.wikipedia.org/wiki/Logistic_map,逻辑图是最简单的 predator-prey 模型或 activator-inhibitor 模型之一) .另一个相似之处是 A2C 模型中的对初始条件的敏感性,它被描述为

    这引入了对数概率(策略分布的对数)和累积奖励值的固有高可变性,因为训练期间的每个轨迹都可能在很大程度上相互偏离。

    https://towardsdatascience.com/understanding-actor-critic-methods-931b97b6df3f 中,维度诅咒也出现在混沌理论中,即吸引子重构

    从系统理论的角度来看,A2C 算法试图调整初始值(开始状态),使其在增加动态系统的增长率时最终到达给定端点,即逻辑图(r 值增加并且初始值(开始状态)不断重新适应以在分叉树中选择正确的分叉(动作))

    因此,A2C 试图以数值方式解决混沌理论问题,即在其混沌区域中找到非线性动力系统的给定结果的初始值。从分析上讲,这个问题在大多数情况下是无法解决的。

    action是分支树中的分支点,states是未来的分支。

    actionsstates 都是由两个耦合的神经网络建模的,这两个神经网络的耦合是 A2C 算法的一大创新。

    https://towardsdatascience.com/reinforcement-learning-w-keras-openai-actor-critic-models-f084612cfd69 中有详细记录的用于实现 A2C 的 keras 代码,因此您可以在那里实现。

    这里的损失函数定义为时间差(TD)函数,即实际分叉点的状态状态精确差/em>在估计的未来之一,但是这个在数学上精确定义的容易产生随机误差(或噪声),所以随机误差包含在的定义中>确切,因为最终机器学习是基于随机系统或误差计算的,这意味着系统由确定性和随机性组成。为了将这个误差归零,使用随机梯度下降。在 keras 中,这只是通过选择 optimizer=sge 来实现的。

    实际步骤和未来步骤的交互在remember 函数中以memory 的形式在https://towardsdatascience.com/reinforcement-learning-w-keras-openai-actor-critic-models-f084612cfd69 上实现,并且此函数还链接actor 和critic 网络(或激活剂和抑制剂网络)。 试验(动作)、调用预测(TD 函数)、记忆和训练(即随机梯度下降)的一般结构是所有强化学习算法的基础,并与 actual 结构相关联状态、动作、奖励、新状态

    预测代码也与之前的强化学习算法非常相似。也就是说,我们只需要迭代试验并调用预测、记忆和训练代理

    在第一个问题的实现中,通过对评论家应用记住并使用这些值训练评论家来解决第一个问题(这是在主函数中),其中训练总是评估损失函数,所以 action em> 和 reward 在此实现中由remember 传递给损失函数:

       actor_critic.remember(cur_state, action, reward, new_state, done)
       actor_critic.train()
    

    由于您的第二个问题:我不确定,但我认为这是通过优化算法(即随机梯度下降)实现的

    第三个问题:在捕食者-猎物模型中,行动者或激活者是猎物,猎物的行为仅取决于栖息地的大小或容量(草的数量)和捕食者的大小(抑制剂) 种群,因此以这种方式对其建模再次符合自然或激活剂-抑制剂系统。在https://towardsdatascience.com/reinforcement-learning-w-keras-openai-actor-critic-models-f084612cfd69main 函数中,也只训练了批评者或抑制者/捕食者。

    【讨论】:

    • 非常感谢您的全面回答!我需要几天的时间来研究你引用的所有材料,然后我可能会再回来问几个问题。
    猜你喜欢
    • 2019-10-29
    • 1970-01-01
    • 2019-10-23
    • 2020-03-15
    • 2021-12-08
    • 2018-12-08
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    相关资源
    最近更新 更多