梯度爆炸问题的介绍和如何解决爆炸问题详细概述

描述

最近在做一个文本检测的项目,在训练的过程中遇到了很严重的梯度爆炸情况,今天就来谈谈梯度爆炸怎么解决。

首先我们要清楚,为什么会产生梯度爆炸。要知道就目前来说,我们一般都认为深层的神经网络会比浅层的神经网络的表现要好,所以在处理一些较为复杂的任务的时候,人们往往会使用更深层次的神经网络,而现在的大部分神经网络的权重更新都要依靠反向传播。

那么,问题来了。要知道权重的更新的公式是这样的:

梯度

对于每个变量的更新,都要求梯度,也就是求链式偏导。假如,我们想象一下,我们的模型处在一个很陡的陡坡上,那么在求梯度的时候,在网络层上出现了指数型的递增,也就是说,梯度爆炸了。

那么具体上是怎么样的呢?我们来看下面这张图:

梯度

可以看到,上面是我输出的每一步的损失函数的值,损失值在指数型地增加。nan是not a number的意思,它表示无穷大的数或者无意义的数。遇到这个问题的时候,我第一反应是:是不是我学习率太大了。然后我调小了学习率,发现情况有所改善,但是到最后还是出现的梯度爆炸。然后我又思考,会不会是我网络结构有问题啊,为了验证这问题,我把batch size调为了1,固定输入一张图片,发现也是收敛到一定程度也出现了梯度爆炸的情况。那么我可以断定了,是由于网络层数过多导致的梯度爆炸的问题。

问题找到了,那我面临了两个选择:一是降低网络层数,二是做梯度裁剪。考虑到了数据的复杂性,我选择了后者。好,那就来说说梯度裁剪是什么?如何做梯度裁剪。

梯度裁剪

梯度裁剪是指在一个变量计算的梯度过大的情况下,人为地将梯度控制在一定的范围以内。

梯度

那直接来看一下代码实现。

optimizer = tf.train.GradientDescentOptimizer(learning_rate)params = tf.trainable_variables()gradients = tf.gradients(loss, params)clipped_gradients, norm = tf.clip_by_global_norm(gradients, clip_norm)optimizer_op = optimizer.apply_gradients(zip(clipped_gradients, params), global_step)

你只要设置里面的clip_norm就可以了,那么设置多少合适呢?

梯度

t_list在这里是所有梯度的张量,然后可以看下它是怎么算的。如果global_norm

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分