什么是 dropblock

文章介绍了卷积神经网络中dropout表现不佳的原因,并引入了dropblock作为结构化dropout解决方案。Dropblock通过一次性丢弃整个特征图区域而非单个单元,有效防止过拟合,提升模型性能。作者还提到了dropblock在ImageNet任务中的应用实例和发文章的新思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家好啊,我是董董灿。

之前介绍过 dropout 算法,它在训练神经网络中,可以随机丢弃神经元,是一种防止网络过拟合的方法。

但是在卷积神经网络中,dropout 的表现却不是很好,于是研究人员又搞了一个“结构化的 dropout 方法”,称为 dropblock,据说在卷积神经网络中表现不错。

今天就一起来看看,什么是 dropblock 吧。

1、卷积层中为什么 dropout 表现不好

dropout 在卷积层表现不好,是因为在卷积层中,特征图中的每个像素都与周围的像素高度相关。

这是由于图像像素具有局部性表达所引起的,所谓的局部性可以查看要学计算机视觉,先了解图像和像素

由于卷积的特征图中相邻位置元素在空间上会共享语义信息,所以尽管某个单元被 dropout 掉,但与其相邻的元素依然可以保有该位置的语义信息,相关的信息仍然可以在卷积网络中流通。

因此,看似丢掉了信息,实际上并没有完全丢掉。

2、dropblock是怎么做的

为了解决这些问题,研究人员提出了一种新方法: dropblock。

dropblock 是一种结构化的 dropout 方法,它可以同时丢弃特征图中的一整块激活区域,而不是随机丢弃一个激活单元。

可以说是一种加宽加大版的 dropout 方法了。

我们以下面的图示来举个例子说明。

图片

图(a) 代表卷积神经网络的输入图像,是一只狗子。

图(b) 和图(c) 中的绿色区域为这只狗子的图片经过了卷积运算之后得到的激活图像,绿色方块包含了激活单元。

由于图像像素局部性的存在,假设绿色区域中左上角激活的为狗子的耳朵,中间部分激活的为狗子的嘴巴,右下激活的为狗子的腿。

那么如图 b 所示,随机丢弃激活单元的方法,仅仅是丢弃了单个单元,剩余的绿色区域中仍然包含了原来的特征(比如耳朵、嘴巴和腿的特征),因此这种单纯的 dropout 方法并不有效。

而连续地将一大块区域丢弃(图c),却可以直接丢掉一些特定的区域信息(比如将左上角的耳朵信息全部丢掉,或者右下角的腿的信息),从而强制剩余的神经元去学习更重要的特征。

假设这是一个图像分类网络,那么剩余的神经元就会被强制去学习其他更有利于分类的特征。

目前,dropblock 已经被应用于许多CNN模型中,包括ResNet、DenseNet、MobileNet、EfficientNet 和 RetinaNet 等。

在ImageNet分类任务中,使用dropblock 的ResNet-50模型的准确率达到了78.13%,比传统的dropout方法提高了1.6%。

3、一个发文章的新思路

发现没有,搞 AI 算法这么卷,大家都在绞尽脑汁对算法进行变形,dropout 这种丢弃单一神经元的方法不好使,那我就整块整块的丢,效果挺好那就是一篇顶刊。

有个网友(知乎:Kevin S)对这种丢弃神经元的方法做了个总结,很有意思:

  • Dropout:完全随机扔

  • SpatialDropout :按channel随机扔

  • Stochastic Depth:按res block随机扔

  • DropBlock:每个feature map按spatial块随机扔

  • Cutout:在input层按spatial块随机扔

  • DropConnect:只在连接处扔,神经元不扔

每一种扔法都是一个顶刊文章,小伙伴们觉得怎么样,是不是打开了发文章的新思路了呢?

参考

1. 论文:Wu, Y., He, K., & Hoiem, D. (2018). DropBlock: A regularization method for convolutional networks. arXiv preprint arXiv:1810.12890.

2. ^ 5分钟搞懂 dropblock

### PyTorch中DropBlock的实现及解释 在PyTorch中,DropBlock是一种改进版的正则化技术,旨在解决卷积神经网络训练过程中过拟合的问题。相比于传统的Dropout随机丢弃单个神经元,DropBlock会按照一定规则丢弃特征图上的连续区域。 #### 计算Gamma值 为了应用DropBlock,首先需要根据给定的概率`keep_prob`以及方块大小`block_size`来计算出gamma参数。此过程确保了所选区域既不会过大也不会过小,从而保持模型性能稳定[^5]。 ```python def calculate_gamma(keep_prob, block_size, feature_map_size): gamma = ((1 - keep_prob) / (block_size ** 2)) * \ (feature_map_size[0] * feature_map_size[1]) / \ ((feature_map_size[0] - block_size + 1) * (feature_map_size[1] - block_size + 1)) return gamma ``` #### 创建Mask矩阵 接着创建一个掩码(mask),用于指示哪些位置应该被保留而哪些应当被置零。这一步骤利用到了二项式分布生成器,并结合之前求得的gamma值完成: ```python import torch.nn.functional as F class DropBlock(nn.Module): def __init__(self, block_size, keep_prob): super(DropBlock, self).__init__() self.block_size = block_size self.keep_prob = keep_prob def forward(self, input): if not self.training or self.keep_prob == 1: return input _, c, h, w = input.size() gamma = calculate_gamma(self.keep_prob, self.block_size, (h,w)) mask = (torch.rand_like(input[:, :1, :, :], device=input.device)<gamma).float() ... ``` 此处省略了一些细节处理部分,完整的类定义可以在开源项目中找到更详细的版本[^3]。 #### 应用Mask并返回结果 最后一步就是将上述产生的mask应用于输入张量之上,再乘以缩放因子使得期望输出不变,最终得到经过DropBlock处理后的数据作为函数返回值。 ```python ... block_mask = compute_block_mask( mask, self.block_size, self.gamma, self.block_size, self.block_size) out = input * block_mask[:, None, :, :] out = out / block_mask.mean() if block_mask.numel()>0 else out return out ``` 通过这种方式,在不改变原有架构的基础上引入了一种新的正则化手段——即DropBlock,有助于提高某些特定场景下CNN的表现力[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董董灿是个攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值