想了解在TensorFlow中实现梯度裁剪时tf.clip_by_value和tf.clip_by_global_norm的角色区别。哪一个是首选以及如何确定裁剪的最大值?
tf.clip_by_value
tf.clip_by_global_norm
chhkpiq41#
TL;DR:使用tf.clip_by_global_norm进行渐变裁剪,最大值为“某个高值”。
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和非常大的最大值进行裁剪),则应该使用它。
tf.clip_by_norm在必要时重新缩放一个Tensor,使其L2范数不超过某个阈值。它通常用于避免一个Tensor上的梯度爆炸,因为您保持梯度方向。例如:
tf.clip_by_norm
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_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。
14.5/sqrt(49 + 196)
sqrt(7^2+ 14^2)>14.5
选择最大值是最难的部分。你应该使用最大的值,这样你就不会有爆炸的渐变(其效果可以是出现在Tensor中的Nan s或infinite值,经过几个训练步骤后,损失/准确度不变)。tf.clip_by_global_norm的值应该比其他值大,因为由于隐含的Tensor的数量,全局L2范数将机械地大于其他范数。
Nan
infinite
1条答案
按热度按时间chhkpiq41#
TL;DR:使用
tf.clip_by_global_norm
进行渐变裁剪,最大值为“某个高值”。clip_by_value
tf.clip_by_value
剪切一个Tensor中的每个值,而不管Tensor中的其他值。例如,字符串
因此,它可以改变Tensor的方向,所以如果Tensor中的值彼此去相关(这不是梯度裁剪的情况),或者避免Tensor中的零/无穷大值,这可能导致其他地方的Nan /无穷大值(例如,通过使用最小值= 1 e-8和非常大的最大值进行裁剪),则应该使用它。
clip_by_norm
tf.clip_by_norm
在必要时重新缩放一个Tensor,使其L2范数不超过某个阈值。它通常用于避免一个Tensor上的梯度爆炸,因为您保持梯度方向。例如:型
然而,
clip_by_norm
只适用于一个梯度,所以如果你在所有梯度Tensor上使用它,你会使它们不平衡(有些会被重新缩放,有些不会,并且不是所有的都具有相同的尺度)。注意,前两个只对一个Tensor起作用,而最后一个用于Tensor列表。
clip_by_global_norm
tf.clip_by_global_norm
重新缩放Tensor列表,使其所有范数的向量的总范数不超过阈值。目标与clip_by_norm
相同(避免梯度爆炸,保持梯度方向),但它同时适用于所有梯度,而不是分别适用于每个梯度(即,如果需要,所有这些都被相同的因子重新缩放,或者没有一个被重新缩放)。这是更好的,因为不同梯度之间的平衡得到了保持。例如:
型
我将通过因子
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范数将机械地大于其他范数。