《ResNeSt: Split-Attention Networks》阅读笔记

目录

一、论文

二、阅读资料

三、网络对比

四、代码

五、论文部分翻译


一、论文

《ResNeSt: Split-Attention Networks》

二、阅读资料

关于ResNeSt的点滴疑惑      

ResNet最强改进版来了!ResNeSt:Split-Attention Networks

【论文笔记】张航和李沐等提出:ResNeSt: Split-Attention Networks(ResNet改进版本)

三、网络对比

1、SE块

《ResNeSt: Split-Attention Networks》阅读笔记_第1张图片

简单地说,把特征图经过卷积操作变为1x1xC大小,当做权重乘到每张特征图上,以起到特征增强的目的。

2、SK块

《ResNeSt: Split-Attention Networks》阅读笔记_第2张图片

简单地说,经过不同的卷积操作,生成大小相同的特征图,然后进行add合并操作,不改变大小,经过卷积操作生成权重,分别乘到两个特征图中,在合并,整个块不改变通道数和大小。得到更加丰富的特征。当然,其中的Split中卷积操作使用分组卷积效果更好。

3、ResNeXt块

《ResNeSt: Split-Attention Networks》阅读笔记_第3张图片

多分支,但使用了组卷积。

4、ResNeSt

《ResNeSt: Split-Attention Networks》阅读笔记_第4张图片《ResNeSt: Split-Attention Networks》阅读笔记_第5张图片

右边图:基数组内的注意力分散。 为了简化图中的可视化,我们在该图中使用c = C/K。

可能现在看起来,大概是一个SK块只分了两路,且就是多个SK块连接起来就构成的SK-Net,但是ResNeSt中分了K个组,每个组又分了r路,增加了网络的宽度。将输入分为K个,每一个记为Cardinal1-k ,然后又将每个Cardinal拆分成R个,每一个记为Split1-r,所以总共有G=KR个组

四、代码

"""Split-Attention"""

import torch
from torch import nn
import torch.nn.functional as F
from torch.nn import Conv2d, Module, Linear, BatchNorm2d, ReLU
from torch.nn.modules.utils import _pair

__all__ = ['SplAtConv2d']

class SplAtConv2d(Module):
    """Split-Attention Conv2d
    """
    def __init__(self, in_channels, channels, kernel_size, stride=(1, 1), padding=(0, 0),
                 dilation=(1, 1), groups=1, bias=True,
                 radix=2, reduction_factor=4,
                 rectify=False, rectify_avg=False, norm_layer=None,
                 dropblock_prob=0.0, **kwargs):
        super(SplAtConv2d, self).__init__()
        padding = _pair(padding)
        self.rectify = rectify and (padding[0] > 0 or padding[1] > 0)
        self.rectify_avg = rectify_avg
        inter_channels = max(in_channels*radix//reduction_factor, 32)
        self.radix = radix
        self.cardinality = groups
        self.channels = channels
        self.dropblock_prob = dropblock_prob
        if self.rectify:
            from rfconv import RFConv2d
            self.conv = RFConv2d(in_channels, channels*radix, kernel_size, stride, padding, dilation,
                                 groups=groups*radix, bias=bias, average_mode=rectify_avg, **kwargs)
        else:
            self.conv = Conv2d(in_channels, channels*radix, kernel_size, stride, padding, dilation,
                               groups=groups*radix, bias=bias, **kwargs)
        self.use_bn = norm_layer is not None
        if self.use_bn:
            self.bn0 = norm_layer(channels*radix)
        self.relu = ReLU(inplace=True)
        self.fc1 = Conv2d(channels, inter_channels, 1, groups=self.cardinality)
        if self.use_bn:
            self.bn1 = norm_layer(inter_channels)
        self.fc2 = Conv2d(inter_channels, channels*radix, 1, groups=self.cardinality)
        if dropblock_prob > 0.0:
            self.dropblock = DropBlock2D(dropblock_prob, 3)
        self.rsoftmax = rSoftMax(radix, groups)

    def forward(self, x):
        x = self.conv(x)
        if self.use_bn:
            x = self.bn0(x)
        if self.dropblock_prob > 0.0:
            x = self.dropblock(x)
        x = self.relu(x)

        batch, rchannel = x.shape[:2]
        if self.radix > 1:
            splited = torch.split(x, rchannel//self.radix, dim=1)
            gap = sum(splited)
        else:
            gap = x
        gap = F.adaptive_avg_pool2d(gap, 1)
        gap = self.fc1(gap)

        if self.use_bn:
            gap = self.bn1(gap)
        gap = self.relu(gap)

        atten = self.fc2(gap)
        atten = self.rsoftmax(atten).view(batch, -1, 1, 1)

        if self.radix > 1:
            attens = torch.split(atten, rchannel//self.radix, dim=1)
            out = sum([att*split for (att, split) in zip(attens, splited)])
        else:
            out = atten * x
        return out.contiguous()

class rSoftMax(nn.Module):
    def __init__(self, radix, cardinality):
        super().__init__()
        self.radix = radix
        self.cardinality = cardinality

    def forward(self, x):
        batch = x.size(0)
        if self.radix > 1:
            x = x.view(batch, self.cardinality, self.radix, -1).transpose(1, 2)
            x = F.softmax(x, dim=1)
            x = x.reshape(batch, -1)
        else:
            x = torch.sigmoid(x)
        return x

五、论文部分翻译

ResNeSt:注意力分散网络

摘要:尽管图像分类模型最近一直在继续发展,但是由于其简单且模块化的结构,大多数下游应用程序(例如对象检测和语义分段)仍将ResNet变体用作骨干网。 我们提供了一个模块化的Split-Attention块,该块可实现跨功能图组的关注。
   通过以ResNet样式堆叠这些Split-Attention块,我们获得了一个称为ResNeSt的新ResNet变体。 我们的网络保留了完整的ResNet结构,可直接用于下游任务,而不会引起额外的计算成本。

ResNeSt模型的模型复杂度优于其他网络。 例如,ResNeSt-50使用224×224的单个作物尺寸在ImageNet上实现了81.13%的top-1精度,比以前的最佳ResNet变种高出1%以上。 此改进还有助于下游任务,包括对象检测,实例分段和语义分段。 例如,通过简单地用ResNeSt-50替换ResNet-50主干,我们将MS-COCO上的FasterRCNN的mAP从39.3%提高到42.3%,并将ADE20K上的DeeplabV3的mIo从42.1%提高到45.1%1。

关键字:ResNeSt,图像分类,转移学习,对象检测,语义分割,实例分割

1 引言

图像分类是计算机视觉研究的基本任务。 经过图像分类训练的网络通常充当为其他应用设计的神经网络的骨干,例如对象检测[22,46],语义分割[6、43、73]和姿势估计[14、58]。 最近的工作通过大规模的神经体系结构搜索(NAS)显着提高了图像分类的准确性[45,55]。 尽管具有最先进的性能,但这些基于NAS的模型通常并未针对培训效率或常规/商业处理硬件(CPU / GPU)上的内存使用进行优化[36]。由于内存消耗过大,这些模型的一些较大版本甚至无法在具有适当的每个设备批处理大小的GPU上进行训练[55]。这限制了NAS衍生模型在其他应用中的应用,特别是涉及密集预测的任务,如分割。

关于下游应用程序的最新工作仍然使用ResNet [23]或其变体之一作为主干CNN。 其简单的模块化设计可轻松适应各种任务。 但是,由于ResNet模型最初是为图像分类而设计的,由于接收场大小有限且缺乏跨通道交互,它们可能不适合各种下游应用。 这意味着要提高给定计算机视觉任务的性能,需要进行“网络手术”来修改ResNet,以使其对特定任务更加有效。例如,某些方法添加了金字塔模块[8,69]或引入了远程连接[  [56]或使用跨渠道特征图关注[15,65]。虽然这些方法确实提高了某些任务的学习学习性能,但它们提出了一个问题:我们是否可以创建具有通用改进特征表示的通用骨干,从而提高性能 跨多个任务?跨通道信息在下游应用中已证明是成功的[56、64、65],而最近的图像分类网络则更侧重于组或深度卷积[27、28、54、60]。 尽管它们在分类任务中具有出色的计算能力和准确性,但这些模型无法很好地转移到其他任务,因为它们的孤立表示无法捕获跨渠道关系[27,28]。 因此,具有跨通道表示的网络是理想的。

作为本文的第一篇贡献,我们探索了ResNet [23]的简单体系结构修改,将功能图拆分注意力纳入各个网络模块中。 更具体地说,我们的每个块都将特征图分为几组(沿通道维数)和更细粒度的子组或分割,其中,每个组的特征表示是通过其分割表示的加权组合确定的(根据全局上下文信息选择权重)。我们将结果单元称为Split-Attention块,它保持简单且模块化。 通过堆叠几个Split-Attention块,我们创建了一个类似ResNet的网络,称为ResNeSt(S表示\ split“)。我们的体系结构不需要比现有ResNet变量更多的计算,并且很容易被用作其他愿景的骨干 任务。

本文的第二个贡献是图像分类和转移学习应用的大规模基准测试。 我们发现,利用ResNeSt主干的模型能够在几个任务上达到最先进的性能,即:图像分类,对象检测,实例分割和语义分割。 建议的ResNeSt优于所有现有的ResNet变体,并且具有相同的计算效率,甚至比通过神经结构搜索生成的最新的CNN模型[55]更好地实现了速度精度的折衷,如表1所示。 在MS-COCO实例分割中,使用ResNeSt-101主干的Cascade-RCNN [3]模型实现了48.3%的框mAP和41.56%的掩码mAP。 我们的单个DeepLabV3 [7]模型再次使用ResNeSt-101主干,在ADE20K场景解析验证集上的mIoU达到46.9%,比以前的最佳结果高出1%以上。 其他结果可以在第5节和第6节中找到。

2、相关工作

现代CNN架构。 自从AlexNet [34]以来,深度卷积神经网络[35]主导了图像分类。 随着这种趋势,研究已经从工程手工功能转移到工程网络体系结构。  NIN [40]首先使用全局平均池化层来代替沉重的全连接层,并采用1×1卷积层来学习特征图通道的非线性组合,这是第一类特征图注意机制。  VGG-Net [47]提出了一种模块化的网络设计策略,将相同类型的网络块重复堆叠,从而简化了网络设计的工作流程,并为下游应用提供了转移学习的机会。公路网[50]引入了公路连接,使信息跨几层流动而不会衰减,并有助于网络融合。  ResNet [23]建立在开拓性工作成功的基础上,引入了身份跳过连接,减轻了深度神经网络中消失梯度的难度,并允许网络学习更深层的特征表示。  ResNet已成为最成功的CNN架构之一,已被各种计算机视觉应用程序采用。

多路径和功能图注意。 多路径表示已在GoogleNet [52]中取得成功,其中每个网络块均由不同的卷积内核组成。  ResNeXt [61]在ResNet瓶块中采用组卷积[34],将多路径结构转换为统一操作。  SE-Net [29]通过自适应地重新校准通道特征响应来引入通道注意机制。  SK-Net [38]引起了两个网络分支对功能图的关注。受先前方法的启发,我们的网络将渠道方面的注意力概括为特征图组表示,可以使用统一的CNN运算符对其进行模块化和加速。

神经架构搜索。 随着计算能力的提高,人们的兴趣已经开始从手动设计的体系结构转移到系统搜索的体系结构,这些体系结构可以适应特定任务。 最近的神经体系结构搜索算法已经自适应地产生了CNN体系结构,该体系结构实现了最新的分类性能,例如:AmoebaNet [45],MNASNet [54]和EfficientNet [55]。 尽管元数据网络结构在图像分类方面取得了巨大成功,但它们彼此之间却截然不同,这使得下游模型难以建立。 相反,我们的模型保留了ResNet元结构,可以将其直接应用于许多现有的下游模型[22、41、46、69]。 我们的方法还可以扩大神经体系结构搜索的搜索空间,并有可能提高整体性能,这可以在以后的工作中进行研究。

3 分散注意力网络

现在,我们引入Split-Attention块,该块启用了跨不同要素图组的要素图关注。 稍后,我们将描述我们的网络实例化以及如何通过标准CNN运营商加速此体系结构。

3.1 分散注意力块

我们的Split-Attention块是一个计算单元,由特征图组和Split Attention操作组成。 图1(右)描绘了SplitAttention模块的概述。

《ResNeSt: Split-Attention Networks》阅读笔记_第6张图片

图1:将我们的ResNeSt块与SE-Net [30]和SK-Net [38]进行比较。 图2中显示了Split-Attention单元的详细视图。为简单起见,我们在基数主视图中显示ResNeSt块(具有相同基数组索引的要素图组彼此相邻)。 我们在实际实现中使用了基数优先级,可以通过组卷积和标准CNN层对其进行模块化和加速(请参阅补充材料)。

特征图组:如在ResNeXt块[61]中一样,特征可以分为几组,特征图组的数量由基数超参数K给出。我们将得到的特征图组称为基数组。 我们引入了一个新的基数超参数R,该基数指示基数组内的分割数,因此特征组的总数为G = KR。 我们可以应用一系列变换到每个单独的组,每个组的中间表示为

将注意力集中在基数组上:继[30,38]之后,每个基团的组合表示可以通过跨多个分割的逐元素求和来融合而获得。 第k个基团的表示为,其中,H,W和C是块输出特征图的大小。
   可以使用跨空间维度的全局平均池来收集具有嵌入式通道统计信息的全局上下文信息[29,38]。 在这里,第c个分量的计算公式为:

基数组表示的加权融合是使用通道方式的软注意力聚合的,其中,每个特征图通道是使用拆分后的加权组合生成的。 第c个通道的计算公式为:

表示(软)分配权重:

《ResNeSt: Split-Attention Networks》阅读笔记_第7张图片

映射根据全局上下文表示确定第c个通道的每个分割的权重。

ResNest块: 然后,将基数组表示形式沿通道维度连接起来: 与标准残差块中一样,如果输入和输出要素图共享相同的形状,则使用快捷连接生成我们的Split-Attention块的最终输出Y:Y = V +X。 对于具有跨步的块,将适当的变换T应用于快捷连接以对齐输出形状:Y = V + T(X)。 例如,T可以是跨步卷积或带池组合卷积。

实例化,加速和计算成本:图1(右)显示了我们的Split-Attention块的实例,其中组变换Fi是1×1卷积,然后是3×3卷积,并且注意权重函数使用带有ReLU的两个完全连接的层进行参数化激活。 我们以基数为主的视图(具有相同基数索引的要素图组彼此相邻)绘制此图,以方便地描述总体逻辑。 通过将布局切换到以基数为主的视图,可以使用标准CNN层(例如组卷积,组完全连接的层和s​​oftmax操作)轻松加速此块,我们将在补充材料中对其进行详细描述。 分割注意块的参数数量和FLOPS与具有相同基数和通道数量的残差块[23,60]大致相同。

与现有注意方法的关系:SE-Net [29]首次引入时,挤压和注意(在原始论文中称为激发)的想法是采用全局上下文来预测通道方面的注意因素。 当radix = 1时,我们的Split-Attention块将挤压和注意操作应用于每个基数组,而SE-Net则在整个块的顶部运行,而与多个组无关。 诸如SK-Net [38]之类的先前模型引入了两个网络分支之间的关注功能,但是它们的操作并未针对训练效率和扩展到大型神经网络进行优化。 我们的方法概括了基数组设置[60]中关于特征图注意[29,38]的先前工作,并且其实现在计算上仍然有效。 图1显示了与SE-Net和SK-Net块的总体比较。

4 网络与训练

现在,我们描述实验中使用的网络设计和训练策略。 首先,我们详细介绍了一些可进一步提高性能的调整,其中一些已在[25]中进行了经验验证。

4.1 网络调整

平均下采样。 当迁移学习的下游应用是密集的预测任务(例如检测或分段)时,保留空间信息就变得至关重要。 最近的ResNet实现通常将跨步卷积应用在3×3层而不是1×1层,以更好地响应保留此类信息[26,30]。 卷积层需要使用零填充策略处理特征图边界,这在转移到其他密集的预测任务时通常不是最佳选择。 而不是在过渡块(对空间分辨率进行下采样)处使用大步卷积,我们使用内核大小为3×3的平均池化层。

来自ResNet-D的调整。 我们还采用了[26]引入的两个简单而有效的ResNet修改:(1)将第一个7×7卷积层替换为三个连续的3×3卷积层,它们具有相同的接收域大小,并且计算成本与 原始设计。  (2)对于步长为2的过渡块,在1×1卷积层之前,将2×2平均池层添加到快捷连接中。

4.2 训练策略

大型小批量分布式培训。 在先前的工作[19,37]之后,我们并行使用8个服务器(总共64个GPU)训练模型。 我们的学习率根据余弦时间表进行调整[26,31]。 我们遵循通常的做法,即根据小批量的大小线性扩展初始学习率。 初始学习率由给出,其中B是最小批量大小,我们使用作为基本学习率。 这种预热策略在前5个时间段内应用,将学习率从0逐渐线性增加到余弦时间表的初始值[19,39]。 批处理归一化(BN)参数在每个块的最终BN操作中被初始化为零,这已被建议用于大型批处理训练[19]。

标签平滑:标签平滑首先用于改善Inception-V2的训练[53]。 回想一下,我们的网络的预测类概率q的交叉熵损失是针对地面真实性p计算的,如下所示:

其中K是类别总数,pi是第i类的地面真实概率,qi是网络对第i类的预测概率。 与标准图片分类一样,我们定义:,其中zi是我们网络的输出层产生的对数。 当提供的标签是类而不是类概率(硬标签)时,如果i等于基本事实类c,则pi = 1,否则=0。因此,在这种情况下:'。 在训练的最后阶段,对于往往很小,而将推至最佳值时,这可能会导致过拟合[26,53]。 标签平滑处理不是使用硬标签作为目标,而是使用平滑的地面真实概率:

 小常数。这可以减轻网络的过度自信和过度拟合。

自动增强:Auto-Augment [11]是一种通过变换图像增强训练数据的策略,在变换图像中自适应地学习变换。 引入了16种不同类型的图像抖动转换,从中,一种基于两个连续转换的24种不同组合(例如移位,旋转和色彩抖动)增强了数据。 可以使用相对参数(例如,    旋转角度),并且可能会跳过变换。 尝试各种候选增强策略的搜索将返回最佳的24种最佳组合。 然后,在训练期间随机选择这24个策略之一并将其应用于每个样本图像。 原始的Auto-Augment实现使用强化学习来搜索这些超参数,并将它们视为离散搜索空间中的分类值。 对于连续搜索空间,它会先搜索可能的值,然后再搜索最佳值。

混合训练:混合是另一种数据增强策略,可以从训练数据中生成随机图像对的加权组合[67]。给定两个图像及其地面真相标签:,合成训练示例生成为: 

其中,对于每个扩充示例,分别独立采样

大剪切尺寸。 图像分类研究通常会比较在共享相同作物大小的图像上运行的不同网络的性能。ResNet变体[23,26,29,60]通常使用224的固定训练作物大小,而Inception-Net系列[51 {53]使用299的训练剪切大小。最近,EfficientNet方法[55]已证明 增加输入图像大小以实现更深,更广泛的网络可能会更好地权衡精度与FLOPS。 为了公平比较,在将ResNeSt与ResNet变体进行比较时,我们使用的作物大小为224,在与其他方法进行比较时,我们使用的剪切大小为256。

正则化: 即使对于大型数据集,非常深的神经网络也倾向于过拟合[68]。 为了防止这种情况,辍学正则化在训练过程中(但不是在推理过程中)随机掩盖了一些神经元,以形成隐式网络集成[29、49、68]。 在最终的全连接层之前,将具有0.2丢失概率的丢失层应用于具有200层以上的网络。 我们还将DropBlock层应用于网络的最后两个阶段的卷积层。 作为丢包的结构化变体,DropBlock [18]随机掩盖了局部块区域,并且比丢包更有效地用于特定化正则化卷积层。

最后,我们还应用了重量衰减(即L2正则化),这还有助于稳定训练。 先前对大型小批量训练的研究表明,重量衰减仅应应用于卷积层和完全连接层的重量[19,26]。 我们不对其他任何网络参数进行权重衰减,包括批次归一化层中的偏置单位γ和β。

5、6中间的实验部分不再赘述

7、总结

这项工作提出了具有新颖的Split-Attention块的ResNeSt体系结构,该块可以普遍改进学习的特征表示,从而提高图像分类,对象检测,实例分割和语义分割的性能。 在后面的下游任务中,通过简单地将主干网络切换到我们的ResNeSt所产生的经验改进明显好于应用于标准主干(例如ResNet)的特定于任务的修改。 我们的Split-Attention块易于使用且计算效率高,因此应在视觉任务中广泛应用。

你可能感兴趣的:(阅读论文,神经网络,计算机视觉)