以下這些函數可以用於解決梯度消失或梯度爆炸問題上。
1. tf.clip_by_value
tf.clip_by_value(
t,
clip_value_min,
clip_value_max,
name=None
)
Returns:A clipped Tensor.
輸入一個張量t,把t中的每一個元素的值都壓縮在clip_value_min和clip_value_max之間。小於min的讓它等於min,大於max的元素的值等於max。
例子:
import tensorflow as tf;
import numpy as np;
A = np.array([[1,1,2,4], [3,4,8,5]])
with tf.Session() as sess:
print sess.run(tf.clip_by_value(A, 2, 5))
>>>
[[2 2 2 4]
[3 4 5 5]]
2. tf.clip_by_norm
tf.clip_by_norm(
t,
clip_norm,
axes=None,
name=None
)
Returns:A clipped Tensor.
指對梯度進行裁剪,通過控制梯度的最大范式,防止梯度爆炸的問題,是一種比較常用的梯度規約的方式。
- t: 輸入tensor,也可以是list
- clip_norm: 一個具體的數,如果\(l_2 \, norm(t)≤clip\_norm\), 則t不變化;否則\(t=\frac{t*clip\_norm}{l_2norm(t)}\)
注意上面的t可以是list,所以最后做比較的時候是將t的二范式和clip_norm作比較。看下面的例子:
a = np.array([2.,5.])
b = tf.clip_by_norm(a, 5)
with tf.Session() as sess:
print(sess.run(tf.norm(a)))
print(sess.run(b))
>>>
5.3851647
[1.8569534 4.6423836]
3. tf.clip_by_average_norm
tf.clip_by_average_norm(
t,
clip_norm,
name=None
)
Returns:A clipped Tensor.
其實和tf.clip_by_norm類似,只不過把\(l_2\,norm(t)\)改成了\(l_2\,norm_avg(t)=\frac{1}{n} \, l_2\,norm(t)\),\(n\)表示t的元素個數。
例子
a = np.array([3, 4]).astype('float32')
e = tf.clip_by_average_norm(a, 1)
with tf.Session() as sess:
print(sess.run(e))
>>>
[1.2 1.6]
驗證一下:\(\frac{3*1}{\frac{1}{2}\sqrt{3^2+4^2}}=\frac{3}{2.5}=1.2\)。
4. tf.clip_by_global_norm
tf.clip_by_global_norm(
t_list,
clip_norm,
use_norm=None,
name=None
)
Returns:
list_clipped
: A list of Tensors of the same type as list_t.global_norm
: A 0-D (scalar) Tensor representing the global norm.
注意這里的t_list
是a tuple or list of tensors。
global_norm計算公式如下:
\[global\_norm=\sqrt{\sum_i^n{l_2\,norm(t[i])^2}} \]
如果global_norm>clip_norm,則t_list中所有元素若如下計算:
\[t\_list[i]=\frac{t\_list[i]*clip\_norm}{max(global\_norm,clip\_norm)} \]