赞
踩
近年来的一些研究,已有证明通道注意机制在改善深度卷积神经网络(CNNs)的性能方面有着很大的潜力,现有方法大多致力于开发更加复杂的注意力模块,从而实现更好的性能,但是可以想到这也会不可避免的增加模型的复杂型。所以为了克服复杂性和性能之间的矛盾,本文提出了一种有效的通道注意力模块ECA模块,虽然只涉及少量的参数,但是却可以获得明显的性能增益。分析发现避免降维对于学习通道注意很重要,适当的跨通道交互可以在显著减低模型复杂度的同时保持性能,因此提出了该不降维的局部交叉通道交互策略,可以通过一维的卷积有效的实现。此外还提出了一种自适应选择一维卷积核大小的方法,以确定局部跨通道交互的覆盖率。
深度卷积神经网络(CNNs)在计算机视觉领域得到了广泛的应用,在图像分类、目标检测和语义分割等广泛的任务方面取得了很大的进展。从开创性的AlexNet开始,为了进一步提高深度卷积神经网络的性能,近年来,将通道注意力引入卷积块引起了人们的广泛关注,在性能改进方面显示出巨大潜力。其中一种方法是SENet ,它学习每个卷积块的通道注意力,为各种深度CNN架构带来明显的性能增益。如下图所示各种注意模块的比较。
在SENet中,一些研究通过捕获更复杂的通道依赖或结合额外的空间注意来改进SE块。虽然这些方法已经实现,但是却有精度越高,模型复杂度越高,计算负担也越重的问题。与前面提到的以更高的模型复杂度为代价来获得更好的性能的方法不同,本文关注的是能否以更有效的方式学习有效的信道注意力。
首先对于SENet中的通道注意模块。具体来说,在给定输入特征的情况下,SE块首先对每个通道单独使用全局平均池,然后使用两个具有非线性的完全连接(FC)层,然后使用一个Sigmoid函数来生成通道权值。两个FC层的设计是为了捕捉非线性的跨通道交互,其中包括降维来控制模型的复杂性。尽管这一策略被广泛应用于后续的通道注意模块,但研究表明,维度减少对通道注意预测有副作用,而且捕获所有通道之间的依赖是低效的,也是不必要的。
因此,本文提出了一种针对深度cnn的高效通道注意力(ECA)模块,该模块避免了降维,有效捕获了跨通道的交互。如上图所示,在不降低维度的渠道全局平均池化之后,ECA通过考虑每个渠道和它的邻居来捕获当地的跨渠道交互。实验证明该方法保证了效率和效果。需要注意的是,ECA可以通过大小为k的快速1D卷积来有效实现,其中内核大小k代表了局部跨通道交互的覆盖率,即有多少邻居参与一个通道的注意力预测。为了避免通过交叉验证对k进行手动调优,开发了一种方法来自适应地确定k,其中交互的覆盖率与通道维数成正比。相比较来说引入很少的额外参数和可忽略的计算,同时带来显著的性能增益。例如,对于具有24.37M参数和3.86 GFLOPs的ResNet-50, ECA-Net50的附加参数和计算分别是80和4.7e4 GFLOPs,与此同时,ECA-Net50在最高精确度方面比ResNet-50高出2.28%。
下表比较现有注意模块是否无信道降维(无DR)、跨通道交互、参数是否小于SE(用轻量表示)。从表中可以看出,ECA模块通过避免降低渠道维度来学习有效的渠道注意,同时以极其轻量级的方式获取跨渠道交互。
贡献总结如下:
(1)对SE块进行了剖析,并分别证明了避免降维和适当的跨通道交互对于学习有效的通道关注和高效的通道关注是重要的。
(2)提出了一种高效信道关注(ECA),为深度cnn网络开发一种极轻量的信道关注模块,该模块在增加模型复杂度的同时也带来了明显的改善。
(3)在ImageNet-1K和MS COCO上的实验结果表明,该方法具有比state-of-the-arts更低的模型复杂度,同时取得了非常有竞争力的性能。
文中首先回顾SENet中的通道注意模块SE块,然后通过分析降维效应和跨通道交互作用对SE块进行了证明。这促使提出了ECA模块。此外,还开发了一种自适应确定ECA参数的方法,并给出了如何将其应用于深度cnn的实例。
设一个卷积块的输出为X∈
R
W
×
H
×
C
R^{W×H×C}
RW×H×C,其中W、H、C分别为宽度、高度和通道尺寸(即过滤器数量)。据此可以计算出SE块中各通道的权重为:
为避免模型过于复杂,将w1和w2的大小分别设置为C×(C/r)和(C/r)×C。可以看到
f
W
1
,
W
2
f_{W1,W2}
fW1,W2涉及到通道注意块的所有参数。虽然Eq.(2)中的降维可以降低模型的复杂性,但它破坏了通道与其权值之间的直接对应关系。例如单一FC层使用所有通道的线性组合来预测每个通道的权重。而Eq.(2)首先将渠道特征投射到一个低维空间,然后再映射回来,使得渠道与其权值之间的对应关系是间接的。
如上所述,Eq.(2)中的降维使得通道与其权值之间的对应关系是间接的。为了验证其效果,作者将原始SE块与它的三个变体进行比较( SE-V ar1, SE-V ar2, SEV ar3),均不进行降维。从下表可以看出,无参数的SE-V ar1仍然优于原始网络,说明通道具有提高深度CNNs性能的能力。同时SE- v ar2独立学习各通道的权值,在参数较少的情况下略优于SE块。这可能意味着信道与其权值需要直接对应,而避免降维比考虑非线性通道相关性更重要。此外,SEV ar3在SE区块使用单一FC层的性能优于使用降维的两层FC层。以上结果清楚地表明,避免降维有助于学习有效的通道注意。因此设计了不降低通道维数的ECA模块。
给定不降维的聚合特征
y
∈
R
C
y∈R^C
y∈RC,则可以学习通过
其中W为C×C参数矩阵。特别地,对于se - var2和se - var3
其中SE-Var2的
W
v
a
r
2
W_{var2}
Wvar2为对角矩阵,涉及C个参数;SE-V的
W
v
a
r
3
W_{var3}
Wvar3是一个完整的矩阵,包含C×C参数。如Eq.(4)所示,关键的区别在于SE-Var3考虑了跨通道交互,而SEV ar2没有考虑,因此SE-Var3的性能更好。这一结果表明,跨渠道互动有利于渠道关注的学习。然而,SEVar3需要大量的参数,导致模型复杂度很高,特别是对于大信道数。所以SE-Var2和SE-Var3之间可能的折中是将
W
v
a
r
2
W_{var2}
Wvar2扩展为块对角矩阵,即:
将通道划分为G组,每个组包含C/G个通道,独立学习每组的信道注意,以局部方式捕捉跨信道交互。因此,它包含了
C
2
/
G
C^2/G
C2/G参数。从卷积的角度来看,SE-Var2、SEVar3和Eq.(5)可以分别看作是深度上的可分离卷积、FC层卷积和群卷积。这里,组卷积的SE块表示为:
但是过多的组卷积会增加内存访问成本,从而降低计算效率。此外,如表2所示,不同组的SE-GC与SE-Var2相比没有增益,说明它不是捕获本地跨通道交互的有效方案。原因可能是SE-GC完全抛弃了不同组之间的依赖关系。
在本文中,我们探索了另一种获取本地跨通道交互的方法,以保证效率和效果。具体地说,使用了一个波段矩阵
W
k
W_k
Wk去学习频道注意力和
W
k
W_k
Wk有
显然,
W
k
W_k
Wk包括k*C个参数小于公式5中的参数,并且也避免在不同群体之间完全独立。与表2 中相比这个方法(ECA-NS)优于上个公式5的SE-GC。对于本公式中
y
i
y_i
yi权重的计算只考虑了k个相邻之间的作用
Ω
i
k
Ω_i^k
Ωik表示
y
i
y_i
yik个相邻通道的集合,一种更有效的方法是让所有通道共享相同的学习参数,即:
这种策略可以通过核大小为k的快速一维卷积来实现,即:
式中,C1D表示一维卷积。这里的方法被称为effective channel attention (ECA)模块,它只涉及k个参数。如表2所示,k = 3的ECA模块在获得与SE-var3相似的结果的同时,具有更低的模型复杂度,通过适当地捕获本地跨通道交互,保证了效率和有效性。
由于ECA模块的目标是适当地捕获本地跨通道的交互,对于不同CNN架构中不同信道数的卷积块,可以手动调优交互的优化覆盖率。但是,通过交叉验证进行的手动调优将消耗大量计算资源。组卷积已经成功完成用于改进CNN架构,其中高维(低维)信道在组数固定的情况下涉及长(短)卷积。共享相似的权重,这是合理的覆盖互动,即kernel size k (1D卷积)与通道维C成正比,也就是说k与C之间可能存在一个映射关系:
最简单的映射是线性函数,但是线性函数所表征的关系太有限了。另一方面,众所周知通道维数C通常被设置为2的幂。因此引入了一种可能的解决方案,将线性函数扩展为非线性函数。
然后,给定信道维数C,可自适应确定内核大小k
其中|t|表示t的最接近奇数。在本文所有实验中分别将λ和b设为2和1。显然,通过映射梯度,高维通道具有较长的相互作用,而低维通道通过非线性映射具有较短的相互作用。
下图给出了pytorch的代码:
一般是在backbone各层之间加入ECA注意力模块,如下代码一Resnet50为例加入ECA注意力模块,只需要在init和forward里面直接插入即可。
def __init__(self, class_num=1000, backbone=resnet50, pretrained=True,param_path='resnet50-19c8e357.pth'):
self.backbone = backbone(pretrained=pretrained, param_path=param_path, remove=True, last_stride=1)
self.eca_layer=eca_layer(2048)
def forward(self, x):
x = self.backbone.conv1(x)
x = self.backbone.bn1(x)
x = self.backbone.relu(x)
x = self.backbone.maxpool(x)
x = self.backbone.layer1(x)
x = self.backbone.layer2(x)
x = self.backbone.layer3(x)
x = self.backbone.layer4(x)
x = self.eca_layer(x)
return x
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。