资讯详情

资讯详情

12种Dropout方法全解析:从原理到实战选型指南

1. 为什么dropout值得单独拿出来讲但凡动手训过几个像样的神经网络你大概率都遇到过这种场景模型在训练集上准确率一路飙到99%损失曲线漂亮得像教科书结果一放到验证集上就原形毕露掉到七八十。这种落差背后过拟合几乎是头号嫌疑人。而对抗过拟合的手段里dropout是最早被大规模验证、也最容易被低估的一招。很多人对dropout的理解停留在“训练时随机丢神经元测试时全用上”这一句话。这句话没错但它只覆盖了最经典的那一种。实际上从2012年那篇引爆深度学习热潮的工作开始dropout已经演化出一个不小的家族有按元素独立丢弃的有按通道整块丢弃的有按区域连续丢弃的有在循环结构里沿时间轴共享掩码的还有把丢弃概率本身也做成可学习参数的。这些方法各自解决不同结构、不同任务下的具体问题数学形式差别不小视觉直觉也完全不一样。这篇东西就是想把这条线捋清楚。我会把12种主要的dropout方法逐个拆开讲清楚它们的数学定义、背后的直觉、适合什么场景以及我在实际项目里踩过的坑。适合已经能跑通基础网络、想进一步理解正则化细节的读者也适合正在调模型、被过拟合折磨得没脾气的从业者。你不需要有很深的数学背景我会尽量用生活化的类比把公式讲明白但该有的严谨性不会丢。2. 先建立统一的心智模型2.1 dropout到底在做什么要理解各种dropout变体先得抓住它们的共同本质。训练一个神经网络本质上是在一个巨大的参数空间里找一组权重让模型在训练数据上的损失最小。问题是训练数据只是真实分布的一个采样模型很容易记住这些样本的噪声而不是学到背后的规律。dropout的思路很直接既然模型可能依赖某些特定的神经元组合来“死记硬背”那我就在训练时随机把这些组合打散逼着网络学会用冗余的、更鲁棒的特征来表达。从数学上看标准dropout在训练时对某一层的激活值h施加一个随机掩码m每个元素以概率p被置零然后为了保持期望不变把剩下的值除以(1-p)。用公式写就是h (m ⊙ h) / (1 - p)其中m的每个元素独立地服从伯努利分布取1的概率是1-p取0的概率是p。测试阶段不做丢弃直接使用完整的h。这个除以(1-p)的操作叫inverted dropout是现代框架的默认做法好处是测试时不用做任何缩放推理路径干净。注意早期有些实现是在测试时乘以(1-p)训练时不缩放。这两种在数学上等价但推理时多一次乘法。现在主流框架默认都是训练时缩放你如果读老代码看到测试阶段有缩放操作不要觉得奇怪。2.2 一个统一的视角噪声注入把dropout看成一种噪声注入很多变体就串起来了。标准dropout注入的是乘性的伯努利噪声每个位置独立。改变噪声的分布、改变噪声作用的结构单元、改变噪声是否共享就得到了不同的dropout方法。比如把独立伯努利换成结构化掩码就是DropBlock把沿时间轴共享掩码就是RNN上的变分dropout把丢弃概率做成可学习就是Concrete dropout那一类。这个视角的好处是你不需要死记12个公式而是记住“噪声怎么设计”这一个问题。下面逐个展开的时候我会反复回到这个框架。2.3 训练与推理的不一致问题所有dropout方法都面临同一个矛盾训练时有噪声推理时没有。标准做法是用期望来对齐也就是训练时缩放。但对于一些复杂变体比如丢弃概率可学习的方法期望对齐就没那么简单了往往需要蒙特卡洛采样或者专门的推理近似。这一点在选型时很关键如果一个方法的推理成本太高哪怕训练效果再好落地时也要掂量。3. 十二种dropout方法逐个拆解3.1 标准Dropout一切的原点标准dropout就是前面说的按元素独立伯努利掩码。它的数学形式简单到不能再简单但效果出奇地好。直觉上它相当于在训练时对网络做了一次隐式的模型集成因为每个batch看到的都是不同的子网络。测试时用完整网络近似于对这些子网络做平均。适用场景全连接层是它的主战场。卷积层上用标准dropout效果通常一般因为卷积核的参数共享特性让空间上的独立丢弃意义不大后面会讲为什么。实操心得丢弃概率p的选取很讲究。全连接层常用0.5输入层常用0.2左右。p太大模型欠拟合p太小起不到正则作用。我一般从0.3开始试根据训练集和验证集的gap来调。如果gap大就加大pgap小甚至验证集更好就减小p。3.2 高斯Dropout乘性噪声的连续版本标准dropout的掩码是0或1比较粗暴。高斯dropout把掩码换成均值为1的连续随机变量通常是正态分布。公式变成h h ⊙ n, n ~ N(1, σ²)这样每个神经元不是被完全丢弃而是被一个接近1的随机数缩放。直觉上这比硬性置零更平滑梯度信息保留得更好。有工作表明在某些任务上高斯dropout比标准dropout收敛更稳。适用场景当训练不稳定、损失震荡明显时可以试试把标准dropout换成高斯版本。它的噪声是乘性的、连续的对激活值的扰动更温和。3.3 高斯Dropout的变体均匀噪声与指数噪声把高斯分布换成均匀分布或者指数分布就得到另外两种乘性噪声dropout。均匀噪声在[1-a, 1a]上采样实现简单计算量小。指数噪声则偏向于产生小于1的缩放因子相当于更倾向于“削弱”而不是“增强”激活。这几种之间的选择说实话没有铁律。我的经验是如果你的激活值本身方差就大用均匀噪声更可控如果希望噪声有方向性指数噪声可以一试。但大多数情况下标准dropout和高斯dropout已经够用这些变体更多是锦上添花。3.4 DropConnect丢权重而不是丢激活DropConnect的思路很巧妙不丢神经元的输出而是丢连接权重。对权重矩阵W施加随机掩码M前向传播变成h f((M ⊙ W) x b)从集成角度看DropConnect的假设空间比标准dropout更大因为它每个样本对应的是不同的权重子集而标准dropout对应的是不同的激活子集。理论上DropConnect的容量更强但计算和实现稍复杂。适用场景全连接层为主尤其是参数量大、容易过拟合的层。我在一个小样本分类任务上对比过DropConnect比标准dropout的验证集准确率高了一个多点但训练时间增加了约15%因为掩码作用在权重上矩阵乘法没法像激活掩码那样简单。注意DropConnect在推理时同样需要缩放而且因为掩码作用在权重上缩放的对象是权重而不是激活。实现时容易搞混建议直接参考成熟框架的实现。3.5 空间Dropout卷积层的整通道丢弃卷积层上直接用标准dropout效果不好原因前面提过卷积核在空间上共享你随机丢一个位置相邻位置还有几乎相同的信息网络很容易补回来。空间dropoutSpatial Dropout的做法是对某个通道的所有空间位置一起丢弃。这样丢的是整个特征图网络没法从邻域恢复正则效果明显更强。公式上对第c个通道生成一个标量掩码m_c然后H[c, :, :] m_c * H[c, :, :] / (1 - p)适用场景卷积网络的特征提取部分。尤其是通道数多、特征图冗余度高的网络空间dropout能有效减少通道间的共适应。实操心得空间dropout的p不要设太大0.1到0.2比较常见。因为丢的是整个通道信息损失比标准dropout大得多p大了直接欠拟合。我一般从0.1开始观察验证集表现再微调。3.6 DropBlock连续区域丢弃空间dropout丢的是整个通道但有时候我们希望丢的是空间上的连续区域模拟遮挡的效果。DropBlock就是干这个的在每个特征图上随机选若干中心点然后把周围block_size × block_size的区域全部置零。它的数学形式比空间dropout复杂一点因为要控制实际丢弃的元素比例。设block_size为b特征图面积为S期望丢弃比例为p则每个位置被选为中心的概率需要调整。具体实现里通常先算出一个gamma再按gamma采样中心点。适用场景图像分类、目标检测这类对空间结构敏感的任务。DropBlock在ResNet类网络上替代空间dropout往往能带来稳定的提升尤其是数据量不够大的时候。我在一个图像分类项目里把空间dropout换成DropBlockblock_size设为7验证集准确率提升了约1.5个百分点。但block_size不能乱设太小退化成标准dropout太大丢的信息过多。经验值是特征图尺寸的1/8到1/4之间。3.7 循环DropoutRNN上的朴素做法RNN的结构和CNN、MLP都不一样它有时间维度。最朴素的循环dropout是在每个时间步独立地对输入或输出施加标准dropout。但这样做有个问题每个时间步的掩码不同相当于给RNN注入了高频噪声破坏了时间上的连续性效果往往不好。所以朴素循环dropout一般不推荐单独使用它更多是作为其他方法的对照基线。如果你在RNN上直接套标准dropout发现效果变差不要怀疑dropout本身而是方法没选对。3.8 变分Dropout沿时间轴共享掩码变分dropoutVariational Dropout的核心改进是同一个序列内所有时间步共享同一个掩码。这样噪声在时间上是连续的不会破坏RNN的记忆机制。公式上对序列的每个时间步t使用同一个掩码mh_t (m ⊙ h_t) / (1 - p)直觉上这相当于对每个序列采样一个子网络然后让这个子网络跑完整个序列。这比每个时间步换一个子网络合理得多。适用场景所有RNN、LSTM、GRU结构。这是RNN上dropout的默认推荐做法效果稳定实现也不复杂。实操心得变分dropout通常作用在输入和输出上而不是循环连接内部。因为循环连接上的掩码如果共享梯度传播的路径会变得很复杂容易出问题。我一般只在embedding输出和RNN输出上加变分dropout循环权重不动。3.9 区域Dropout按特征维度分组丢弃区域dropoutZoneout是专门为RNN设计的另一种思路它不是丢弃激活而是让某些神经元保持上一时间步的状态。公式上h_t d ⊙ h_{t-1} (1 - d) ⊙ h_t_new其中d是随机掩码。这相当于在时间维度上做了一种随机跳跃连接让信息可以跨时间步直接传递。适用场景长序列建模尤其是需要长期记忆的任务。Zoneout和变分dropout可以叠加使用一个管输入输出的噪声一个管状态更新的噪声。3.10 注意力DropoutTransformer时代的常客Transformer结构里dropout被用在了多个位置注意力权重上、残差连接后、前馈网络里。注意力dropout特指对softmax后的注意力权重施加dropout让某些位置对之间的注意力被随机切断。这个做法在训练大模型时几乎是标配。直觉上它防止模型过度依赖某几个特定的注意力连接鼓励更分散的注意力分布。适用场景所有基于注意力的结构。p值通常设得比较小0.1左右因为注意力权重本身已经是归一化的丢太多会破坏信息聚合。3.11 嵌入Dropout输入层的正则嵌入dropout是对输入嵌入向量施加dropout。它和标准dropout形式一样只是作用位置在嵌入层。别小看这一层输入端的噪声会随着网络深度被放大正则效果往往比中间层更明显。适用场景NLP任务、推荐系统等有嵌入层的模型。p一般设0.1到0.3。实操心得嵌入dropout和词级别的dropout可以叠加。词级别是随机把某个词替换成unk或者删除嵌入级别是在向量上做扰动。两者结合对文本任务的泛化提升很明显。3.12 可学习Dropout让网络自己决定丢弃率前面所有方法的丢弃概率p都是超参数需要人工调。可学习dropout比如Concrete Dropout把p也变成可学习的参数通过重参数化技巧让梯度能传过去。这样网络可以根据数据自动调整每个层、甚至每个神经元的丢弃率。数学上它用连续松弛来近似离散的伯努利采样使得整个采样过程可微。训练时同时优化权重和丢弃率。适用场景数据量变化大、难以手动调参的任务。它的优势是省去了调p的麻烦代价是实现复杂、训练稍慢。我在一个数据量中等的回归任务上试过自动学出来的p在不同层差异很大浅层接近0.1深层接近0.4比手动设统一值效果好。4. 方法对比与选型建议4.1 十二种方法速查表方法作用对象噪声类型适用结构推理是否缩放标准Dropout激活独立伯努利MLP是高斯Dropout激活乘性高斯MLP是均匀噪声Dropout激活乘性均匀MLP是指数噪声Dropout激活乘性指数MLP是DropConnect权重独立伯努利MLP是空间Dropout通道通道级伯努利CNN是DropBlock空间区域结构化伯努利CNN是朴素循环Dropout激活独立伯努利RNN是变分Dropout激活时间共享伯努利RNN是Zoneout状态时间共享伯努利RNN否注意力Dropout注意力权重独立伯努利Transformer是可学习Dropout激活可微松弛通用近似4.2 按结构选型MLP结构优先考虑标准dropout或DropConnect。如果训练不稳定换高斯dropout。CNN结构优先空间dropout或DropBlock数据量小用DropBlock数据量充足用空间dropout即可。RNN结构优先变分dropout长序列加Zoneout。Transformer结构注意力dropout是标配嵌入dropout看任务加。4.3 按任务选型分类任务对dropout的容忍度较高p可以稍大。回归任务对噪声敏感p要小或者用高斯这类温和的噪声。生成任务要小心dropout太强会破坏生成质量通常只在判别器或编码器上用。5. 实操中的坑与排查5.1 训练和验证gap不降反升这是最常见的困惑加了dropout验证集反而更差了。原因通常有三个。一是p设太大模型欠拟合训练集都没学好。二是作用位置不对比如在BN层后面直接加dropout两者会打架。三是推理时忘了切换模式框架里model.eval()没调用导致推理时还在丢弃。排查顺序先确认推理模式正确再检查p值最后看作用位置。BN和dropout同时用时一般把dropout放在BN之前或者干脆二选一。5.2 卷积层上加dropout没效果前面解释过标准dropout在卷积层上效果弱因为空间冗余。解决办法是换空间dropout或DropBlock。如果你在卷积层上加了标准dropout发现验证集没变化不要急着否定dropout先换方法。5.3 RNN上dropout导致训练发散朴素循环dropout在RNN上容易发散因为时间步之间的噪声不连续。换成变分dropout并且只作用在输入输出上通常就能解决。如果还发散检查梯度裁剪有没有开RNN的梯度爆炸和dropout叠加会放大问题。5.4 可学习dropout的推理成本可学习dropout在推理时通常需要蒙特卡洛采样来近似期望这意味着推理要跑多次前向。如果延迟敏感这个成本要提前评估。我的做法是训练时用可学习dropout推理时把学到的p固定用标准dropout的缩放方式做单次推理效果损失很小但速度快很多。5.5 常见问题速查现象可能原因解决方向验证集变差p太大或位置不对减小p调整位置训练不收敛噪声太强换温和噪声或减小p卷积层无效方法不匹配换空间dropout/DropBlockRNN发散时间噪声不连续换变分dropout推理变慢采样次数多固定p做单次推理6. 我个人的几条经验调dropout这件事说到底是在偏差和方差之间找平衡。我自己的习惯是先把模型训到过拟合确认模型容量够然后再加dropout去压方差。如果一上来就加很强的dropout你根本不知道模型本身能学到什么程度。p值的调整我一般用二分法从0.5开始如果欠拟合就减半如果还过拟合就加0.1几次就能找到合适区间。不同层的p可以不一样浅层小、深层大是常见规律因为深层特征更抽象、更容易共适应。还有一个容易被忽略的点dropout和数据增强是互补的不是替代关系。图像任务里数据增强管输入空间的多样性dropout管特征空间的冗余两者一起用效果最好。我见过有人用很强的数据增强就不加dropout结果模型还是在训练集上过拟合因为增强没覆盖到的模式还是被记住了。最后别迷信任何一种dropout。12种方法没有绝对优劣只有适不适合你的结构和数据。多试几种用验证集说话比看论文里的对比表靠谱得多。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →