你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

基于paddlepaddle实现MobileNets_v1复现

2021/11/18 18:54:01

文章目录

  • 一、介绍
  • 二、网络特点
  • 二、单个block结构
  • 三、整体网络结构
  • 四、论文复现
    • 1、导入相关库
    • 2、建立基础的代码运行块
    • 3、按照单个block结构建立深度可分离卷积的block
    • 4、搭建整体的网络结构
    • 5、查看网络结构

一、介绍

MobileNets是Google针对手机等嵌入式设备提出的一种轻量级的深层神经网络;中点在于压缩模型,同时保证精度。

MobileNets是基于一个流线型的架构,它使用深度可分离的卷积来构建轻量级的深层神经网络。

二、网络特点


Depthwise Convolutional Filter


Pointwise Convolution

该网络相比于标准卷积网络,将层卷积和深度卷积分离,减少了计算量。

标准卷积的计算:DK.DK.M.N.DF.DF

可分离卷积的计算:DK.DK.M.DF.DF+M.N.DF.DF

计算比为: D K . D K . M . N . D F . D F D K . D K . M . D F . D F + M . N . D F . D F \frac{D_K.D_K.M.N.D_F.D_F}{D_K.D_K.M.D_F.D_F+M.N.D_F.D_F} DK.DK.M.DF.DF+M.N.DF.DFDK.DK.M.N.DF.DF= 1 N + 1 D 2 \frac{1}{N}+\frac{1}{D^2} N1+D21

注释: D K D_K DK为输入图像大小,M为输入图像层数, D K D_K DK为输出图像大小,N为输出图像层数

二、单个block结构


该block体现了深度分离卷积的特点。

三、整体网络结构

四、论文复现

1、导入相关库

import paddle
from paddle.nn import Conv2D, BatchNorm2D, AdaptiveAvgPool2D
import paddle.nn.functional as F

2、建立基础的代码运行块

class ConvBNLayer(paddle.nn.Layer):
    def __init__(self, in_channels, out_channels, kernel_size, stride, padding, num_group = 1):
        super(ConvBNLayer, self).__init__()
        self.conv = Conv2D(
            in_channels,
            out_channels,
            kernel_size,
            stride = stride,
            padding = padding,
            groups = num_group
            )
        self.bn = BatchNorm2D(out_channels)

    def forward(self, inputs):
        x = self.conv(inputs)
        x = self.bn(x)
        x = F.relu(x)

        return x

3、按照单个block结构建立深度可分离卷积的block

class DepthwiseSeperable(paddle.nn.Layer):
    def __init__(self, inchannels, outchannels, stride):
        super(DepthwiseSeperable, self).__init__()
        self.dcf = ConvBNLayer(
            in_channels = inchannels,
            out_channels = inchannels,
            kernel_size = 3,
            stride = stride,
            padding = 1,
            num_group = inchannels
            )
        self.pc = ConvBNLayer(
            in_channels=inchannels,
            out_channels=outchannels,
            kernel_size=1,
            stride=1,
            padding=0
            )

    def forward(self, inputs):
        x = self.dcf(inputs)
        x = self.pc(x)

        return x

4、搭建整体的网络结构

class MobileNet_v1(paddle.nn.Layer):
    def __init__(self):
        super(MobileNet_v1, self).__init__()
        self.dws = []
        self.conv0 = ConvBNLayer(
            in_channels=3,
            out_channels=32,
            kernel_size=3,
            stride=2,
            padding=1
            )
        layer0 = DepthwiseSeperable(
            inchannels=32,
            outchannels=64,
            stride=1
            )
        self.dws.append(layer0)
        layer1 = DepthwiseSeperable(
            inchannels=64,
            outchannels=128,
            stride=2
            )
        self.dws.append(layer1)
        layer2 = DepthwiseSeperable(
            inchannels=128,
            outchannels=128,
            stride=1
            )
        self.dws.append(layer2)
        layer3 = DepthwiseSeperable(
            inchannels=128,
            outchannels=256,
            stride=2
            )
        self.dws.append(layer3)
        layer4 = DepthwiseSeperable(
            inchannels=256,
            outchannels=256,
            stride=1
            )
        self.dws.append(layer4)
        layer5 = DepthwiseSeperable(
            inchannels=256,
            outchannels=512,
            stride=2
            )
        self.dws.append(layer5)
        for i in range(5):
            tmp = DepthwiseSeperable(
                inchannels=512,
                outchannels=512,
                stride=1
                )
            self.dws.append(tmp)
        layer6 = DepthwiseSeperable(
            inchannels=512,
            outchannels=1024,
            stride=2
            )
        self.dws.append(layer6)
        layer7 = DepthwiseSeperable(
            inchannels=1024,
            outchannels=1024,
            stride=1
            )
        self.dws.append(layer7)
        self.pooling = AdaptiveAvgPool2D(output_size=(1, 1))
    
    def forward(self, inputs):
        x = self.conv0(inputs)
        for dws in self.dws:
            x = dws(x)
        x = self.pooling(x)
        x = paddle.squeeze(x)

        return x

5、查看网络结构

model = MobileNet_v1()
paddle.summary(model, (1, 3, 224, 224))