Dropout
Dropout
Dropout 是在训练过程中已一定概率使神经元失活,即输出为 0,能提高模型的泛化能力,减少过拟合
平衡训练和测试差异
在测试阶段,Dropout 会被关闭。
为了保持训练阶段和测试阶段的输出期望相同,在以 的概率对神经元失活的同时,会将剩下保留的神经元的输出乘 。
实现代码
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 在训练时会把以 的概率将隐藏层的神经元置为零,同时会将其他神经元乘以 ,保证输出值期望的一致性,即:
接下来我们来推导一下 dropout 输出值的均值和方差(这里是为了推出经过 dropout 层后方差发生了变化),为了方便计算,我们把 dropout 单独表示成一个随机变量,假设 d 为一个服从二项分布的随机变量( 的概率取 0, 的概率取 1),则根据二项分布的公式,d 的均值为 , 方差为 , 假设原来的隐藏层为随机变量 , 则经过 dropout 后可以用如下公式表示:
接下来来计算下这个东西的均值和方差:
首先是均值:
可以发现均值是没有发生变化的
然后是方差,这里直接套用计算两个随机变量相乘后方差的公式:
可以发现,经过 dropout 之后,输出的均值没有发生变化,但是方差发生了变化。
如果使用了dropout,在训练时隐藏层神经元的输出的方差会与验证时输出的方差不一致,这个方差的变化在经过非线性层的映射之后会导致输出值发生偏移,最终导致了在验证集上的效果很差。
由于回归问题输出是一个绝对值,对这种变化就很敏感,但是分类问题输出只是一个相对的logit,对这种变化就没那么敏感,因此,在回归问题上最好不要用dropout,而在分类问题上才用dropout
本文来自博客园,作者:Un-Defined,转载请保留本文署名Un-Defined,并在文章顶部注明原文链接:https://www.cnblogs.com/EIPsilly/p/18381892
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人