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

简介: 本文探讨了深度可分离卷积和空间可分离卷积,通过代码示例展示了它们在降低计算复杂性和提高效率方面的优势。

1. 摘要🎄

本文介绍了深度可分离卷积和空间可分离卷积的概念及其在计算复杂性和效率上的优势。深度可分离卷积通过通道内卷积和1x1卷积减少参数量,而空间可分离卷积将3x3卷积分解为3x1和1x3卷积以降低计算复杂性。代码示例展示了这两种卷积在实际网络结构中的应用,并通过比较计算量表明深度可分离卷积具有更高的效率。

2. 定义🎄

空间可分离卷积:空间可分离卷积是一种将传统卷积操作分解为两个更小操作的方法,通常分为逐行卷积和逐列卷积两个步骤。首先,使用一维卷积核对输入特征图的每一行进行卷积,生成中间特征图;然后,对中间特征图的每一列进行卷积,得到最终输出特征图。这种卷积方式可以减少计算量和参数数量,但并非所有的卷积核都适合进行空间上的分离,因此在深度学习中的应用不如深度可分离卷积广泛。 最常见的情况是将3x3的卷积核划分为3x1和1x3的卷积核,如下所示:
在这里插入图片描述
现在,我们不是用9次乘法进行一次卷积,而是进行两次卷积,每次3次乘法(总共6次),以达到相同的效果。 乘法较少,计算复杂性下降,网络运行速度更快。

import torch
import torch.nn as nn

