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