深度可分离卷积

一、前言:为什么会出现深度可分离卷积?

在卷积神经网络(CNN)早期阶段(如 VGG、ResNet),我们通常使用标准卷积(Standard Convolution)

虽然这种操作能有效提取空间特征和通道特征,但计算量极大,尤其在移动端或嵌入式设备上难以部署。

核心矛盾:

  • 想提取更多特征 → 卷积核越多 → 参数量激增

  • 想减少计算量 → 卷积层变浅 → 表达能力下降

为解决这种"性能与效率"的矛盾,Google 在 MobileNet(2017) 中提出了 深度可分离卷积(Depthwise Separable Convolution) ,它将传统卷积分解为两步:
"空间卷积" + "通道融合",在保持精度的同时极大地降低了计算量。


二、标准卷积回顾

设输入特征图尺寸为:

输出特征图为:

卷积核大小为 ( )。

标准卷积的输出第 ( j ) 个通道计算为:

其中 ( )。

🧮 参数量与计算量:
  • 参数量:

  • 计算量(FLOPs):

显然,参数和计算量都与输入通道和输出通道呈乘积关系 ,当 ( )、( ) 较大时,计算代价极其高。


三、深度卷积(Depthwise Convolution)

3.1 数学定义

深度卷积的思想是:
"每个输入通道单独做卷积",不再跨通道混合。

即对每个输入通道 ( ) 仅使用一个卷积核 ():

其中 ( )。

这样,输出通道数 = 输入通道数。

3.2 参数量分析

相比标准卷积:参数减少

3.3 计算量

计算量随通道线性增长,而非二次增长。


四、逐点卷积(Pointwise Convolution)

4.1 数学定义

逐点卷积就是 1×1 卷积,它的作用是:

将前一步的深度卷积结果进行通道融合与线性变换

此时卷积核尺寸为 ( )。

4.2 参数量与计算量
  • 参数量:

  • 计算量:


五、深度可分离卷积整体结构(DW + PW)

深度可分离卷积将标准卷积分为两步:

  1. Depthwise Conv:独立提取每个通道的空间特征;

  2. Pointwise Conv:1×1卷积混合通道特征,生成新通道组合。

🧮 参数与计算量总和:

与标准卷积相比:

\\text{计算量比} = \\frac{F_{DSC}}{F_{standard}} = \\frac{1}{C_{out}} + \\frac{1}{K\^2}

例如当 ( K=3, ) 时:

仅需约 12% 的计算量!


六、MobileNet 中的应用

6.1 结构替换思想

MobileNet V1(2017)首次全面采用深度可分离卷积:

复制代码
Standard Conv → Depthwise Conv + Pointwise Conv

每一层替换后,网络结构示意:

复制代码
Input → DWConv → BN → ReLU → PWConv → BN → ReLU → Output
6.2 实际效果
模型 Top-1 精度 计算量(FLOPs) 参数量 相比ResNet加速
VGG-16 71.5% 15.3B 138M ×1
MobileNet V1 70.6% 0.57B 4.2M ≈27倍更快

深度可分离卷积虽然略损精度,但换来了数量级的效率提升,尤其适合移动端、嵌入式平台。


七、PyTorch 实现(两种方式)

7.1 使用 groups 参数实现 Depthwise
python 复制代码
import torch
import torch.nn as nn

# 深度卷积 + 逐点卷积 实现
class DepthwiseSeparableConv(nn.Module):
    def __init__(self, in_ch, out_ch, kernel_size=3, stride=1, padding=1):
        super().__init__()
        # 深度卷积: 每个输入通道单独卷积
        self.depthwise = nn.Conv2d(in_ch, in_ch, kernel_size, stride,
                                   padding, groups=in_ch, bias=False)
        # 逐点卷积: 1x1卷积融合通道
        self.pointwise = nn.Conv2d(in_ch, out_ch, 1, bias=False)
        self.bn = nn.BatchNorm2d(out_ch)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        x = self.depthwise(x)
        x = self.pointwise(x)
        x = self.bn(x)
        return self.relu(x)

# 示例
x = torch.randn(1, 32, 112, 112)
model = DepthwiseSeparableConv(32, 64)
print(model(x).shape)  # torch.Size([1, 64, 112, 112])
7.2 自定义实现(手写两步)
python 复制代码
class DW_PW_Custom(nn.Module):
    def __init__(self, in_ch, out_ch):
        super().__init__()
        self.dw = nn.Conv2d(in_ch, in_ch, 3, padding=1, groups=in_ch)
        self.pw = nn.Conv2d(in_ch, out_ch, 1)
    def forward(self, x):
        return self.pw(self.dw(x))

八、优缺点总结

优点 缺点
参数量、计算量显著下降(约 1/9) 减少跨通道特征交互,特征表达能力下降
支持高并行性,适合移动端部署 不适合通道间关系复杂的任务(如检测)
可与BN/激活轻松组合 单独使用时精度下降明显

结论:深度可分离卷积是一种"效率优先"的设计,特别适合轻量化模型(MobileNet、EfficientNet、ShuffleNet 等)。


九、适用与不适用场景

适用:

  • 移动端/实时推理(如手机端检测、人脸识别)

  • 参数量受限模型

  • 部署在嵌入式设备上(如 Jetson、Raspberry Pi)

不适用:

相关推荐
DKunYu4 小时前
2.2softmax回归
pytorch·python·深度学习·1024程序员节
材料科学研究4 小时前
量子计算与AI融合:材料科学新突破
人工智能·量子计算·dft·第一性原理
w0000064 小时前
YOLOv4
人工智能·计算机视觉·目标跟踪
2401_841495645 小时前
【机器学习】k近邻法
人工智能·python·机器学习·分类··knn·k近邻算法
lisw055 小时前
对遗传学进行机器学习的现状与展望!
大数据·人工智能·机器学习
开心-开心急了5 小时前
Kivy 乒乓游戏教程 基于Minconda或Anconda 运行
python·conda·1024程序员节·kivy
望获linux7 小时前
【Linux基础知识系列:第一百五十九篇】磁盘健康监测:smartctl
linux·前端·数据库·chrome·python·操作系统·软件
爬虫程序猿8 小时前
用 Python 给京东商品详情做“全身 CT”——可量产、可扩展的爬虫实战
开发语言·爬虫·python
诗句藏于尽头8 小时前
自动签到之实现掘金模拟签到
python·1024程序员节