我在RNN上关注this tutorial,在第177行执行以下代码。
max_grad_norm = 10
....
grads, _ = tf.clip_by_global_norm(tf.gradients(cost, tvars), max_grad_norm)
optimizer = tf.train.GradientDescentOptimizer(self.lr)
self._train_op = optimizer.apply_gradients(zip(grads, tvars),
global_step=tf.contrib.framework.get_or_create_global_step())
我们为什么要clip_by_global_norm
? max_grad_norm
的价值是如何决定的?
答案 0 :(得分:9)
削减规范的原因是否则可能爆炸:
正确训练复发有两个众所周知的问题 神经网络,消失和爆炸梯度问题 在Bengio等人中有详细介绍。 (1994)。在本文中,我们试图改进 通过探索这些问题来理解潜在的问题 从分析,几何和动态系统的角度来看。 我们的分析用于证明一个简单而有效的解决方案。我们 提出一种梯度范数裁剪策略来处理爆炸 梯度
以上摘自this论文。
就如何设置max_grad_norm
而言,您可以稍微使用它来查看它对结果的影响。这通常设置为非常小的数字(我在几个案例中看到过5个)。请注意,tensorflow不会强制您指定此值。如果不这样做,它将自己指定(如documentation中所述)。
rnn中爆炸\消失梯度的常见原因是因为在进行反向传播时(这称为反向传播),我们需要将梯度矩阵一直乘以t=0
(即,如果我们目前在t=100
,比如句子中的100个字符,我们需要乘以100个矩阵)。以下是t=3
:
(此等式取自here)
如果矩阵的范数大于1,它最终会爆炸。它小于1,它最终会消失。如果它们具有许多隐藏层,则这可能发生在通常的神经网络中。然而,前馈神经网络通常没有那么多隐藏层,而rnn的输入序列很容易有很多字符。