可分离卷积及深度可分离卷积详解

分离卷积深度可分离卷积详解
战前战后可分离卷积
再来看⼀下nn.Conv2d():
输⼊为(N,C_in,H,W),输出为(N,C_out,H_out,W_out).
dilation空洞卷积来控制卷积膨胀间隔;
groups分组卷积来控制输⼊和输出的连接⽅式,in_channels和out_channels都要被groups整除。当groups设置不同时,可以区分出分组卷积或深度可分离卷积:
1. 当groups=1时,表⽰普通卷积层
2. 当groups<in_channels时,表⽰普通的分组卷积
3. 当groups=in_channels时,表⽰深度可分离卷积,每个通道都有⼀组⾃⼰的滤波器,⼤⼩为:
可分离卷积
可分离卷积包括空间可分离卷积(Spatially Separable Convolutions)和深度可分离卷积(depthwise separable convolution)。
假设feature的size为[channel, height , width]
空间也就是指:[height, width]这两维度组成的。
深度也就是指:channel这⼀维度。
1. 空间可分离卷积
通俗的说,空间可分离卷积就是将nxn的卷积分成1xn和nx1两步计算。
普通的3x3卷积在⼀个5x5的feature map上的计算⽅式如下图,每个位置需要9此惩罚,⼀共9个位置,整个操作要81次做乘法:
* 同样的状况在空间可分离卷积中的计算⽅式如下图,第⼀步先使⽤3x1的filter,所需计算量为:15x3=45;第⼆步使⽤1x3的filter,所需计算量为:9x3=27;总共需要72次乘法就可以得到最终结果,要⼩于普通卷积的81次乘法。
虽然空间可分离卷积可以节省计算成本,但⼀般情况下很少⽤到。所以我们后⾯主要以深度可分离卷积展开讲解。
2. 深度可分离卷积:
在Google的Xception以及MobileNet论⽂中都有描述。它的核⼼思想是将⼀个完整的卷积运算分解为两步进⾏,分别为Depthwise Convolution(逐深度卷积)与Pointwise Convolution(逐点1*1卷积)。
⾼效的神经⽹络主要通过:1. 减少参数数量;2. 量化参数,减少每个参数占⽤内存
⽬前的研究总结来看分为两个⽅向:
⼀是对训练好的复杂模型进⾏压缩得到⼩模型;
⼆是直接设计⼩模型并进⾏训练。(Mobile Net属于这类)
⾸先,我们⽐较下全卷积和深度可分离卷积:
常规卷积:假设输⼊层为⼀个⼤⼩为64×64像素、三通道彩⾊图⽚。经过⼀个包含4个Filter的卷积层,最终输出4个Feature Map,且尺⼨与输⼊层相同。我们可以计算出卷积层的参数数量是 4x3x3x3=108,参考下图:
逐深度卷积(滤波):将单个滤波器应⽤到每⼀个输⼊通道。还⽤上⾯那个例⼦,这⾥的Filter的数量与上⼀层的Depth相同。所以⼀个三通道的图像经过运算后⽣成了3个Feature map,参数数量是 3x3x3=27,参考下图:
* 逐点卷积(组合):⽤1*1的卷积组合不同深度卷积的输出,得到⼀组新的输出。卷积核的尺⼨为 1×1×M,M为上⼀层的depth。这⾥的卷积运算会将上⼀步的map在深度⽅向上进⾏加权组合,⽣成新的Feature map。有⼏个Filter就有⼏个Feature map,计算参数量为
1x1x3x4=12,参考下图:
综上,我们⽐对⼀下:常规卷积的参数个数为108;深度可分离卷积的参数个数为39,参数个数是常规卷积的约1/3。 下⾯我们⽤代码来验证⼀下!
代码测试
1. 普通卷积、深度可分离卷积对⽐:
as nn
import torch
from torchsummary import summary
class Conv_test(nn.Module):
def__init__(self, in_ch, out_ch, kernel_size, padding, groups):
super(Conv_test, self).__init__()
in_channels=in_ch,
out_channels=out_ch,
kernel_size=kernel_size,
stride=1,
padding=padding,
groups=groups,
bias=False
)
def forward(self,input):
out = v(input)
return out
#标准的卷积层,输⼊的是3x64x64,⽬标输出4个feature map
device = torch.device('cuda'if torch.cuda.is_available()else'cpu')
conv = Conv_test(3,4,3,1,1).to(device)
print(summary(conv,  input_size=(3,64,64)))
ses----------------------------------------------------------------
Layer (type)              Output Shape        Param #
================================================================            Conv2d-1[-1,4,64,64]108
================================================================ Total params:108
Trainable params:108
Non-trainable params:0
----------------------------------------------------------------
Input size (MB):0.05
Forward/backward pass size (MB):0.12
Params size (MB):0.00
Estimated Total Size (MB):0.17
----------------------------------------------------------------
None
# 逐深度卷积层,输⼊同上
device = torch.device('cuda'if torch.cuda.is_available()else'cpu')
conv = Conv_test(3,3,3, padding=1, groups=3).to(device)
print(summary(conv,  input_size=(3,64,64)))
----------------------------------------------------------------
Layer (type)              Output Shape        Param #
================================================================            Conv2d-1[-1,3,64,64]27
================================================================ Total params:27
Trainable params:27
Non-trainable params:0
----------------------------------------------------------------
Input size (MB):0.05
Forward/backward pass size (MB):0.09
Params size (MB):0.00
Estimated Total Size (MB):0.14
----------------------------------------------------------------
None
# 逐点卷积层,输⼊即逐深度卷积的输出⼤⼩,⽬标输出也是4个feature map
device = torch.device('cuda'if torch.cuda.is_available()else'cpu')
conv = Conv_test(3,4, kernel_size=1, padding=0, groups=1).to(device)
print(summary(conv,  input_size=(3,64,64)))
----------------------------------------------------------------
Layer (type)              Output Shape        Param #
================================================================
Conv2d-1[-1,4,64,64]12
================================================================
Total params:12
Trainable params:12
Non-trainable params:0
----------------------------------------------------------------
Input size (MB):0.05
Forward/backward pass size (MB):0.12
Params size (MB):0.00
Estimated Total Size (MB):0.17
----------------------------------------------------------------
None
2. 分组卷积、深度可分离卷积对⽐:
普通卷积:总参数量是 4x8x3x3=288。
分组卷积:假设输⼊层为⼀个⼤⼩为64×64像素的彩⾊图⽚、in_channels=4,out_channels=8,经过2组卷积层,最终输出8个Feature Map,我们可以计算出卷积层的参数数量是 2x8x3x3=144。
深度可分离卷积:逐深度卷积的卷积数量是 4x3x3=36, 逐点卷积卷积数量是 1x1x4x8=32,总参数量为68。
#普通卷积层
device = torch.device('cuda'if torch.cuda.is_available()else'cpu')
conv = Conv_test(4,8,3, padding=1, groups=1).to(device)
print(summary(conv,  input_size=(4,64,64)))
----------------------------------------------------------------
Layer (type)              Output Shape        Param #
================================================================
Conv2d-1[-1,8,64,64]288
================================================================
Total params:288
Trainable params:2887075t6
Non-trainable params:0
-
---------------------------------------------------------------
Input size (MB):0.06
Forward/backward pass size (MB):0.25
Params size (MB):0.00
Estimated Total Size (MB):0.31
----------------------------------------------------------------
None
# 分组卷积层,输⼊的是4x64x64,⽬标输出8个feature map
device = torch.device('cuda'if torch.cuda.is_available()else'cpu')
conv = Conv_test(4,8,3, padding=1, groups=2).to(device)
print(summary(conv,  input_size=(4,64,64)))
-
---------------------------------------------------------------
Layer (type)              Output Shape        Param #
================================================================            Conv2d-1[-1,8,64,64]144
================================================================ Total params:144
Trainable params:144
Non-trainable params:0
----------------------------------------------------------------
Input size (MB):0.06
Forward/backward pass size (MB):0.25
Params size (MB):0.00
Estimated Total Size (MB):0.31
----------------------------------------------------------------
None
# 逐深度卷积层,输⼊同上
device = torch.device('cuda'if torch.cuda.is_available()else'cpu')
conv = Conv_test(4,4,3, padding=1, groups=4).to(device)
print(summary(conv,  input_size=(4,64,64)))
----------------------------------------------------------------
Layer (type)              Output Shape        Param #
================================================================            Conv2d-1[-1,4,64,64]36
================================================================ Total params:36
网络炒汇
Trainable params:36
Non-trainable params:0
----------------------------------------------------------------
Input size (MB):0.06
Forward/backward pass size (MB):0.12
Params size (MB):0.00
Estimated Total Size (MB):0.19
----------------------------------------------------------------
None
# 逐点卷积层,输⼊即逐深度卷积的输出⼤⼩,⽬标输出也是8个feature map device = torch.device('cuda'if torch.cuda.is_available()else'cpu')
conv = Conv_test(4,8, kernel_size=1, padding=0, groups=1).to(device)
print(summary(conv,  input_size=(4,64,64)))
----------------------------------------------------------------
Layer (type)              Output Shape        Param #
================================================================            Conv2d-1[-1,8,64,64]32
================================================================ Total params:32
Trainable params:32
Non-trainable params:0
-
献身艺术 献身爱情
---------------------------------------------------------------
Input size (MB):0.06
Forward/backward pass size (MB):0.25
Params size (MB):0.00
Estimated Total Size (MB):0.31
----------------------------------------------------------------
None
3. MobileNet V1
企业管理创新论文

本文发布于:2024-09-21 19:00:46,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/293335.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:卷积   分离   深度   参数   模型   输出   数量
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议