一、ECA注意力机制介绍、
论文地址:ECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks | IEEE Conference Publication | IEEE Xplore
1. ECA的本质:
- ECA是一种通道注意力机制的实现形式,基于SE(Squeeze-and-Excitation)注意力机制的扩展。它的目的是增强卷积神经网络对各个通道的重要性判断。SE模块中的通道注意力通过全连接层来计算,而ECA则采用了更简单、更高效的方式。
2. 与SE模块的区别:
- SE模块中的全连接层被ECA简化了:
- SE模块中使用两个全连接(Fully Connected, FC)层来捕获通道之间的依赖关系,但ECA的作者认为使用全连接层来进行跨通道交互,可能会引入过多的参数,并且通道之间的依赖关系学习较为复杂且不必要。
- ECA简化了这个过程,认为权重学习的过程应该是直接且对应的。换句话说,ECA避免了过度复杂的全连接层,改为使用一种更加轻量的方式来进行通道间的交互。
3. ECA的关键设计:
ECA通过注意力机制避免了全连接层:它直接在全局平均池化后的特征图上使用
1×1
卷积核,这种操作避免了维度缩减并且有效地捕捉了通道之间的交互关系。这使得ECA能够通过少量的参数实现良好的效果。ECA的优势:相比于SE模块复杂的两层全连接操作,ECA只需要很少的参数就能够实现较好的效果。这意味着ECA更为轻量、参数更少,但性能不逊色于传统的注意力机制。
4. ECA的实现原理:
使用1D卷积:ECA使用1D卷积层来进行通道间信息的融合。具体来说,1D卷积通过一个可变的卷积核大小对通道之间的交互进行建模。这里卷积核的大小是根据通道数
c
来自适应变化的,确保每层的通道数较多时,能够进行足够的通道交互。卷积核大小的自适应:卷积核的大小由公式
k = log2(c) / γ + b
自适应调整,其中c
是通道数,γ
和b
是超参数。这个公式根据通道数自动调整卷积核的大小,确保卷积核既不会太大,也不会太小,从而保证ECA能够捕捉到合适的跨通道信息。5. 总结:
- ECA机制通过避免全连接层,并利用自适应1D卷积的方式,在降低模型复杂度的同时,实现了对通道注意力的高效计算。通过自适应调整卷积核的大小,ECA能够有效地捕捉跨通道的依赖关系,同时减少了冗余计算。
二、ECA注意力机制的应用
class ECA(nn.Module): def __init__(self, inc, outc, k_size=3): super(ECA, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.conv = nn.Conv1d(1, 1, kernel_size=k_size, padding=(k_size - 1) // 2, bias=False) self.sigmoid = nn.Sigmoid() def forward(self, x): # Global spatial information y = self.avg_pool(x) # [B, C, 1, 1] # Squeeze and Conv1D y = self.conv(y.squeeze(-1).permute(0, 2, 1)) # [B, 1, C] # Multi-scale information fusion and Sigmoid y = self.sigmoid(y).permute(0, 2, 1).unsqueeze(-1) # [B, C, 1, 1] # Scale the input feature map return x * y.expand_as(x)
1.在yolov5/models/common.py最下面添加代码
class ECA(nn.Module): def __init__(self, inc, outc, k_size=3): super(ECA, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.conv = nn.Conv1d(1, 1, kernel_size=k_size, padding=(k_size - 1) // 2, bias=False) self.sigmoid = nn.Sigmoid() def forward(self, x): # Global spatial information y = self.avg_pool(x) # [B, C, 1, 1] # Squeeze and Conv1D y = self.conv(y.squeeze(-1).permute(0, 2, 1)) # [B, 1, C] # Multi-scale information fusion and Sigmoid y = self.sigmoid(y).permute(0, 2, 1).unsqueeze(-1) # [B, C, 1, 1] # Scale the input feature map return x * y.expand_as(x)
2.在yolov5/models/yolo.py的parse_model添加代码
3.在yolov5/models/新建yolov5s_ECA.yaml文件
4.修改yolo.py调用
三、实现结果
结束