Dropout

UnDefined / 2024-08-27 / 原文

Dropout

目录
  • Dropout
    • 平衡训练和测试差异
    • 实现代码
    • 在回归任务中,用dropout的效果不好

Dropout 是在训练过程中已一定概率使神经元失活,即输出为 0,能提高模型的泛化能力,减少过拟合

平衡训练和测试差异

在测试阶段,Dropout 会被关闭。
为了保持训练阶段和测试阶段的输出期望相同,在以 \(p\) 的概率对神经元失活的同时,会将剩下保留的神经元的输出乘 \(\frac{1}{1-p}\)

实现代码

class MyDropout(torch.nn.Module):
    def __init__(self, p=0.5):
        super(MyDropout, self).__init__()
        self.p = p
        
    def forward(self, x):
        if self.training:
            # 在训练阶段,生成一个与输入 x 相同形状的掩码 mask,并按照概率 p 将其设置为 0 或 1
            mask = (torch.rand(x.shape) > self.p).float()
            # 将输入 x 与掩码相乘,以实现随机丢弃部分神经元
            x = x * mask / (1 - self.p)
        return x

在回归任务中,用dropout的效果不好

参考 https://zhuanlan.zhihu.com/p/561124500

经过dropout之后,输出的均值没有发生变化,但是方差发生了变化
如果使用了dropout,在训练时隐藏层神经元的输出的方差会与验证时输出的方差不一致,这个方差的变化在经过非线性层的映射之后会导致输出值发生偏移,最终导致了在验证集上的效果很差。

由于回归问题输出是一个绝对值,对这种变化就很敏感,但是分类问题输出只是一个相对的logit,对这种变化就没那么敏感,因此,在回归问题上最好不要用dropout,而在分类问题上才用dropout