TensorFlow中的梯度裁剪(Gradient Clipping)

梯度爆炸是深度学习中十分常见的现象,有时会导致寻优过程不收敛,或者算出来的结果干脆直接溢出,例如在Python里都是Nan,使迭代无法继续下去。TensorFlow里提供了一系列简单可行的梯度裁剪函数,方便我们对超过阈值的梯度值进行规约,使优化算法相对更加数值稳定。
TensorFlow里提供的几个Gradient Clipping函数都是以clip_by开头,分别是tf.clip_by_normtf.clip_by_global_normtf.clip_by_average_normtf.clip_by_value,下面依次逐个介绍。


1. tf.clip_by_norm

使用方法:

tf.clip_by_norm(t, clip_norm, axes=None, name=None)
"""
t: 要裁剪的梯度张量
clip_norm: 裁剪阈值,一个合适的正数
axes: 需要进行规约的维度,为None时,则对张量t的所有元素做规约
name:操作名称
"""

规约公式如下:

t={tclip_norm||t||2 ,t ,||t||2clip_normotherwise t = { t ∗ c l i p _ n o r m | | t | | 2   , | | t | | 2 ≥ c l i p _ n o r m t   , otherwise

其中: ||t||2 | | t | | 2 是张量 t t 的二范式,也就是对其所有元素的平方值求和后开根号,上述的号是elementwise乘积。

只有当 ||t||2 | | t | | 2 超过一定阈值的时候才会对梯度 t t 做相应的收缩。

2. tf.clip_by_global_norm

使用方法:

tf.clip_by_global_norm(t_list, clip_norm, use_norm=None, name=None)
"""
t_list: 要裁剪的梯度张量列表
clip_norm: 裁剪阈值,一个合适的正数
use_norm: 如果已经算出来了global_norm,可以直接传入到这一项参数里,节省算力
name:操作名称
"""

规约公式如下:

ti={ticlip_normavg_norm ,ti ,avg_normclip_normotherwise t i = { t i ∗ c l i p _ n o r m a v g _ n o r m   , a v g _ n o r m ≥ c l i p _ n o r m t i   , otherwise

where avg_norm=i||ti||22 w h e r e   a v g _ n o r m = ∑ i | | t i | | 2 2

其中: ti t i 表示t_list里的各个梯度张量。相比于tf.clip_by_norm,这个方法是对给出的梯度列表t_list里所有的梯度做规约,其中判断条件则变成了所有梯度张量二范式的平方求和后的方根,前者只看一个参数的梯度,这里看所有列出来的参数的梯度。

3. tf.clip_by_averge_norm

使用方法:

tf.clip_by_average_norm(t, clip_norm, name=None)
"""
t: 要裁剪的梯度张量
clip_norm: 裁剪阈值,一个合适的正数
name:操作名称
"""

规约公式如下:

t={tclip_normavg_norm ,t ,if avg_normclip_normotherwise t = { t ∗ c l i p _ n o r m a v g _ n o r m   , i f   a v g _ n o r m ≥ c l i p _ n o r m t   , otherwise

其中:

 avg_norm=||t||2m=mj=1t2jm,   a v g _ n o r m = | | t | | 2 m = ∑ j = 1 m t j 2 m ,

m m 是张量t t 的元素个数, tj t j 表示梯度张量t的各个分量。

3. tf.clip_by_value

使用方法:

tf.clip_by_value(t, clip_value_min, clip_value_max, name=None)
"""
t: 要裁剪的梯度张量
clip_value_min: 裁剪阈值下界
clip_value_max: 裁剪阈值上界
name:操作名称
"""

这里借用numpy数组的布尔索引就能解释:

t[t > clip_value_max] = clip_value_max
t[t < clip_value_min] = clip_value_min

小结

以上四种方法,无论是针对l2-norm还是对值的规约,归根结底都是截断绝对值较大的梯度分量

你可能感兴趣的:(深度学习,tensorflow,tensorflow)