10 | 卷积(下):如何用卷积为计算机“开天眼”?
深度可分离卷积(Depthwise Separable Convolution)
- 深入了解
- 翻译
- 解释
- 总结
深度可分离卷积和空洞卷积是两种特殊的卷积操作,适用于轻量化模型设计和图像分割任务。深度可分离卷积通过分别进行深度卷积和逐点卷积,大幅减少计算量,适用于资源受限的移动终端等场景。在PyTorch中实现深度可分离卷积需要控制输入特征图与输出特征图的分组情况。空洞卷积则能够在不缩小特征图的情况下获得更大的感受野,适用于图像分割任务。感受野是指在原始图像中反应的区域,而空洞卷积的计算方式是通过扩张率来实现。建议在轻量化模型设计中考虑使用深度可分离卷积,而在图像分割项目中考虑使用空洞卷积。总体而言,本文介绍了PyTorch中卷积操作的重要参数,并提供了实际操作的练习。
《PyTorch 深度学习实战》,新⼈⾸单¥59
全部留言(20)
- 最新
- 精选
- IUniversex=torch.rand((3,128,128)).unsqueeze(0) print(x.shape) in_channel_DW=x.shape[1] out_channel_DW=x.shape[1] kernel_size=3 DW=nn.Conv2d(in_channel_DW,out_channel_DW,kernel_size,groups=in_channel_DW) in_channels_PW=out_channel_DW out_channels_PW=10 PW=nn.Conv2d(in_channels_PW,out_channels_PW,1) output=PW(DW(x)) print(output.shape)
作者回复: 你好,IUniverse。感谢你的留言。正确👍🏻👍🏻👍🏻,^^。
2021-11-0125 - sonald我觉得没有解释清楚“它最大的优点就是不需要缩小特征图,也可以获得更大的感受野。”,感受野是增大了,特征图没缩小吗?
作者回复: 你好,sonald,感谢你的留言。 是的,特征图没有缩小。
2022-02-2523 - 黑暗骑士老师好,请问为什么in_channel_DW=x.shape[1],x.shape[0]才是通道啊?
作者回复: hello,感谢你的留言。 你看这段代码, # 生成一个三通道的5x5特征图 x = torch.rand((3, 5, 5)).unsqueeze(0) print(x.shape) # 输出:torch.Size([1, 3, 5, 5]) 后面还有个unsqueeze(0),x的第0位是1,也就是batch_size
2022-02-2222 - 醒狮老师,我另外有一个问题没想明白,就是这个“groups”到底是怎么一回事?groups的定义是需要out和in_channels都能整除groups吗?我的理解是把输入和输出的通道除groups之后进行配对,各自组成小的基本卷积(比如除完之后又2组in,就将这两组in当做两个通道,让后out处完之后有3组,就当做一个卷积核的3个通道,再进行基本卷积)让后再把这groups这么多组得出的结果加和在一起组成新的单独的一个输出特征图,大概是这个意思吗?谢谢老师,您辛苦了!
作者回复: 抱歉回复迟了。 要求是必须整除。 不是in当做两组通道,是相当于两个组,每个组里有输入特征图的二分之一个特征。
2022-08-04归属地:北京1 - 硕掌柜老师您好,当我从原理上知道一个Conv2d的计算量是m * n * k * k * h' * w' 后,pytorch是否提供了函数可以查看,当给定一个batch数据时 / batchsize = 1时的计算量(理解为运算的次数)呢
作者回复: 你好,可以看看这个能不能帮到你。 https://github.com/1adrianb/pytorch-estimate-flops
2022-11-08归属地:北京 - John(易筋)import torch import torch.nn as nn # 生成一个三通道的128x128特征图 x = torch.rand((3,128,128)).unsqueeze(0) print(x.shape) # 请注意DW中,输入特征通道数与输出通道数是一样的 in_channels_dw = x.shape[1] out_channels_dw = x.shape[1] # 一般来讲DW卷积的kernel size为3 kernel_size = 3 stride = 1 # DW卷积groups参数与输入通道数一样 dw = nn.Conv2d(in_channels_dw, out_channels_dw, kernel_size, stride, groups=in_channels_dw) in_channels_pw = out_channels_dw out_channels_pw = 10 pw = nn.Conv2d(in_channels_pw, out_channels_pw, kernel_size_pw, stride) output = pw(dw(x)) print(output.shape) # Output torch.Size([1, 3, 128, 128]) torch.Size([1, 10, 126, 126])
作者回复: 👍🏻
2022-08-04归属地:北京 - 醒狮import torch import torch.nn as nn a = torch.rand(3,128,128) # 注:torch.tensor的分类是(batch_size,channels,w,h) a = torch.unsqueeze(a,0) print(a.shape) dw = nn.Conv2d(3,3,(3,3),stride=(3,3),groups=3) dw = dw(a) pw = nn.Conv2d(3,10,(1,1)) b = pw(dw) print(b) 老师好,请您检查一下,谢谢您!
作者回复: 👍🏻 ^^看起来没问题
2022-08-04归属地:北京 - Geek_622508请问,您这种动态图是用什么画的呢?
作者回复: hi,你好,我是直接引用文中的github的动图。具体怎么做我也没尝试过,不好意思啊。
2022-06-062 - 亚林import torch import torch.nn as nn # 生成一个三通道的128x128特征图 x = torch.rand((3, 128, 128)).unsqueeze(0) print(x.shape) # 请注意DW中,输入特征通道数与输出通道数是一样的 in_channels_dw = x.shape[1] out_channels_dw = x.shape[1] # 一般来讲DW卷积的kernel size为3 kernel_size = 3 stride = 1 # DW卷积groups参数与输入通道数一样 dw = nn.Conv2d(in_channels_dw, out_channels_dw, kernel_size, stride, groups=in_channels_dw) in_channels_pw = out_channels_dw out_channels_pw = 10 kernel_size_pw = 1 pw = nn.Conv2d(in_channels_pw, out_channels_pw, kernel_size_pw, stride) out = pw(dw(x)) print(out.shape)
作者回复: 👍🏻👍🏻👍🏻
2022-05-17 - zhangting请问下,感受野=输入特征图中蓝色加橘黄色部分,但是为啥不计算原图中右边和下边的白色格子?然后就是原图是6X6不是5X5
作者回复: 你好,zhangting,感谢留言。 当卷积核滑动的时候,就会计算右边和下边白色格子。 对是6x6,Sorry,这块我忘记改了。稍后我改一下。
2022-05-10