有没有办法在张量流中剪辑中间爆炸梯度

Posted

技术标签:

【中文标题】有没有办法在张量流中剪辑中间爆炸梯度【英文标题】:Is there a way to clip intermediate exploded gradients in tensorflow 【发布时间】:2017-02-21 01:59:21 【问题描述】:

问题:一个很长的 RNN 网络

N1 -- N2 -- ... --- N100

对于像AdamOptimizer 这样的优化器,compute_gradient() 将为所有训练变量提供梯度。

但是,它可能会在某些步骤中爆炸。

类似how-to-effectively-apply-gradient-clipping-in-tensor-flow 的方法 可以裁剪大的最终渐变。

但是如何剪辑那些中间的呢?

一种方法可能是从“N100 --> N99”手动执行反向传播,剪切渐变,然后“N99 --> N98”等等,但这太复杂了。

所以我的问题是:有没有更简单的方法来剪辑中间渐变? (当然,严格来说,它们不再是数学意义上的梯度)

【问题讨论】:

粗略的想法——将你的每一层包装成一个使用自定义渐变的 py_func,就像 here 所做的那样。自定义梯度函数将采用后向值向量并返回裁剪后的版本。 裁剪权重和/或激活也可能有助于防止大梯度 【参考方案1】:

您可以使用custom_gradient 装饰器制作tf.identity 的一个版本,该版本会剪辑中间的爆炸渐变。

``` 从 tensorflow.contrib.eager.python 导入 tfe

@tfe.custom_gradient def gradient_clipping_identity(张量,max_norm): 结果 = tf.identity(张量)

def grad(结果): return tf.clip_by_norm(dresult, max_norm), None

返回结果,毕业生 ```

然后使用gradient_clipping_identity,就像您通常使用标识一样,您的渐变将在反向传递中被剪裁。

【讨论】:

【参考方案2】:
@tf.custom_gradient
def gradient_clipping(x):
  return x, lambda dy: tf.clip_by_norm(dy, 10.0)

【讨论】:

以上是关于有没有办法在张量流中剪辑中间爆炸梯度的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow2 手把手教你避开梯度消失和梯度爆炸

RNN 训练时梯度爆炸的理解

梯度爆炸是什么?有什么后果?如何判断梯度爆炸?如何避免梯度爆炸?

剑指offer梯度消失和梯度爆炸

梯度消失梯度爆炸

再聊聊梯度消失与梯度爆炸