知乎: Lukan

来源: https://zhuanlan.zhihu.com/p/561124500
最近在做一个nlp的回归任务,所以直接套用之前做分类问题的的代码,仅仅修改了下损失函数而已,结果发现验证损失一直在震荡,不收敛,但是别人的代码loss却能够稳定下降,最终下降到0.1左右,而我的只能却一直飘,最终只下降到0.14,如下图:
最后通过对比别人的代码,我发现其实就两行代码的差异:
这边把bert内部的dropout全部关掉了,于是我也尝试了这种做法,最终得到这样的一个loss,对比一下,这个loss下降就很平稳了,而且最小值明显低很多
很神奇是不是,按照之前学的,dropout相当于ensemble,按理应该是能够防止过拟合,增加模型稳健性的,怎么到了我这里,用了dropout反而性能损失这么大?
于是我在讨论区发了个帖子问了一下,有个大佬给了我回复:
通过阅读他给出的两个链接(见文末链接),我终于明白了问题的根源,总结一下,我做的这个是回归任务,回归任务是不能用dropout的,接下来结合我自己的理解阐述一下为什么
首先回顾一下dropout的用法
dropout在训练时会把以的概率将隐藏层的神经元置为零,同时会将其他神经元乘以,保证输出值期望的一致性:
这其实就是个二项分布,根据二项分布计算的公式,输出值的均值为:,这是没有变化的。
但是方差变成了:,可以发现,经过dropout之后,输出的均值没有发生变化,但是方差发生了变化
由于后面这个输出还要经过非线性层(比如Linear层+ReLU),方差的变化就会导致经过后面非线性层输出的均值发生偏移,最终导致整个网络的输出值发生偏移,也就是说,如果使用了dropout,在训练时隐藏层神经元的输出的方差会与验证时输出的方差不一致,这个方差的变化在经过非线性层的映射之后会导致输出值发生偏移,最终导致了在验证集上的效果很差。
由于回归问题输出是一个绝对值,对这种变化就很敏感,但是分类问题输出只是一个相对的logit,对这种变化就没那么敏感,因此,在回归问题上最好不要用dropout,而在分类问题上才用dropout,后面查了下发现也有一篇论文的实验佐证了这一观点:
Effect of Dropout Layer on Classical Regression Problems
不过,根据上面的分析,其实dropout最好是不要加在网络的中间,在最后输出层前面加应该还是没问题的,根据我自己的实验来看,dropout加在最后一层是没有观察到明显的性能损失的,但是也没有提高就是了,因此,回归任务干脆就别用dropout了

参考

  1. Pitfalls with Dropout and BatchNorm in regression problems: https://towardsdatascience.com/pitfalls-with-dropout-and-batchnorm-in-regression-problems-39e02ce08e4d
  2. The Magic of No Dropout: https://www.kaggle.com/competitions/commonlitreadabilityprize/discussion/260729
  3. Effect of Dropout Layer on Classical Regression Problems: https://www.researchgate.net/publication/344274687_Effect_of_Dropout_Layer_on_Classical_Regression_Problems

📝论文解读投稿,让你的文章被更多不同背景、不同方向的人看到,不被石沉大海,或许还能增加不少引用的呦~ 投稿加下面微信备注“投稿”即可。
最近文章

下载一:中文版!学习TensorFlow、PyTorch、机器学习、深度学习和数据结构五件套!后台回复【五件套
下载二:南大模式识别PPT后台回复南大模式识别

投稿或交流学习,备注:昵称-学校(公司)-方向,进入DL&NLP交流群。
方向有很多:机器学习、深度学习,python,情感分析、意见挖掘、句法分析、机器翻译、人机对话、知识图谱、语音识别等
记得备注~
继续阅读
阅读原文