卷积层常用的方法与适用范围与深度可分离卷积详解
1. 标准卷积(Standard Convolution)
方法:
-
使用固定的卷积核(滤波器)在输入特征图上滑动,提取局部特征。
适用范围:
-
图像分类:如在 AlexNet、VGGNet 中,标准卷积用于逐步提取图像的局部特征。
-
通用特征提取:适用于大多数需要提取局部特征的任务。
2. 深度可分离卷积(Depthwise Separable Convolution)
方法:
-
将标准卷积分解为两个独立的操作:
-
深度卷积(Depthwise Convolution):对每个输入通道单独进行卷积。
-
逐点卷积(Pointwise Convolution):使用 1×1 卷积核对深度卷积的输出进行组合。
-
-
减少了计算量和参数数量。
适用范围:
-
轻量级模型:如 MobileNet 和 EfficientNet,适用于移动设备和资源受限的环境。
-
实时应用:如实时视频处理、移动设备上的图像识别。
3. 扩张卷积(Dilated Convolution)
方法:
-
在卷积核中引入扩张率(Dilation Rate),扩大了卷积核的感受野,而不需要增加额外的参数。
适用范围:
-
语义分割:如在 DeepLab 中,扩张卷积用于扩大感受野,捕捉更多上下文信息。
-
图像生成:如在生成对抗网络(GAN)中,用于生成更高质量的图像。
4. 转置卷积(Transposed Convolution)
方法:
-
用于上采样(Upsampling),通过卷积操作增加特征图的分辨率。
-
常用于生成模型和语义分割任务中的上采样模块。
适用范围:
-
语义分割:如在 U-Net 和 DeepLab 中,用于将特征图上采样到原始图像大小。
-
生成模型:如在 GAN 的生成器中,用于生成高分辨率图像。
5. 分组卷积(Grouped Convolution)
方法:
-
将输入通道分成多个组,每个组独立进行卷积操作。
-
减少了计算量和参数数量,同时保持了特征的多样性。
适用范围:
-
轻量级模型:如 ResNeXt,通过分组卷积提高模型的效率。
-
多尺度特征提取:适用于需要处理多尺度特征的任务。
6. 混合精度卷积(Mixed Precision Convolution)
方法:
-
使用不同的数据精度(如 FP16 和 FP32)进行卷积操作,减少计算量和内存占用,同时保持模型性能。
适用范围:
-
大规模训练:在 GPU 和 TPU 上加速训练过程,同时减少内存占用。
-
推理优化:在部署时使用混合精度,提高推理速度。
7. 3D 卷积(3D Convolution)
方法:
-
在三维数据(如视频或体积数据)上进行卷积操作,捕捉时空特征。
适用范围:
-
视频分析:如在视频分类和目标检测中,捕捉时间维度的特征。
-
医学图像分析:如在 CT 和 MRI 数据中,处理三维体积数据。
8. 可变形卷积(Deformable Convolution)
方法:
-
在标准卷积的基础上引入可变形的采样点,能够捕捉不规则形状的特征。
-
通过学习偏移量来调整卷积核的采样位置。
适用范围:
-
目标检测:如在 Faster R-CNN 中,用于处理目标的不规则形状。
-
语义分割:在复杂场景中,能够更好地捕捉物体的边界。
总结
-
效率优先:使用深度可分离卷积或分组卷积。
-
扩大感受野:使用扩张卷积。
-
上采样:使用转置卷积。
-
处理视频或体积数据:使用 3D 卷积。
https://blog.csdn.net/zml194849/article/details/117021815
https://blog.csdn.net/m0_45267220/article/details/130291855
一些轻量级的网络,如mobilenet中,会有深度可分离卷积depthwise separable convolution,由depthwise(DW)和pointwise(PW)两个部分结合起来,用来提取特征feature map。相比常规的卷积操作,其参数数量和运算成本比较低。
深度可分离卷积主要分为两个过程,分别为逐通道卷积(Depthwise Convolution)和逐点卷积(Pointwise Convolution)。
逐通道卷积(Depthwise Convolution)
Depthwise Convolution的一个卷积核负责一个通道,一个通道只被一个卷积核卷积,这个过程产生的feature map通道数和输入的通道数完全一样。
一张5×5像素、三通道彩色输入图片(shape为5×5×3),Depthwise Convolution首先经过第一次卷积运算,DW完全是在二维平面内进行。卷积核的数量与上一层的通道数相同(通道和卷积核一一对应)。所以一个三通道的图像经过运算后生成了3个Feature map(如果有same padding则尺寸与输入层相同为5×5),如下图所示。(卷积核的shape即为:卷积核W x 卷积核H x 输入通道数)
其中一个Filter只包含一个大小为3×3的Kernel,卷积部分的参数个数计算如下(即为:卷积核Wx卷积核Hx输入通道数):
N_depthwise = 3 × 3 × 3 = 27
计算量为(即:卷积核W x 卷积核H x (图片W-卷积核W+1) x (图片H-卷积核H+1) x 输入通道数)
C_depthwise=3x3x(5-2)x(5-2)x3=243
Depthwise Convolution完成后的Feature map数量与输入层的通道数相同,无法扩展Feature map。而且这种运算对输入层的每个通道独立进行卷积运算,没有有效的利用不同通道在相同空间位置上的feature信息。因此需要Pointwise Convolution来将这些Feature map进行组合生成新的Feature map。
逐点卷积(Pointwise Convolution)
Pointwise Convolution的运算与常规卷积运算非常相似,它的卷积核的尺寸为 1×1×M,M为上一层的通道数。所以这里的卷积运算会将上一步的map在深度方向上进行加权组合,生成新的Feature map。有几个卷积核就有几个输出Feature map。(卷积核的shape即为:1 x 1 x 输入通道数 x 输出通道数)
由于采用的是1×1卷积的方式,此步中卷积涉及到的参数个数可以计算为(即为:1 x 1 x 输入通道数 x 输出通道数):
N_pointwise = 1 × 1 × 3 × 4 = 12
计算量(即为:1 x 1 x 特征层W x 特征层H x 输入通道数 x 输出通道数):
C_pointwise = 1 × 1 × 3 × 3 × 3 × 4 = 108
经过Pointwise Convolution之后,同样输出了4张Feature map,与常规卷积的输出维度相同。
四、参数对比
回顾一下,常规卷积的参数个数为:
N_std = 4 × 3 × 3 × 3 = 108
Separable Convolution的参数由两部分相加得到:
N_depthwise = 3 × 3 × 3 = 27
N_pointwise = 1 × 1 × 3 × 4 = 12
N_separable = N_depthwise + N_pointwise = 39
相同的输入,同样是得到4张Feature map,Separable Convolution的参数个数是常规卷积的约1/3。因此,在参数量相同的前提下,采用Separable Convolution的神经网络层数可以做的更深。
五、计算量对比
回顾一下,常规卷积的计算量为:
C_std =3*3*(5-2)*(5-2)*3*4=972
Separable Convolution的计算量由两部分相加得到:
C_depthwise=3x3x(5-2)x(5-2)x3=243
C_pointwise = 1 × 1 × 3 × 3 × 3 × 4 = 108
C_separable = C_depthwise + C_pointwise = 351
相同的输入,同样是得到4张Feature map,Separable Convolution的计算量是常规卷积的约1/3。因此,在计算量相同的情况下,Depthwise Separable Convolution可以将神经网络层数可以做的更深。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import torch from torch import nn from torchsummary import summary class depth_separable(nn.Module): def __init__(self, in_channels: int , out_channels: int ) -> None: super(depth_separable,self).__init__() self.depth_conv = nn.Conv2d( #和常规卷积不同就是设置了groups参数 in_channels, in_channels, kernel_size=3, stride=1, groups=in_channels, #groups设置为输入通道数,可以使逐通道卷积 ) self.point_conv = nn.Conv2d( #实现点卷积 in_channels, out_channels, kernel_size=1, ) def forward(self, x): return self.point_conv(self.depth_conv(x)) class mydepth_separable(nn.Module): def __init__(self) -> None: super(mydepth_separable,self).__init__() self.conv2d = depth_separable(3,8) self.relu = nn.ReLU() def forward(self, x): return self.relu(self.conv2d(x)) device = torch.device( "cuda" ) model=mydepth_separable().to(device) summary(model, (3, 5, 5)) #查看参数量(3,5,5)表示输入的尺寸是5×5×3 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了