【CVPR-20】ECANet

架构

输入F,[N,C,H,W]

经过GAP,[N,C,H,W]→[N,C,1,1]→[N,C,1]→[N,1,C]

经过卷积,[N,1,C]→[N,1,C]→[N,C,1]→[N,C,1,1]

经过逐元素相乘,[N,C,1,1]→[N,C,H,W]

image.png

实现

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import torch
from torch import nn

class ECANet(nn.Module):
def __init__(self,in_ch,gamma=2,b=1):
super(ECANet, self).__init__()
self.gap = nn.AdaptiveAvgPool2d(1)
self.in_ch = torch.tensor(in_ch,dtype=torch.float32)
self.k = int(abs(torch.log2(self.in_ch) + b) / gamma)
self.k = self.k if self.k % 2 else self.k + 1
self.conv = nn.Conv1d(in_channels=1,out_channels=1,
kernel_size=self.k,padding=(self.k - 1) // 2)
self.act = nn.Sigmoid()

def forward(self,x):
# [N, C, 1, 1]
out = self.gap(x)
# [N, 1, C]
out = out.squeeze(-1).permute(0,2,1)
out = self.conv(out)
out = out.transpose(1,2).unsqueeze(-1)
# [N, C, 1, 1]
out = self.act(out)
return out * x

if __name__ == '__main__':
x = torch.randn(2,64,32,32)
N,C,H,W = x.shape
model = ECANet(in_ch=C)
print((model(x)).shape)

FAQ

卷积计算出现问题

RuntimeError: Given groups=1, weight of size [1, 1, 3, 3], expected input[1, 2, 1, 64] to have 1 channels, but got 2 channels instead

输入维度为[N,1,C],不能使用2D卷积,以下是1D卷积和2D卷积的区别

nn.Conv1d 输入维度为[N,C,L],在输入的长度(L)维度上进行卷积,适用于三维输入,处理时间序列、音频信号。

nn.Conv2d 输入维度为[N,C,H,W],在输入的高度和宽度(H、W)维度上进行卷积,适用于四维输入,处理图像信息。