【Deep Learning 7】深度可分离卷积

🌞欢迎来到Pytorch的世界 
🌈博客主页:卿云阁

💌欢迎关注🎉点赞👍收藏⭐️留言📝

🌟本文由卿云阁原创!

📆首发时间:🌹2024年2月21日🌹

✉️希望可以和大家一起完成进阶之路!

🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!


目录

普通卷积

黑白图像中的卷积

填充

步长为3

计算公式

多维卷积

多个卷积核

卷积的三种模式

Pytorch卷积层原理和示例

nn.conv1d

nn.conv2d

深度可分离卷积


普通卷积

黑白图像中的卷积
填充

步长为3

计算公式

多维卷积

多个卷积核

卷积的三种模式

        深度学习框架中通常会实现三种不同的卷积模式,分别是 SAME、VALID、FULL。这三种模式的核心区别在于卷积核进行卷积操作的移动区域不同,进而导致输出的尺寸不同。我们以一个例子来看这三种模式的区别,输入图片的尺寸是 5×5 ,卷积核尺寸是 3×3 ,stride 取 1。

  • FULL 模式

FULL 模式下卷积核从与输入有一个点的相交的地方就开始卷积。如下图所示,蓝框的位置就是卷积核第一个卷积的地方,灰色部分是为了卷积能够正常进行的 padding(一般填 0)。因此 FULL 模式下卷积核移动区域最大,卷积后输出的尺寸也最大。

  • VALID 模式

VALID 模式与 FULL 模式相反,在整个卷积核与输入重叠的地方才开始卷积操作,因此不需要 padding,输出的尺寸也最小。

  • SAME 模式

SAME 模式是最常用的一种模式,SAME 的意思是卷积后输出的尺寸与输入尺寸保持一致(假定 stride 为 1)。通过将卷积核的中心与输入的第一个点进行对齐确定卷积核起始位置,然后补齐对应 padding 即可。如下图所示,可以看到卷积输出的尺寸与出入保持一致。

SAME 模式下当卷积核边长为偶数时,可以通过在其中一边增加多一行(列)padding,即不对称的 padding 实现输出尺寸与输入尺寸保持一致,如下图所示(卷积核尺寸为 2×2 )

以上三种模式区别在于卷积核进行卷积操作的移动区域不同,其实是确定了所需的 padding。各种模式 padding 计算如下:

def get_padding(inputs, ks, mode="SAME"):
    """
    Return padding list in different modes.
    params: inputs (input array)
    params: ks (kernel size) [p, q]
    return: padding list [n,m,j,k]
    """
    pad = None
    if mode == "FULL":
        pad = [ks[0] - 1, ks[1] - 1, ks[0] - 1, ks[1] - 1]
    elif mode == "VALID":
        pad = [0, 0, 0, 0]
    elif mode == "SAME":
        pad = [(ks[0] - 1) // 2, (ks[1] - 1) // 2,
               (ks[0] - 1) // 2, (ks[1] - 1) // 2]
        if ks[0] % 2 == 0:
            pad[2] += 1
        if ks[1] % 2 == 0:
            pad[3] += 1
    else:
        print("Invalid mode")
    return pad

     确定了输入尺寸、卷积核尺寸、padding 以及 stride,输出的尺寸就被确定下来,可以由以下公式计算。

Pytorch卷积层原理和示例
nn.conv1d

conv1d是一维卷积,它和conv2d的区别在于只对宽度进行卷积,对高度不卷积。

函数定义:

torch.nn.functional.conv1d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)

参数说明:

  • input:输入的Tensor数据,格式为(batch,channels,W),三维数组,第一维度是样本数量,第二维度是通道数或者记录数。三维度是宽度。
  • weight:卷积核权重,也就是卷积核本身。是一个三维数组,(out_channels, in_channels/groups, kW)。out_channels是卷积核输出层的神经元个数,也就是这层有多少个卷积核;in_channels是输入通道数;kW是卷积核的宽度。
  • bias:位移参数,可选项,一般也不用管。
  • stride:滑动窗口,默认为1,指每次卷积对原数据滑动1个单元格。
  • padding:是否对输入数据填充0。Padding可以将输入数据的区域改造成是卷积核大小的整数倍,这样对不满足卷积核大小的部分数据就不会忽略了。通过padding参数指定填充区域的高度和宽度,默认0(就是填充区域为0,不填充的意思)
  • dilation:卷积核之间的空格,默认1。
  • groups:将输入数据分组,通常不用管这个参数,没有太大意义。

代码:

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F

a=range(16)
x = Variable(torch.Tensor(a))
'''
a: range(0, 16)
x: tensor([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13.,
        14., 15.])
'''

x=x.view(1,1,16)
'''
x variable: tensor([[[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13., 14., 15.]]])
'''

b=torch.ones(3)
b[0]=0.1
b[1]=0.2
b[2]=0.3
weights = Variable(b)
weights=weights.view(1,1,3)
'''
weights: tensor([[[0.1000, 0.2000, 0.3000]]])
'''

