tensorflow RNN的tf.clip_by_value和tf.clip_by_global_norm之间的区别以及如何确定最大值?

klsxnrf1  于 6个月前  发布在  其他
关注(0)|答案(1)|浏览(62)

想了解在TensorFlow中实现梯度裁剪时tf.clip_by_valuetf.clip_by_global_norm的角色区别。哪一个是首选以及如何确定裁剪的最大值?

chhkpiq4

chhkpiq41#

TL;DR:使用tf.clip_by_global_norm进行渐变裁剪,最大值为“某个高值”。

clip_by_value

tf.clip_by_value剪切一个Tensor中的每个值,而不管Tensor中的其他值。例如,

tf.clip_by_value([-1, 2, 10], 0, 3)  -> [0, 2, 3]  # Only the values below 0 or above 3 are changed

字符串
因此,它可以改变Tensor的方向,所以如果Tensor中的值彼此去相关(这不是梯度裁剪的情况),或者避免Tensor中的零/无穷大值,这可能导致其他地方的Nan /无穷大值(例如,通过使用最小值= 1 e-8和非常大的最大值进行裁剪),则应该使用它。

clip_by_norm

tf.clip_by_norm在必要时重新缩放一个Tensor,使其L2范数不超过某个阈值。它通常用于避免一个Tensor上的梯度爆炸,因为您保持梯度方向。例如:

tf.clip_by_norm([-2, 3, 6], 5)  -> [-2, 3, 6]*5/7  # The original L2 norm is 7, which is >5, so the final one is 5
tf.clip_by_norm([-2, 3, 6], 9)  -> [-2, 3, 6]  # The original L2 norm is 7, which is <9, so it is left unchanged


然而,clip_by_norm只适用于一个梯度,所以如果你在所有梯度Tensor上使用它,你会使它们不平衡(有些会被重新缩放,有些不会,并且不是所有的都具有相同的尺度)。
注意,前两个只对一个Tensor起作用,而最后一个用于Tensor列表。

clip_by_global_norm

tf.clip_by_global_norm重新缩放Tensor列表,使其所有范数的向量的总范数不超过阈值。目标与clip_by_norm相同(避免梯度爆炸,保持梯度方向),但它同时适用于所有梯度,而不是分别适用于每个梯度(即,如果需要,所有这些都被相同的因子重新缩放,或者没有一个被重新缩放)。这是更好的,因为不同梯度之间的平衡得到了保持。
例如:

tf.clip_by_global_norm([tf.constant([-2, 3, 6]),tf.constant([-4, 6, 12])] , 14.5)


我将通过因子14.5/sqrt(49 + 196)重新缩放两个Tensor,因为第一个Tensor的L2范数为7,第二个Tensor的L2范数为14,而sqrt(7^2+ 14^2)>14.5
这个(tf.clip_by_global_norm)是你应该用来进行渐变裁剪的。更多信息参见this

选择值

选择最大值是最难的部分。你应该使用最大的值,这样你就不会有爆炸的渐变(其效果可以是出现在Tensor中的Nan s或infinite值,经过几个训练步骤后,损失/准确度不变)。tf.clip_by_global_norm的值应该比其他值大,因为由于隐含的Tensor的数量,全局L2范数将机械地大于其他范数。

相关问题