深度学习笔记(十二):普通卷积、深度可分离卷积、空间可分离卷积代码

定义

  • 空间可分离卷积:是因为它主要处理图像和卷积核(kernel)的空间维度:宽度和高度。空间可分离卷积简单地将卷积核划分为两个较小的卷积核。 最常见的情况是将3x3的卷积核划分为3x1和1x3的卷积 核,如下所示:在这里插入图片描述
    现在,我们不是用9次乘法进行一次卷积,而是进行两次卷积,每次3次乘法(总共6次),以达到相同的效果。 乘法较少,计算复杂性下降,网络运行速度更快。

  • 深度可分离卷积:对输入图像的每个通道分别设置一个卷积核,卷积出的结果通道数与原图保持一致,后使用point-wise 1*1卷积调成需要的通道数。在这里插入图片描述

具体代码分析

import torch.nn as nn
from Module.activation import act_layers

class ConvBNReLU(nn.Sequential):
    def __init__(self,i,o,k,s,p,dilation=(1,1),groups=1,bias=False,activation='ReLU'):
        super(ConvBNReLU, self).__init__()

        self.CBA = nn.Sequential(
            nn.Conv2d(i,o,kernel_size=k,stride=s,padding=p,dilation=dilation,groups=groups,bias=bias),
            nn.BatchNorm2d(o),
            act_layers(activation)
        )
    def forward(self, input):
        x = self.CBA(input)
        return x


class Param(nn.Module):
    def __init__(self,activation='ReLU'):
        super(Param, self).__init__()
        self.conv1 = nn.Sequential(
            nn.Conv2d(3, 24, kernel_size=3, stride=2, padding=1, bias=False),
            nn.BatchNorm2d(24),
            act_layers(activation)
        )
        # 普通卷积
        self.conv2 = nn.Sequential(
            nn.Conv2d(24, 24, kernel_size=3, stride=1, padding=1, bias=False),
            nn.BatchNorm2d(24),
            act_layers(activation)
        )
        # 深度可分离
        self.conv3 = nn.Sequential(
            self.depthwise_conv(24, 24, kernel_s=3, stride=1, padding=1),
            nn.Conv2d(24, 24, 1),
            nn.BatchNorm2d(24),
            act_layers(activation)
        )
        # 空间可分离
        self.D3x1_D1x3 = nn.Sequential(
            ConvBNReLU(24,24,(3,1),1,p=(1,0),dilation=(1,1),groups=1),
            ConvBNReLU(24,24,(1,3),1,p=(0,1),dilation=(1,1),groups=1)
        )

    @staticmethod
    def depthwise_conv(input_c: int,
                       output_c: int,
                       kernel_s: int,
                       stride: int = 1,
                       padding: int = 0,
                       bias: bool = False) -> nn.Conv2d:
        return nn.Conv2d(in_channels=input_c, out_channels=output_c, kernel_size=kernel_s,
                         stride=stride, padding=padding, bias=bias, groups=input_c)

    def forward(self, x):
        x = self.conv1(x)
        # 普通卷积 258.55M 5.93k
        x = self.conv2(x)
        # 深度可分离 69.57M 1.56K
        x = self.conv3(x)
        # 空间可分离 186.9M 4.25K
        x = self.D3x1_D1x3(x)

        return x

很明显深度可分离卷积参数量和计算复杂度都最小。

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ZZY_dl

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

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

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

打赏作者

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

抵扣说明:

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

余额充值