爲了解決深度學習中常見的梯度消失(gradient explosion)和梯度爆炸(gradients vanishing)問題,tensorflow
中全部的優化器tf.train.xxxOptimizer
都有兩個方法:python
compute_gradients
apply_gradients
對於compute_gradients
方法,計算var_list中參數的梯度,使得loss變小。默認狀況下,var_list爲GraphKeys.TRAINABLE_VARIABLES
中的全部參數。
compute_gradients方法返回由多個(gradients, variable)
二元組組成的列表。app
compute_gradients( loss, var_list=None, gate_gradients=GATE_OP, aggregation_method=None, colocate_gradients_with_ops=False, grad_loss=None )
對於apply_gradients
方法,根據compute_gradients的返回結果對參數進行更新學習
apply_gradients( grads_and_vars, global_step=None, name=None )
tensorflow中裁剪梯度的幾種方式優化
def clip_by_value(t, clip_value_min, clip_value_max, name=None):
其中,t
爲一個張量,clip_by_value返回一個與t的type相同、shape相同的張量,可是新tensor中的值被裁剪到了clip_value_min
和clip_value_max
之間。code
def clip_by_global_norm(t_list, clip_norm, use_norm=None, name=None):
其中,t_list
爲A tuple or list of mixed Tensors
, IndexedSlices
, or None
。clip_norm
爲clipping ratio,use_norm
指定global_norm,若是use_norm爲None,則按global_norm = sqrt(sum([l2norm(t)**2 for t in t_list]))
計算global_norm。
最終,梯度的裁剪方式爲
$$t\_list[i] \times \frac{clip\_norm}{max(global\_norm, clip\_norm)}$$
可知,若是clip_norm > global_norm, 則不對梯度進行裁剪,不然對梯度進行縮放。orm
scale = clip_norm * math_ops.minimum( 1.0 / use_norm, constant_op.constant(1.0, dtype=use_norm.dtype) / clip_norm)
方法的返回值爲裁剪後的梯度列表list_clipped和global_norm
示例代碼ip
optimizer = tf.train.AdamOptimizer(learning_rate) gradients, v = zip(*optimizer.compute_gradients(loss)) gradients, _ = tf.clip_by_global_norm(gradients, grad_clip) updates = optimizer.apply_gradients(zip(gradients, v),global_step=global_step)
def clip_by_average_norm(t, clip_norm, name=None):
t
爲張量,clip_norm
爲maximum clipping value深度學習
裁剪方式以下,
$$ t \times \frac{clip\_norm}{max(avg\_norm, clip\_norm)}$$
其中,avg_norm=l2norm_avg(t)
it
def clip_by_norm(t, clip_norm, axes=None, name=None):
t
爲張量,clip_norm
爲maximum clipping value
裁剪方式爲
$$t \times \frac{clip\_norm}{l2norm(t)}$$
示例代碼io
optimizer = tf.train.AdamOptimizer(learning_rate, beta1=0.5) grads = optimizer.compute_gradients(cost) for i, (g, v) in enumerate(grads): if g is not None: grads[i] = (tf.clip_by_norm(g, 5), v) # clip gradients train_op = optimizer.apply_gradients(grads)
注意到,clip_by_value
、clib_by-avg_norm
和clip_by_norm
都是針對於單個張量的,而clip_by_global_norm
可用於多個張量組成的列表。