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

Vis*_*ram 13 python-3.x deep-learning tensorflow

想要了解在tensorflow中实现渐变剪切期间tf.clip_by_value和tf.clip_by_global_norm的角色差异.哪一个是首选的,如何决定要剪辑的最大值?

gde*_*lab 25

TL; DR:tf.clip_by_global_norm用于渐变剪辑.

clip_by_value

tf.clip_by_value无论张量中的其他值如何,都会在一个张量内剪切每个值.例如,

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

因此,它可以改变张量的方向,因此如果张量中的值彼此去相关(梯度削波不是这种情况),或者为了避免张量中的零/无限值,则应该使用张量的方向.在其他地方导致Nan /无限值(例如,通过剪切最小的epsilon = 1e-8和非常大的最大值).

clip_by_norm

tf.clip_by_norm必要时重新调整一个张量,使其L2范数不超过某个阈值.通常避免在一个张量上爆炸渐变是有用的,因为您保持渐变方向.例如:

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
Run Code Online (Sandbox Code Playgroud)

但是,clip_by_norm仅适用于一个渐变,因此如果您在所有渐变张量上使用它,您将使它们失去平衡(一些将被重新缩放,另一些则不会,并且不是全部具有相同的比例).

请注意,前两个只能处理一个张量,而最后一个则用于张量列表.

clip_by_global_norm

tf.clip_by_global_norm重新调整张量列表,使其所有规范的向量的总范数不超过阈值.目标与 clip_by_norm(避免爆炸渐变,保持渐变方向)相同,但它同时适用于所有渐变,而不是分别对每个渐变起作用(也就是说,如果需要,所有渐变都由相同的因子重新缩放,或者没有他们被重新调整).这样更好,因为保持了不同梯度之间的平衡.

例如:

tf.clip_by_global_norm([tf.constant([-2, 3, 6]),tf.constant([-4, 6, 12])] , 14.5)
Run Code Online (Sandbox Code Playgroud)

将一个因子重新缩放两个张量14.5/sqrt(49 + 196),因为第一个张量的L2范数为7,第二个张量为14,和sqrt(7^2+ 14^2)>14.5

此(tf.clip_by_global_norm)是您应该用于渐变剪裁的那个.见为更多信息实例.

选择价值

选择最大值是最难的部分.你应该使用最大的值,使你没有爆炸梯度(其影响可以是你的张量中出现的Nans或infinite值,经过几个训练步骤后不断丢失/准确).该值应该大于tf.clip_by_global_norm其他值,因为由于隐含的张量数量,全局L2规范将比其他规范更大.

  • 我的意思是方向与向量的方向具有相同的意义:如果将张量中的所有值乘以 2 或 0.5,则不会更改其中不同值之间的比率,因此不会更改其方向(它仍然表示在同一方向上的运动,只是距离更大)。如果您更改一个值比其他值多,那么您确实会更改比率,因此您确实会更改方向,这对于应该指向正确方向(大约在最小值的方向)的渐变来说是不好的. (2认同)