ECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks---CVPR2020

ECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks---CVPR2020_第1张图片

这是CVPR2020的一篇文章。
地址:

如上图所示,SE实现通道注意力是使用两个全连接层,而ECA是需要一个的卷积。作者这么做的原因一方面是认为计算所有通道两两之间的注意力是没有必要的,另一方面是用两个全连接层确实引入了太多的参数和计算量。

因此作者进行了AvgPool之后,只是使用了一个感受野为k的一维卷积(相当于只计算与相邻k个通道的注意力),这样做就大大的减少的参数和计算量。(i.e.相当于SE是一个global的注意力,而ECA是一个local的注意力)

import numpy as np
import torch
from torch import nn
from torch.nn import init
from collections import OrderedDict
class ECAAttention(nn.Module):
    def __init__(self, kernel_size=3):
        super().__init__()
        self.gap=nn.AdaptiveAvgPool2d(1)
        self.conv=nn.Conv1d(1,1,kernel_size=kernel_size,padding=(kernel_size-1)//2)
        self.sigmoid=nn.Sigmoid()
    def init_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                init.kaiming_normal_(m.weight, mode='fan_out')
                if m.bias is not None:
                    init.constant_(m.bias, 0)
            elif isinstance(m, nn.BatchNorm2d):
                init.constant_(m.weight, 1)
                init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                init.normal_(m.weight, std=0.001)
                if m.bias is not None:
                    init.constant_(m.bias, 0)
    def forward(self, x):
        y=self.gap(x) #bs,c,1,1
        print(y.squeeze(-1).shape)
        y=y.squeeze(-1).permute(0,2,1) #bs,1,c
        print(y.shape)
        y=self.conv(y) #bs,1,c
        print(y.shape)
        y=self.sigmoid(y) #bs,1,c
        y=y.permute(0,2,1).unsqueeze(-1) #bs,c,1,1
        return x*y.expand_as(x)
if __name__ == '__main__':
    input=torch.randn(50,512,7,7)
    eca = ECAAttention(kernel_size=3)
    output=eca(input)
    print(output.shape)

    

你可能感兴趣的:(深度学习中的,Attention,机制总结与代码实现,深度学习,神经网络)