-
问题的引入
传统的cnn中,各个通道的一般是相互独立的 ,就算有关系,也是全局或者部分感受野的关系(类比sppnet),那么其实在分类或者目标检测中,物体的中心点的权重和信息理所当然的应该比周边的信息多,比如人的脸比人的头的信息和细节更加的丰富,那么在cnn中如何体现了?
-
解决思路
不同的特征层是特征的体现,那么要体现脸和头的细节的差别,就要针对不同的特征层有不同的权重。
-
具体思路
分为两部分,Squeeze做的事情是把H*W*C压缩为1*1*C,相当于把H*W压缩成一维了,实际中一般是用global average pooling实现的。H*W压缩成一维后,相当于这一维参数获得了之前H*W全局的视野,感受野更广。
2. Excitation部分。得到Squeeze的1*1*C的表示后,加入一个FC全连接层,对每个通道的重要性进行预测,得到不同channel的重要性大小后再作用(softmax)到之前的feature map的对应channel上,直接相乘,再进行后续操作。
-
代码:
class SELayer(nn.Module):
def __init__(self, channel, reduction=16):
super(SELayer, self).__init__()
# 全局池化
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Sequential(
# 压缩维度
nn.Linear(channel, channel // reduction, bias=False),
nn.ReLU(inplace=True),
# 扩展维度
nn.Linear(channel // reduction, channel, bias=False),
# 得到各通道的权重
nn.Sigmoid()
)
def forward(self, x):
b, c, _, _ = x.size()
y = self.avg_pool(x).view(b, c)
y = self.fc(y).view(b, c, 1, 1)
return x * y.expand_as(x)