MobileNetV3:Searching for MobileNetV3

结合了 MobileNetv1的深度可分离卷积、MobileNetv2的 Inverted Residuals 和 Linear Bottleneck 以及 SE 模块,利用 NAS(神经结构搜索)来搜索网络的配置和参数

什么是MobileNetv3?

  • 结合了 MobileNetv1的深度可分离卷积、MobileNetv2 的 Inverted Residuals 和 Linear Bottleneck 以及 SE 模块,利用 NAS(神经结构搜索)来搜索网络的配置和参数

MobileNetv3的网络结构?

  • large和small的整体结构一致,区别就是基本单元MobileNetv3 block的个数以及内部参数上,主要是通道数目
  • bneck是网络的基本结构。SE代表是否使用通道注意力机制。NL代表激活函数的类型,包括HS(h-swish),RE(ReLU)。NBN 代表没有BN操作。 s 是stride的意思,网络使用卷积stride操作进行降采样,没有使用pooling操作

MobileNetv3 block的组成?

  • MobileNetv3 block在MobileNetv2的“倒残差”瓶颈( Inverted Residuals Bottlenecks) 基础上修改,引入SEBlock,显式地建模网络卷积特 征通道之间的相互依赖关系,来提高网络所产生表示的质量
  • SE结构会消耗一定的时间,所以在expansion layer的channel变为原来的 1/4
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
       class SeModule(nn.Module):
    def __init__(self, in_size, reduction=4):
    super(SeModule, self).__init__()
    self.se = nn.Sequential(
    nn.AdaptiveAvgPool2d(1),
    nn.Conv2d(in_size, in_size // reduction, kernel_size=1, stride=1, padding=0, bias=False),
    nn.BatchNorm2d(in_size // reduction),
    nn.ReLU(inplace=True),
    nn.Conv2d(in_size // reduction, in_size, kernel_size=1, stride=1, padding=0, bias=False),
    nn.BatchNorm2d(in_size),
    hsigmoid())

    def forward(self, x):
    return x * self.se(x)

mobileNetv3如何定义head结构?

  • 在MobileNetv2中,avg pooling之前存在一个1x1卷积,目的是提高特征图的维度,但是这带来计算量。MobileNetv3将1x1卷积放在avg pooling的后面,首先利用avg pooling将特征图大小由7x7降到了1x1,降到1x1后,然后再利用1x1提高维度,这样就减少了 7x7=49倍的计算量
  • 为了进一步的降低计算量,作者直接去掉了前面纺锤型卷积的3x3以及1x1卷积,进一步减少了计算量

mobileNetv3更换激活函数?

  • 使用ReLU6(x+3)/6来近似替代sigmoid,进行了速度优化
1
2
3
4
5
6
7
8
9
class hswish(nn.Module):
def forward(self, x):
out = x * F.relu6(x + 3, inplace=True) / 6
return out

class hsigmoid(nn.Module):
def forward(self, x):
out = F.relu6(x + 3, inplace=True) / 6
return out