y=F.conv1d(x, weights, padding=0)
'''
y: tensor([[[0.8000, 1.4000, 2.0000, 2.6000, 3.2000, 3.8000, 4.4000, 5.0000, 5.6000, 6.2000, 6.8000, 7.4000, 8.0000, 8.6000]]])
'''

nn.conv2d

函数定义

nn.Conv2d(self, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True))

参数:

  • in_channel: 输入数据的通道数,例RGB图片通道数为3;
  • out_channel: 输出数据的通道数,这个根据模型调整;
  • kennel_size: 卷积核大小,可以是int,或tuple;kennel_size=2,意味着卷积大小(2,2),                              kennel_size=(2,3),意味着卷积大小(2,3)即非正方形卷积
  • stride:步长,默认为1,与kennel_size类似,stride=2,意味着步长上下左右扫描皆为2,                         stride=(2,3),左右扫描步长为2,上下为3;
  •  padding: 零填充

代码

import torch
import torch.nn as nn
from torch.autograd import Variable

r = torch.randn(5, 8, 10, 5) # batch, channel , height , width
print(r.shape)

r2 = nn.Conv2d(8, 14, (3, 2), (2,1))  # in_channel, out_channel ,kennel_size,stride
print(r2)

r3 = r2(r)
print(r3.shape)
torch.Size([5, 8, 10, 5])
Conv2d(8, 14, kernel_size=(3, 2), stride=(2, 1))
torch.Size([5, 14, 4, 4])

深度可分离卷积

论文:《Xception: Deep Learning with Depthwise Separable Convolutions》
代码:API

逐深度卷积

不同于原始卷积,深度卷积是一个卷积核负责一个通道,独立地在每个通道上进行空间卷积。因此,深度卷积的输出特征图数量等于输入特征图数量,无法进行有效的维度扩展。

逐点卷积

由于一个特征图仅被一个滤波器卷积,无法有效的利用不同通道在相同空间位置上的特征信息,由此加入了逐点卷积。点卷积主要是要1×1卷积构成,负责将深度卷积的输出按通道投影到一个新的特征图上。

 重复多次1x1的卷积操作(如下图为128次),则最后便会得到一个深度的卷积结果。

代码实现:

class DeepWise_PointWise_Conv(nn.Module):
    def __init__(self, in_ch, out_ch):
        super(DeepWise_PointWise_Conv, self).__init__()

        # 深度卷积层(Depthwise Convolution)
        self.depth_conv = nn.Conv2d(
            in_channels=in_ch,          # 输入通道数
            out_channels=in_ch,         # 输出通道数,每个输入通道对应一个输出通道
            kernel_size=3,               # 卷积核大小,这里是3x3的深度卷积核
            stride=1,                    # 步长
            padding=1,                   # 填充
            groups=in_ch                 # 输入通道数等于组数,每个输入通道分配一个卷积核
        )

        # 点卷积层(Pointwise Convolution)
        self.point_conv = nn.Conv2d(
            in_channels=in_ch,          # 输入通道数,这里等于深度卷积层的输出通道数
            out_channels=out_ch,        # 输出通道数,决定了最终的特征图数量
            kernel_size=1,               # 卷积核大小为1x1,即点卷积
            stride=1,                    # 步长
            padding=0,                   # 无填充
            groups=1                     # 输入通道数等于组数,每个输入通道独享一个卷积核
        )

    def forward(self, input):
        # 深度卷积
        out = self.depth_conv(input)
        # 点卷积
        out = self.point_conv(out)
        return out

#将普通卷积替换成深度可分离卷积
nn.Conv2d(32,128,kernal_size=3,stride=1,padding=1)
 
DepthWiseConv(32,128)


 

  • 38
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
深度分离是一种在深度学习中常用的卷操作,它可以有效地减少模型的参数量和计算量,同时保持较好的性能。深度分离由两个步骤组成:深度和逐点卷深度(Depthwise Convolution)是指对输入的每个通道分别进行卷操作,使用一个卷核(filter)对每个通道进行独立的卷运算。这样可以减少参数量,因为每个通道只需要一个卷核。 逐点卷(Pointwise Convolution)是指使用1x1的卷核对深度的结果进行卷操作。逐点卷可以用来增加通道数或者减少通道数,通过调整卷核的数量来实现。 深度分离的优势在于可以显著减少参数量和计算量,从而提高模型的效率和速度。同时,它还可以提供较好的特征表示能力,使得模型在保持性能的同时具有更小的体。 以下是一些关于深度分离的参考文献: 1. Chollet, F. (2017). Xception: Deep learning with depthwise separable convolutions. In Proceedings of the IEEE conference on computer vision and pattern recognition (pp. 1251-1258). 2. Howard, A. G., Zhu, M., Chen, B., Kalenichenko, D., Wang, W., Weyand, T., ... & Adam, H. (2017). MobileNets: Efficient convolutional neural networks for mobile vision applications. arXiv preprint arXiv:1704.04861. 3. Sandler, M., Howard, A., Zhu, M., Zhmoginov, A., & Chen, L. C. (2018). MobileNetV2: Inverted residuals and linear bottlenecks. In Proceedings of the IEEE conference on computer vision and pattern recognition (pp. 4510-4520).
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卿云阁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值