美文网首页
初识mobilenet v1

初识mobilenet v1

作者: 寒夏凉秋 | 来源:发表于2020-01-14 16:32 被阅读0次

    Depthwise separable convolution

    深度级可分离卷积其实是一种可分解卷积操作(factorized convolutions).将卷积分解成两个更小的操作:

    • depthwise convolution
    • pointwise convolution

    在标准卷积中,其卷积核作用于所有输入通道上(input channel).如输出图片为:(6,6,3),原来卷积操作是:(4,4,3,5).4X4的卷积大小,3是卷积的通道数,5是卷积核的数量.其输出尺寸为\frac{6-4}{1}+1=3,其输出特征为(3,3,5),如图所示(同一个卷积核作用在所有通道上):

    image

    不同通道结果相加得到该卷积核的感受野的值.

    深度分离卷积(depthwise convolution),针对每个输入通道采用不同的卷积核,就是说一个卷积核对应一个输入通道.如图所示:


    image

    输入有3个通道,对应着有3个大小为(4,4,1) (4,4,1)(4,4,1)的深度卷积核,卷积结果共有3个大小为(3,3,1) (3,3,1)(3,3,1)

    最后,采用pointwise convolution.pointwise convolution其实就是普通的卷积,只不过其采用1x1的卷积核。1 X 1的卷积核作用 用于将不同通道的值相加.

    depthwise convolution先将通道(深度)分别进行卷积操作,再用pointwise convolution(1X1的卷积)进行通道间的卷积感受野值相加 最终结果与标准卷积类似.

    官方示意图如下所示:


    image

    计算量估计

    假设输入特征图大小为:D_{f} * D_{f}*M,而输出特征图大小为:D_{f} * D_{f} * N
    假设特征图的width与height,与输出图大小一样,两者差别在于通道.

    标准卷积

    对于标准卷积(D_{k} * D_{k}):

    每个卷积核的乘积计算量:D_{K} * D_{K}

    单个通道输出特征图边长所需的乘积计算量:D_{F} * D_{F} * D_{K} *D_{K}

    单个卷积核跨通道值相乘:D_{F} * D_{F} * D_{K} * D_{K} * M

    N个卷积:D_{F} * D_{F} * D_{K} * D_{K} * M * N

    depthwise convolution

    对于每一个通道,都有一个卷积,所以其计算量为:D_{K} * D_{K} *D_{F} * D_{K} * M

    pointwise convolution

    1*1卷积,其计算量为:
    M * N * D_{F} * D_{F}

    最后比较depthwise separable convolution和标准卷积如下:
    \frac{M * N * D_{F} * D_{F} + D_{K} * D_{K} *D_{F} * D_{K} * M}{D_{F} * D_{F} * D_{K} * D_{K} * M * N} = \frac{1}{N} + \frac{1}{D_{K}^{2}}

    一般情况下 N 比较大,那么如果采用3x3卷积核的话,depthwise separable convolution相较标准卷积可以降低大约9倍的计算量。其实,后面会有对比,参数量也会减少很多。

    mobilenet v1 结构

    基础结构如图:

    image

    原始的mobilenet v1 用于imagenet分类任务中,整个网络有28层.

    image

    mobilenet 超参数

    • width multiplier
    • resolution multiplier

    width multiplier主要按照比例减少通道数:
    其记为\alpha,取值范围从(0,1]
    总计算量变为:
    DK · DK · αM · DF · DF + αM · αN · DF · DF

    分辨率因子用来控制输入的分辨率,记为ρ:

    DK · DK · αM · ρDF · ρDF + αM · αN · ρDF · ρDF

    pytorch实现:

    在torch.nn.Conv2d中,group参数用来控制是否对输入的每个通道单独设置卷积:

    • At groups=1, all inputs are convolved to all outputs.(groups=1的时候,为标准卷积)
    • At groups=2, the operation becomes equivalent to having two conv layers side by side, each seeing half the input channels, and producing half the output channels, and both subsequently concatenated.(=2时,用两个卷积核,一个卷积核看一半,最后concat)
    • At groups= in_channels, each input channel is convolved with its own set of filters.(每个通道放一个卷积核,这就是我们要的depthwise convolution)

    所以,论文中的mobilenet基础结构为:

    def conv_dw(inp, oup, stride):
                return nn.Sequential(
                    nn.Conv2d(inp, inp, 3, stride, 1, groups=inp, bias=False),
                    nn.BatchNorm2d(inp),
                    nn.ReLU(inplace=True),
        
                    nn.Conv2d(inp, oup, 1, 1, 0, bias=False),
                    nn.BatchNorm2d(oup),
                    nn.ReLU(inplace=True),
                )
    
    

    整个mobilenet v1的论文结构代码为:

    class MobileNet(nn.Module):
        def __init__(self):
            super(MobileNet, self).__init__()
    
            def conv_bn(inp, oup, stride):
                return nn.Sequential(
                    nn.Conv2d(inp, oup, 3, stride, 1, bias=False),
                    nn.BatchNorm2d(oup),
                    nn.ReLU(inplace=True)
                )
    
            def conv_dw(inp, oup, stride):
                return nn.Sequential(
                    nn.Conv2d(inp, inp, 3, stride, 1, groups=inp, bias=False),
                    nn.BatchNorm2d(inp),
                    nn.ReLU(inplace=True),
        
                    nn.Conv2d(inp, oup, 1, 1, 0, bias=False),
                    nn.BatchNorm2d(oup),
                    nn.ReLU(inplace=True),
                )
    
            self.model = nn.Sequential(
                conv_bn(  3,  32, 2), 
                conv_dw( 32,  64, 1),
                conv_dw( 64, 128, 2),
                conv_dw(128, 128, 1),
                conv_dw(128, 256, 2),
                conv_dw(256, 256, 1),
                conv_dw(256, 512, 2),
                conv_dw(512, 512, 1),
                conv_dw(512, 512, 1),
                conv_dw(512, 512, 1),
                conv_dw(512, 512, 1),
                conv_dw(512, 512, 1),
                conv_dw(512, 1024, 2),
                conv_dw(1024, 1024, 1),
                nn.AvgPool2d(7),
            )
            self.fc = nn.Linear(1024, 1000)
    
        def forward(self, x):
            x = self.model(x)
            x = x.view(-1, 1024)
            x = self.fc(x)
            return x
    

    代码出自:https://github.com/marvis/pytorch-mobilenet.git

    相关文章

      网友评论

          本文标题:初识mobilenet v1

          本文链接:https://www.haomeiwen.com/subject/pysaactx.html