dropout以及dropblock

本文探讨了在深度学习中解决过拟合问题的两种方法:Dropout和DropBlock。Dropout通过随机失活神经元抑制特征协同,而DropBlock则针对卷积层,通过失活某一区域来增强网络鲁棒性。文章详细解析了Vanilla Dropout、Inverted Dropout及DropBlock的原理与应用。

在搭建深度卷积神经网络的过程中,当我们拥有的数据比较少的时候,我们经常遇到过拟合问题,为了解决该问题Hinton提出了dropout方法,即其认为过拟合问题可以通过抑制某些特征的协同来缓解。同样,在进行检测过程中,若在卷积层中使用dropout意义并不是很大,由于卷积层可以通过drop掉的神经元附近学习到相似的信息,因此为了在卷积层中防止过拟合现象,出现了dropblock模块,通过随机失活某一个区域来达到抑制信息协同的作用。

Dropout

dropout的实现主要是通过binomial(伯努利)方法,随机生成一个0、1分布的向量,0代表神经元被抑制,1代表神经元激活。dropout主要包含两种,分别是初始Vanilla dropout以及inverted dropout。

Vanilla dropout

输入特征图为X=[X1,X2,X3,X4],对应的权重参数为W=[W1,W2,W3,W4],假设以drop_ratio=0.25来进行伯努利采样,获得对应的Mask为M=[1,0,1,1]。
训练Inference:X’=[X1,0,X3,X4],对应的梯度为[W1,0,W3,W4],由上可以看到在训练的过程中,完整输出是训练输出的1/(1-drop_ratio)。因此在预测的过程中,需要全体输出变小,这个时候预测过程需要跟着Dropout的策略去做对应调整。

Inverted dropout

输入特征图为X=[X1,X2,X3,X4],对应的权重参数为W=[W1,W2,W3,W4],假设以drop_ratio=0.25来进行伯努利采样,获得对应的Mask为M=[1,0,1,1]。
训练Inference:在推理的时候直接进行放大,保持前后的期望一致,X’=(1/0.75)*[X1,0,X3,X4],对应的梯度为(1/0.75)[W1,0,W3,W4],由上可以看到在训练的过程中,Inverted dropout的输出与完整输出的期望是一致的。因此在预测的过程中,不需要再对输出做对应操作。

DropBlock

dropblock主要是用于处理卷积中dropout不能处理的过拟合问题,首先DropBlock需要满足dropout相同的失活元素的个数,而且dropblock主要用于失活一个区域,比如说一张图片上有一只狗,失活掉狗头,通过剩下的部分来识别其类别,增强网络的鲁棒性,所以有一个block_size的超参数需要设置。dropblock用于dropout的神经元个数为(1-keep_ratio)(feature_sizefeature_size)。为了保证dropblock是在特征图上进行操作,需要满足block_size的中心在离特征图边缘一定的距离即(block_size//2),因此满足block_size中心的区域为(feature_size-block_size+1)。
所以,DropBlock 的概率即γ*(block_sizeblock_size),有效的区域面积为(feat_size-block_size+1)(feat_size-block_size+1),最终得到drop掉的元素数目为γ*(block_sizeblock_size)(feat_size-block_size+1)*(feat_size-block_size+1)

最后,dropout==DropBlock ,即让(1-keep_prob)(feat_sizefeat_size)=γ*(block_sizeblock_size)(feat_size-block_size+1)*(feat_size-block_size+1)

这样就会得到伯努利概率γ

### DropBlock简介 DropBlock是一种用于卷积神经网络(CNNs)中的正则化技术,旨在通过随机丢弃特征图上的连续区域来增强模型的泛化能力[^1]。这种方法不同于传统的Dropout,后者是以独立的方式随机丢弃单个神经元。而DropBlock则是以块的形式删除一组相邻单元,从而模拟更复杂的扰动模式。 #### 工作原理 在训练过程中,DropBlock会按照设定的概率`drop_prob`随机选择一些方形区域并将其置零。这些被屏蔽掉的区域不会参与前向传播反向梯度计算过程。随着训练的推进,通常建议逐渐增加`drop_prob`值以便让网络逐步适应这种更强的正则化效果[^4]。 对于PyTorch实现来说,可以自定义一个名为`DropBlock2D`类继承于`nn.Module`,其中主要参数包括: - `block_size`: 被遮挡方块大小; - `gamma`: 控制整体比例因子,最终影响实际dropping概率; 下面给出一段简单的Python代码展示如何构建这样一个模块: ```python import torch from torch import nn import numpy as np class DropBlock2D(nn.Module): def __init__(self, block_size=7, gamma=0.): super(DropBlock2D, self).__init__() self.block_size = block_size self.gamma = gamma def calculate_gamma(self, x): W,H = x.shape[-2:] feat_area = H * W blocked_num = int(feat_area / (self.block_size ** 2)) actual_gamma = min(1., max(0., self.gamma*(blocked_num/feat_area))) return actual_gamma def forward(self,x): if not self.training or self.gamma == 0.: return x batch_size,c,h,w = x.size() total_size = w*h mask = torch.ones_like(x) rand_mask = torch.rand(batch_size, c, h-w+self.block_size+1 ,w-h+self.block_size+1, device=x.device,dtype=torch.float32) _,_,top,left = ((rand_mask<self.calculate_gamma(x)).nonzero(as_tuple=True)) for idx in range(len(top)): i,j,k,l=top[idx],left[idx]+k,top[idx]+j,left[idx]+l mask[...,i:i+self.block_size,j:j+self.block_size]=0. out = x*mask*(mask.numel()/mask.sum()) return out ``` 至于TensorFlow/Keras版本,则可以通过子类化Layer或者利用Lambda层配合tf.image.extract_patches函数达成相似功能。不过具体细节可能有所差异,需依据框架特性调整逻辑流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值