我想在训练期间调用一些层(但不是推理) - 梯度似乎没有流过这些层



我正在使用ray.tune()的自定义PPO模型,我想添加一些依赖于batch[' obs '], batch[' done '], batch[' action ']和batch[' next_obs ']的自监督学习

我在模型中定义了一些只在训练时调用的层。

我已经定义了一个损失函数,我在损失函数中传递给训练器,我通过在正向模型中从未调用过的层传递了各种输入。具体来说,这些输入是train_batch[' actions '](来自观察的东西),以及我存储为模型属性的图层(例如model.loss_context)

不在前向模型中的层(即仅在损失函数期间调用的层)似乎没有添加到梯度中-我正在记录它们的大小并且它们没有改变,即使我在前向模型之外的层上放置一个明显简单的例子,这只是一个巨大的权重衰减。

我还尝试将这些层添加到重写的@custom_loss函数中,如示例https://github.com/ray-project/ray/blob/50e1fda022a81e5015978cf723f7b5fd9cc06b2c/rllib/examples/models/custom_loss_model.py:,但在这种情况下,这些层的权重甚至没有初始化。

有人解决这个问题了吗?我看到很多关于这个问题的堆栈溢出问题,但是没有答案!

见上图。我期待权重会改变。这是损失函数

LoggedPPO = PPOTFPolicy.with_updates(
name="SHPPOPolicy",
loss_fn=ppo_surrogate_loss,
grad_stats_fn=grad_stats,
stats_fn=stats,
)
context, action_mask, net_mask = tf.split(
logits,
[
model.context_dim * model.max_num_nets,
model.max_num_nets * (9 + model.svg_feature_dict["max_layers"]),
model.max_num_nets,
],
axis=1,
)
x = model.test_dense(context)
wd_loss = sum(
[tf.reduce_sum(v ** 2) for v in model.test_dense.variables]
) + 1e-4

batch_loss = [ ..... wd_loss]

在这个例子中,test_dense(在向前传递过程中没有被调用)永远不会被更新,即使这种情况是微不足道的,并且模型应该尝试减少其权重的绝对标量值。

您需要确保您实际上正在做以下几件事:

  • 通过这些层传递输入并获得输出
  • 计算损失和梯度
  • 步骤与优化器
  • (分配权重)

我建议使用零工作者,现在不使用tune,并在修改的代码部分设置断点。从这里很难看出上述哪些步骤没有采取。由于您提到了with_updates():该API已被弃用,并且使用它使调试像这样的问题有点困难。考虑升级!当前的PPO策略可以简单地子类化。在GH上发布完整的复制脚本使您的修改看起来更明显。

欢呼

最新更新