clip gradient

算法步骤如下。

  • 首先设置一个梯度阈值:clip_gradient
  • 在后向传播中求出各参数的梯度,这里我们不直接使用梯度进去参数更新,我们求这些梯度的l2范数
  • 然后比较梯度的l2范数||g||与clip_gradient的大小
  • 如果前者大,求缩放因子clip_gradient/||g||, 由缩放因子可以看出梯度越大,则缩放因子越小,这样便很好地控制了梯度的范围
  • 最后将梯度乘上缩放因子便得到最后所需的梯度 


作者:Gein Chen

链接:https://www.zhihu.com/question/29873016/answer/77647103
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

clip_gradient 的引入是为了处理gradient explosion的问题。当在一次迭代中权重的更新过于迅猛的话,很容易导致loss divergence。clip_gradient 的直观作用就是让权重的更新限制在一个合适的范围。

具体的细节是,
1.在solver中先设置一个clip_gradient
2.在前向传播与反向传播之后,我们会得到每个权重的梯度diff,这时不像通常那样直接使用这些梯度进行权重更新,而是先求所有权重梯度的平方和sumsq_diff,如果sumsq_diff > clip_gradient,则求缩放因子scale_factor = clip_gradient / sumsq_diff。这个scale_factor在(0,1)之间。如果权重梯度的平方和sumsq_diff越大,那缩放因子将越小。
3.最后将所有的权重梯度乘以这个缩放因子,这时得到的梯度才是最后的梯度信息。

这样就保证了在一次迭代更新中,所有权重的梯度的平方和在一个设定范围以内,这个范围就是clip_gradient.


最后补充一点,这个参数多用于LSTM中,而我这个回答是基于jeffdonahue 在caffe Pull的RNN 代码,你可以在 jeffdonahue/caffe at recurrent · GitHub 中的src/caffe/solver.cpp里看到具体的实现代码。


作者:圣行
链接:https://www.zhihu.com/question/29873016/answer/48682130
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

SolverParameter中的clip_gradients,设置为一个大于0的值,作为一个阈值,在计算当前梯度的时候,如果该值超过了该阈值,则将梯度直接设置为该阈值。
增加这个设计的原因,应该是源于这个回答( Handle divergence/NaNs gracefully · Issue #1349 · BVLC/caffe · GitHub):
I'm encountering a problem I never had before. So usually the loss either diverge soon and generate NaNs or start converging and never diverges again. However, recently in some experiments I'm encountering the problem that the loss start converging, and after a while 45K iterations diverges.
We need to do something about this, in addition to stop, maybe we could log what caused the NaN to appear.
Also maybe adding gradient clipping could help, **** could you do a PR with the gradient clipping?

作者:Weijie Huang
链接:https://www.zhihu.com/question/29873016/answer/106125794
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

arxiv.org/abs/1211.5063
On the difficulty of training Recurrent Neural Networks
这篇文章最早提出了Gradient clipping这个优化,用于解决exploding gradients 问题.
-----
把关联的问题也回答了吧

##Vanishing Gradients是什么,如何解决这个问题
###如果一个神经网络有超过1层比如4层的话,bp算法会使得四层学习的速度逐步递减,layer4>layer3>layer2>layer1,这意味着在前面的隐藏层中的神经元学习速度要慢于后面的隐藏层.
###BP的本质是对神经元的输出z进行纠正,通过对他求梯度作一个反方向的偏移,这里假设我们Layer1的b要进行反向传播更新权值,那么可以得出公式:"neuralnetworksanddeeplearning.com", 这样可以观察到这个等式传播的时候有两个关键点,一个是w权值,一个是sigmoid'(z).sigmoid'(z)是一个max=0.25的正态分布图,所以随着Layers越多显然这个学习的速度就会至少降低75%,所以会产生这个Vanishing Gradients问题.同理,如果这个w权值非常大的话,那么理论上整个乘积也会放大,但是sigmoid'函数里面的z是等于(wx + b),这个数值越大则sigmoid'越靠两边其实数值越小,所以其实最后的学习率通常来讲都是越来越小的.

##Exploding gradient是什么,如何解决这个问题
###梯度爆炸就是当上面的w控制在一个非常大的值,同时sigmoid'也非常大,两个的乘积都大于1的时候,就有了梯度爆炸的问题.

###解决方法:通过对w进行pre-trained可以通过更改w权值来解决Vanishing Gradients,或者更改激活函数从sigmoid换成ReLU,这样ReLU是1/0函数,不会使得传播的时候持续缩小了

###解决方法:gradient clipping解决了Exploding gradient问题,把每次更新的gradient压缩在clip范围内,就不会无限制的连乘导致偏离了.

cs224d.stanford.edu/lec
[译] 第五章 深度神经网络为何很难训练

##是因为BP训练才产生Exploding gradient和Vanishing Gradients的问题吗
### 应该是的,因为BP训练的过程才得到了上面的等式,才有了这么一系列推论.

Neural networks and deep learning

修改了好几次这个答案,有错误还请指正

猜你喜欢

转载自blog.csdn.net/xiewenbo/article/details/80336687