[深度之眼轻量化网络专题]1.MobileNets

1. 推导:MobileNets中的深度游可分离卷积与标准卷积的算力消耗之比?(input feature: FxFxC, kernel size: KxKxCxM, padding=same)

  • 普通卷积:
    在这里插入图片描述

    • 参数量:KxKxCxM

    • 运算量:由于是same padding,所以输出图尺寸是FxFxM

      FxFxMxKxKxC

  • 深度可分离卷积:
    在这里插入图片描述
    在这里插入图片描述

    • 参数量:(KxKxCx1) + (1x1xCxM) = (KxKxC) + (CxM)
    • 运算量:(FxFxCxKxKx1) + (FxFxMx1x1xC) = (FxFxCxKxK) + (FxFxMxC)
  • 所以两者参数量之比是:
    ( K ∗ K ∗ C ) + ( C ∗ M ) F ∗ F ∗ C ∗ M = 1 M + 1 F 2 \frac{(K*K*C) + (C*M)}{F*F*C*M}=\frac{1}{M}+\frac{1}{F^2} FFCM(KKC)+(CM)=M1+F21
    两者运算量之比是:
    ( F ∗ F ∗ C ∗ K ∗ K ) + ( M ∗ K ∗ K ∗ C ) F ∗ F ∗ M ∗ K ∗ K ∗ C = 1 M + 1 F 2 \frac{(F*F*C*K*K) + (M*K*K*C)}{F*F*M*K*K*C}=\frac{1}{M}+\frac{1}{F^2} FFMKKC(FFCKK)+(MKKC)=M1+F21

2. 代码实践:利用pytorch复现MobileNet 28层网络结构,模型参数设置同论文一致。

  • 首先定义深度卷积和点卷积

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PyUJ1N5J-1593353541499)(…/…/image/image-20200628104315398.png)]

    # define depthwise convlution using group conv
    class dw_conv(nn.Module):
        def __init__(self, in_dim, stride):
            super(dw_conv, self).__init__()
            self.conv = nn.Conv2d(in_channels=in_dim, out_channels=in_dim, kernel_size=3,
                                 stride=stride, groups=in_dim, bias=False)
            self.bn = nn.BatchNorm2d(in_dim)
            self.relu = nn.ReLU()
            
        def forward(self, x):
            out = self.conv(x)
            out = self.bn(out)
            out = self.relu(out)
            return out
    
    dw = dw_conv(16, 1)
    print(dw)
    
    # define point convolution
    class point_conv(nn.Module):
        def __init__(self, in_dim, out_dim):
            super(point_conv, self).__init__()
            self.conv = nn.Conv2d(in_channels=in_dim, out_channels=out_dim, kernel_size=1,
                                 stride=1, bias=False)
            self.bn = nn.BatchNorm2d(out_dim)
            self.relu = nn.ReLU()
            
        def forward(self, x):
            out = self.conv(x)
            out = self.bn(out)
            out = self.relu(out)
            return out
    
    point = point_conv(16, 32)
    print(point)
    
  • 然后根据网络模型搭建
    在这里插入图片描述

    # define mobilenetv1
    class MobileNetV1(nn.Module):
        def __init__(self, num_classes):
            super(MobileNetV1, self).__init__()
            self.num_classes = num_classes
            self.net = nn.Sequential(
                nn.Conv2d(3, 32, 3, 2),
                nn.ReLU(),
                dw_conv(32, 1),
                point_conv(32, 64),
                dw_conv(64, 2),
                point_conv(64, 128),
                dw_conv(128, 1),
                point_conv(128, 128),
                dw_conv(128, 2),
                point_conv(128, 256),
                dw_conv(256, 1),
                point_conv(256, 256),
                dw_conv(256, 2),
                point_conv(256, 512),
                dw_conv(512, 1),
                point_conv(512, 512),
                dw_conv(512, 1),
                point_conv(512, 512),
                dw_conv(512, 1),
                point_conv(512, 512),
                dw_conv(512, 1),
                point_conv(512, 512),
                dw_conv(512, 1),
                point_conv(512, 512),
                dw_conv(512, 2),
                point_conv(512, 1024),
                dw_conv(1024, 2),
                point_conv(1024, 1024),
                nn.AvgPool2d(7, 1)
                )
                self.fc1 = nn.Linear(1024, self.num_classes)
                
        def forward(self, x):
            out = self.net(x)
            out = out.view(-1, 1024)
            out = self.fc1(out)
            return out
        
        def init_weights(self):
            print('=> init weights from normal distribution')
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    # nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                    nn.init.normal_(m.weight, std=0.001)
                    # nn.init.constant_(m.bias, 0)
                elif isinstance(m, nn.BatchNorm2d):
                    nn.init.constant_(m.weight, 1)
                    nn.init.constant_(m.bias, 0)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值