class SpatiallySeparableConv2d(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):
        super(SpatiallySeparableConv2d, self).__init__()
        # 检查卷积核大小是否为奇数
        assert kernel_size % 2 == 1, "Kernel size must be odd for spatially separable convolution"

        self.depthwise_row_conv = nn.Conv2d(in_channels, in_channels, kernel_size=(kernel_size, 1),
                                            stride=(stride, 1), padding=((padding//2), 0), groups=in_channels)
        self.depthwise_col_conv = nn.Conv2d(in_channels, out_channels, kernel_size=(1, kernel_size),
                                            stride=(1, stride), padding=(0, (padding//2)), groups=in_channels)

    def forward(self, x):
        x = self.depthwise_row_conv(x)
        x = self.depthwise_col_conv(x)
        return x

# 示例使用
input_tensor = torch.randn(1, 3, 32, 32)  # (batch_size, channels, height, width)
conv = SpatiallySeparableConv2d(in_channels=3, out_channels=8, kernel_size=3, stride=1, padding=1)
output = conv(input_tensor)

print(output.shape)  # 输出的形状

深度可分离卷积:深度可分离卷积(Depthwise Separable Convolution)是一种高效的卷积操作,广泛应用于轻量级神经网络中,如MobileNet和Xception。它将标准卷积操作分解为两个较小的操作:深度卷积(Depthwise Convolution)和逐点卷积(Pointwise Convolution)。

  1. 深度卷积:在这一步中,每个输入通道独立地应用一个卷积核,这样只捕获空间特征而不混合通道信息。

  2. 逐点卷积:此步骤使用1x1的卷积核对深度卷积的输出进行卷积,目的是组合来自不同通道的特征。

这种分解方法显著减少了计算量和模型参数,同时保持了网络的性能。深度可分离卷积特别适合于计算资源有限的环境,如移动设备和嵌入式系统,深度可分离卷积步骤如下图所示。
在这里插入图片描述

import torch
import torch.nn as nn

class DepthwiseSeparableConv2d(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):
        super(DepthwiseSeparableConv2d, self).__init__()
        self.depthwise = nn.Conv2d(
            in_channels, in_channels, 
            kernel_size=kernel_size, 
            stride=stride, 
            padding=padding, 
            groups=in_channels
        )
        self.pointwise = nn.Conv2d(
            in_channels, out_channels, 
            kernel_size=1, 
            stride=1, 
            padding=0
        )

    def forward(self, x):
        x = self.depthwise(x)
        x = self.pointwise(x)
        return x

# 示例使用
input_tensor = torch.randn(1, 3, 32, 32)  # (batch_size, channels, height, width)
dconv = DepthwiseSeparableConv2d(in_channels=3, out_channels=8, kernel_size=3, stride=1, padding=1)
output = dconv(input_tensor)

print(output.shape)  # 输出的形状

3. 具体代码分析🎄

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

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

目录
相关文章
|
15天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的卷积神经网络(CNN): 从理论到实践
本文将深入浅出地介绍卷积神经网络(CNN)的工作原理,并带领读者通过一个简单的图像分类项目,实现从理论到代码的转变。我们将探索CNN如何识别和处理图像数据,并通过实例展示如何训练一个有效的CNN模型。无论你是深度学习领域的新手还是希望扩展你的技术栈,这篇文章都将为你提供宝贵的知识和技能。
50 7
|
12天前
|
机器学习/深度学习 自然语言处理 算法
深入理解深度学习中的卷积神经网络(CNN)
深入理解深度学习中的卷积神经网络(CNN)
15 1
|
15天前
|
机器学习/深度学习 人工智能 自然语言处理
探索深度学习中的卷积神经网络(CNN)及其在现代应用中的革新
探索深度学习中的卷积神经网络(CNN)及其在现代应用中的革新
|
27天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的卷积神经网络:从理论到实践
【10月更文挑战第35天】在人工智能的浪潮中,深度学习技术以其强大的数据处理能力成为科技界的宠儿。其中,卷积神经网络(CNN)作为深度学习的一个重要分支,在图像识别和视频分析等领域展现出了惊人的潜力。本文将深入浅出地介绍CNN的工作原理,并结合实际代码示例,带领读者从零开始构建一个简单的CNN模型,探索其在图像分类任务中的应用。通过本文,读者不仅能够理解CNN背后的数学原理,还能学会如何利用现代深度学习框架实现自己的CNN模型。
|
26天前
|
机器学习/深度学习 人工智能 算法框架/工具
深度学习中的卷积神经网络(CNN)及其在图像识别中的应用
【10月更文挑战第36天】探索卷积神经网络(CNN)的神秘面纱,揭示其在图像识别领域的威力。本文将带你了解CNN的核心概念,并通过实际代码示例,展示如何构建和训练一个简单的CNN模型。无论你是深度学习的初学者还是希望深化理解,这篇文章都将为你提供有价值的见解。
|
1月前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
79 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
27天前
|
机器学习/深度学习 人工智能 自动驾驶
深入解析深度学习中的卷积神经网络(CNN)
深入解析深度学习中的卷积神经网络(CNN)
41 0
|
1月前
|
机器学习/深度学习 人工智能 TensorFlow
深度学习中的卷积神经网络(CNN)及其在图像识别中的应用
【10月更文挑战第32天】本文将介绍深度学习中的一个重要分支——卷积神经网络(CNN),以及其在图像识别领域的应用。我们将通过一个简单的代码示例,展示如何使用Python和TensorFlow库构建一个基本的CNN模型,并对其进行训练和测试。
|
1月前
|
机器学习/深度学习 自然语言处理 TensorFlow
深度学习中的卷积神经网络(CNN)及其应用
【10月更文挑战第26天】在这篇文章中,我们将深入探讨卷积神经网络(CNN)的基本原理、结构和应用。CNN是深度学习领域的一个重要分支,广泛应用于图像识别、语音处理等领域。我们将通过代码示例和实际应用案例,帮助读者更好地理解CNN的概念和应用。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
深度学习与生活:如何利用卷积神经网络识别日常物品
【10月更文挑战第24天】在这篇文章中,我们将探索深度学习如何从理论走向实践,特别是卷积神经网络(CNN)在图像识别中的应用。通过一个简单的示例,我们将了解如何使用CNN来识别日常生活中的物体,如水果和家具。这不仅是对深度学习概念的一次直观体验,也是对技术如何融入日常生活的一次深刻反思。文章将引导读者思考技术背后的哲理,以及它如何影响我们的生活和思维方式。