深度可分离卷积解析 - MobileNetV1

文章目录

  • 1 原理浅析
    • 1.1 背景简介
    • 1.2 标准卷积
    • 1.3 深度可分离卷积
      • 1.3.1 逐通道卷积
      • 1.3.2 逐点卷积
    • 1.4 综合比较
  • 2 代码实现 - pytorch

1 原理浅析

1.1 背景简介

  2017 年 4 月,谷歌提出 MobileNetV1 这一专注于移动设备的轻量级神经网络。MobileNetV1 运用深度可分离卷积(Depthwise separable convolution)构建轻量级网络,在准确率没有大幅下降的情况下,显著降低参数量和计算量,这在实际应用中意义非凡。MobileNetV1 论文相关信息如下:

论文:《MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications》
作者:Andrew G. Howard et al. (谷歌)
年份:2017 年

关于 MobileNetV1 的可用一句话概括,即 MobileNetV1 就是把 VGG 中的标准卷积层替换为深度可分离卷积。因此,本文将对深度可分离卷积进行详细介绍。

1.2 标准卷积

深度可分离卷积解析 - MobileNetV1_第1张图片

  标准卷积过程如上图所示。因为标准卷积并非本文重点,故而不在此次对其展开讲解。作为下文深度可分离卷积的对照组,按此方式设置标准卷积相关参数:输入为 5 x 5 x 3,卷积核组为 3 x 3 x 3 x 4,padding 为 1,stride 为 1,故而输出为 5 x 5 x 4。在此基础上,计算标准卷积的参数量和计算量:

  • 参数量(卷积核参数量):3 x 3 x 3 x 4 = 108;
  • 计算量(卷积操作计算量):3 x 3 x 3 x 3 x 3 x 4 = 972;

其中,关于参数量的计算可参考本人之前的博客 (神经网络参数量的计算),计算量的计算公式则为计算量 = 卷积核W x 卷积核H x (图片W - 卷积核W + 1) x (图片H - 卷积核H + 1) x 输入通道数 x 输出通道数

1.3 深度可分离卷积

深度可分离卷积解析 - MobileNetV1_第2张图片

  深度可分离卷积可分为逐通道卷积(Depthwise Convolution)和逐点卷积(Pointwise Convolution)两个过程,如上图所示。下面将对这两个过程展开详细的讲解。

1.3.1 逐通道卷积

深度可分离卷积解析 - MobileNetV1_第3张图片

  逐通道卷积的过程如上图所示,一个卷积核作用于一个通道,因此有卷积核通道数 = 输入通道数 = 输出通道数。此外,也可借助分组卷积进行理解,即逐通道卷积可看作是一个组数为输入通道数的标准卷积,通过设置nn.Conv2d()函数中 groups 参数为输入通道数加以实现。对比标准卷积设置相关参数:输入为 5 x 5 x 3,卷积核组为 3 x 3 x 3,padding 为 1,stride 为 1,故而输出为 5 x 5 x 3。在此基础上,计算其参数量和计算量:

  • 参数量:3 x 3 x 3 = 27;
  • 计算量:3 x 3 x 3 x 3 x 3 = 243;

1.3.2 逐点卷积

深度可分离卷积解析 - MobileNetV1_第4张图片

  逐点卷积的过程如上图所示,其可被看作是标准卷积的特殊形式,即卷积核尺寸变为 1 x 1 的标准卷积。同样对逐点卷积相关参数进行设置:输入为 5 x 5 x 3,卷积核组为 1 x 1 x 3 x 4,padding 为 0,stride 为 1,故而输出为 5 x 5 x 4。在此基础上,计算其参数量和计算量:

  • 参数量:1 x 1 x 3 x 4 = 12;
  • 计算量:1 x 1 x 5 x 5 x 3 x 4 = 300;

  需要注意的是,为保证在比较标准卷积和深度可分离卷积时的一致性,即保证二者的输入和输出完全一致,标准卷积、逐通道卷积核逐点卷积的padding被设置为 1、1 和 0。

1.4 综合比较

  为直观展示标准卷积与深度可分离卷积在参数量核计算量上的差距,将前文所得结果汇总至下表:

结果对比
卷积操作 参数量 计算量
标准卷积 108 972
深度可分离卷积 逐通道卷积 27 243
逐点卷积 12 300
合计 39 543
由上表可知,在参数量和计算量方面,深度可分离卷积优势巨大。

2 代码实现 - pytorch

# _*_coding:utf-8_*_
import torch
import torch.nn as nn


class DSC(nn.Module):
    def __init__(self, in_channel, out_channel):
        super(DSC, self).__init__()
        self.dsc_module = nn.Sequential(
            nn.Conv2d(in_channel, in_channel, kernel_size=3, padding=1, groups=in_channel),
            nn.Conv2d(in_channel, out_channel, kernel_size=1)
        )

    def forward(self, x):
        return self.dsc_module(x)


if __name__ == "__main__":
    inputs = torch.rand((8, 3, 5, 5))
    dsc = DSC(3, 4)
    outputs = dsc(inputs)
    # outputs: (B=8, C=4, H=5, W=5)
    print("Outputs shape: ", outputs.size())

【参考】

  1. B 站视频讲解;
  2. 视频对应笔记;
  3. 深度可分离卷积pytorch实现;

你可能感兴趣的:(分割与抠图,深度可分离卷积,MobileNet,v1)