本文参考https://github.com/fourierer/Learn_GhostNet_pytorch
SEModule的认识:(momenta-孙刚)
(1)$F_{tr}$:$X$到$U$的卷积过程 ,但是通道之间的关系并没有发生变化;
(2)$F_{sq}$:将每个通道做了一个$squeeze$操作(主要是池化操作),将每个通道表示成了一个标量,得到per channel的描述;
(3)$F_{ex}$:将per channel标量进行“激活”,可以理解为算出了per channel的$W$(权值),实际上这一步就是全连接;
(4)最后将per channel的$W$(权重)乘回到原来的feature map上得到加权后的channel,将channel 做了恰当的融合;
SE-Module 可以用于网络的任意阶段,且squeeze 操作保证了在网络的早期感受野就可以大到全图的范围。
code:
class SELayer(nn.Module):
def __init__(self, channel, reduction=4):
super(SELayer, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Sequential(
nn.Linear(channel, channel // reduction),
nn.ReLU(inplace=True),
nn.Linear(channel // reduction, channel), )
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)
y = torch.clamp(y, 0, 1)#限制y(权重)的取值在[0,1]之间
return x * y
depthwise convolution
def depthwise_conv(inp, oup, kernel_size=3, stride=1, relu=False):
return nn.Sequential(
nn.Conv2d(inp, oup, kernel_size, stride, kernel_size//2, groups=inp, bias=False),
nn.BatchNorm2d(o