【YOLOv8改进】LSKA(Large Separable Kernel Attention):大核分离卷积注意力模块 (论文笔记+引入代码)

简介: YOLO目标检测专栏介绍了大可分卷积核注意力模块LSKA,用于解决VAN中大卷积核效率问题。LSKA通过分解2D卷积为1D卷积降低计算复杂度和内存占用,且使模型关注形状而非纹理,提高鲁棒性。在多种任务和数据集上,LSKA表现优于ViTs和ConvNeXt,代码可在GitHub获取。基础原理包括LSKA的卷积核分解设计和计算效率优化。示例展示了LSKA模块的实现。更多详情及配置参见相关链接。

YOLO目标检测创新改进与实战案例专栏

专栏目录: YOLO有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例

专栏链接: YOLO基础解析+创新改进+实战案例

摘要

带有大卷积核注意力(LKA)模块的视觉注意网络(VAN)在一系列基于视觉的任务上表现出色,超越了视觉Transformer(ViTs)。然而,这些LKA模块中的深度卷积层随着卷积核尺寸的增加,会导致计算和内存占用的二次增长。为了解决这些问题并使在VAN的注意力模块中使用超大卷积核成为可能,我们提出了一种大可分卷积核注意力模块家族,称为LSKA。LSKA将深度卷积层的二维卷积核分解为串联的水平和垂直一维卷积核。与标准LKA设计不同,这种分解方法使得可以直接在注意力模块中使用带有大卷积核的深度卷积层,而不需要额外的模块。我们证明了在VAN中使用的LSKA模块可以在计算复杂度和内存占用更低的情况下,达到与标准LKA模块相当的性能。我们还发现,随着卷积核尺寸的增加,提出的LSKA设计使VAN更倾向于关注物体的形状而不是纹理。此外,我们还在五种受损版本的ImageNet数据集上,对VAN、ViTs以及最新的ConvNeXt中的LKA和LSKA模块进行了稳健性基准测试,这些数据集在以往的工作中很少被探索。我们广泛的实验结果表明,随着卷积核尺寸的增加,提出的VAN中的LSKA模块显著减少了计算复杂度和内存占用,同时在对象识别、对象检测、语义分割和稳健性测试上表现优于ViTs、ConvNeXt,并与VAN中的LKA模块性能相当。代码可在 https://github.com/StevenLauHKHK/Large-Separable-Kernel-Attention 获得。

基本原理

Large Separable Kernel Attention (LSKA)是一种新颖的注意力模块设计,旨在解决Visual Attention Networks (VAN)中使用大内核卷积时所面临的计算效率问题。LSKA通过将2D深度卷积层的卷积核分解为级联的水平和垂直1-D卷积核,从而实现了对大内核的直接使用,无需额外的模块。

概述

  1. 基本设计

    • LSKA将2D深度卷积层的卷积核分解为级联的水平和垂直1-D卷积核。
    • 这种分解设计使得LSKA可以直接使用深度卷积层的大内核,无需额外的模块或计算。
  2. 计算效率

    • LSKA的设计降低了参数数量的增长,从而降低了计算复杂度和内存占用。
    • 通过级联1-D卷积核的方式,LSKA在处理大内核时能够保持高效性能。
  3. 形状和纹理偏好

    • LSKA设计使得模块更加偏向于对象的形状而非纹理。
    • 这种偏好有助于提高模型对对象形状的学习能力,从而提高模型的鲁棒性和泛化能力。

总的来说,LSKA通过巧妙的卷积核分解设计,实现了对大内核的高效利用,同时保持了模型的性能和鲁棒性。其技术原理使得LSKA成为一种有潜力的注意力模块设计,可以在VAN等视觉任务中发挥重要作用。

yolov8 引入


# 定义一个名为LSKA的神经网络模块类,继承自nn.Module
class LSKA(nn.Module):
    def __init__(self, dim, k_size):
        # 初始化LSKA类,dim为通道数,k_size为卷积核大小
        super().__init__()

        self.k_size = k_size  # 保存卷积核大小

        # 根据k_size的不同值,初始化不同的卷积层
        if k_size == 7:
            # 水平和垂直方向上的第一层卷积
            self.conv0h = nn.Conv2d(dim, dim, kernel_size=(1, 3), stride=(1,1), padding=(0,(3-1)//2), groups=dim)
            self.conv0v = nn.Conv2d(dim, dim, kernel_size=(3, 1), stride=(1,1), padding=((3-1)//2,0), groups=dim)
            # 空间卷积层,带有膨胀参数
            self.conv_spatial_h = nn.Conv2d(dim, dim, kernel_size=(1, 3), stride=(1,1), padding=(0,2), groups=dim, dilation=2)
            self.conv_spatial_v = nn.Conv2d(dim, dim, kernel_size=(3, 1), stride=(1,1), padding=(2,0), groups=dim, dilation=2)
        elif k_size == 11:
            self.conv0h = nn.Conv2d(dim, dim, kernel_size=(1, 3), stride=(1,1), padding=(0,(3-1)//2), groups=dim)
            self.conv0v = nn.Conv2d(dim, dim, kernel_size=(3, 1), stride=(1,1), padding=((3-1)//2,0), groups=dim)
            self.conv_spatial_h = nn.Conv2d(dim, dim, kernel_size=(1, 5), stride=(1,1), padding=(0,4), groups=dim, dilation=2)
            self.conv_spatial_v = nn.Conv2d(dim, dim, kernel_size=(5, 1), stride=(1,1), padding=(4,0), groups=dim, dilation=2)
        elif k_size == 23:
            self.conv0h = nn.Conv2d(dim, dim, kernel_size=(1, 5), stride=(1,1), padding=(0,(5-1)//2), groups=dim)
            self.conv0v = nn.Conv2d(dim, dim, kernel_size=(5, 1), stride=(1,1), padding=((5-1)//2,0), groups=dim)
            self.conv_spatial_h = nn.Conv2d(dim, dim, kernel_size=(1, 7), stride=(1,1), padding=(0,9), groups=dim, dilation=3)
            self.conv_spatial_v = nn.Conv2d(dim, dim, kernel_size=(7, 1), stride=(1,1), padding=(9,0), groups=dim, dilation=3)
        elif k_size == 35:
            self.conv0h = nn.Conv2d(dim, dim, kernel_size=(1, 5), stride=(1,1), padding=(0,(5-1)//2), groups=dim)
            self.conv0v = nn.Conv2d(dim, dim, kernel_size=(5, 1), stride=(1,1), padding=((5-1)//2,0), groups=dim)
            self.conv_spatial_h = nn.Conv2d(dim, dim, kernel_size=(1, 11), stride=(1,1), padding=(0,15), groups=dim, dilation=3)
            self.conv_spatial_v = nn.Conv2d(dim, dim, kernel_size=(11, 1), stride=(1,1), padding=(15,0), groups=dim, dilation=3)
        elif k_size == 41:
            self.conv0h = nn.Conv2d(dim, dim, kernel_size=(1, 5), stride=(1,1), padding=(0,(5-1)//2), groups=dim)
            self.conv0v = nn.Conv2d(dim, dim, kernel_size=(5, 1), stride=(1,1), padding=((5-1)//2,0), groups=dim)
            self.conv_spatial_h = nn.Conv2d(dim, dim, kernel_size=(1, 13), stride=(1,1), padding=(0,18), groups=dim, dilation=3)
            self.conv_spatial_v = nn.Conv2d(dim, dim, kernel_size=(13, 1), stride=(1,1), padding=(18,0), groups=dim, dilation=3)
        elif k_size == 53:
            self.conv0h = nn.Conv2d(dim, dim, kernel_size=(1, 5), stride=(1,1), padding=(0,(5-1)//2), groups=dim)
            self.conv0v = nn.Conv2d(dim, dim, kernel_size=(5, 1), stride=(1,1), padding=((5-1)//2,0), groups=dim)
            self.conv_spatial_h = nn.Conv2d(dim, dim, kernel_size=(1, 17), stride=(1,1), padding=(0,24), groups=dim, dilation=3)
            self.conv_spatial_v = nn.Conv2d(dim, dim, kernel_size=(17, 1), stride=(1,1), padding=(24,0), groups=dim, dilation=3)

        # 通道间卷积,用于融合信息
        self.conv1 = nn.Conv2d(dim, dim, 1)

    # 定义前向传播函数
    def forward(self, x):
        u = x.clone()  # 克隆输入张量
        attn = self.conv0h(x)  # 通过第一个水平卷积层
        attn = self.conv0v(attn)  # 通过第一个垂直卷积层
        attn = self.conv_spatial_h(attn)  # 通过第二个水平卷积层
        attn = self.conv_spatial_v(attn)  # 通过第二个垂直卷积层
        attn = self.conv1(attn)  # 通过1x1卷积层融合信息
        return u * attn  # 输入与注意力权重相乘后返回

task与yaml配置

详见:https://blog.csdn.net/shangyanaf/article/details/139249202

相关文章
|
机器学习/深度学习 测试技术 计算机视觉
【YOLOv11改进 - 注意力机制】LSKA(Large Separable Kernel Attention):大核分离卷积注意力模块
【YOLOv11改进 - 注意力机制】LSKA(Large Separable Kernel Attention):大核分离卷积注意力模块
【YOLOv11改进 - 注意力机制】LSKA(Large Separable Kernel Attention):大核分离卷积注意力模块
|
9月前
|
机器学习/深度学习 计算机视觉
YOLOv11改进策略【注意力机制篇】| Large Separable Kernel Attention (LSKA) 大核可分离卷积注意力 二次创新C2PSA、C3k2
YOLOv11改进策略【注意力机制篇】| Large Separable Kernel Attention (LSKA) 大核可分离卷积注意力 二次创新C2PSA、C3k2
610 2
YOLOv11改进策略【注意力机制篇】| Large Separable Kernel Attention (LSKA) 大核可分离卷积注意力 二次创新C2PSA、C3k2
|
10月前
|
机器学习/深度学习 算法 计算机视觉
YOLOv11改进策略【SPPF】| SimSPPF,简化设计,提高计算效率
YOLOv11改进策略【SPPF】| SimSPPF,简化设计,提高计算效率
1932 8
YOLOv11改进策略【SPPF】| SimSPPF,简化设计,提高计算效率
|
9月前
|
机器学习/深度学习 数据可视化 网络架构
YOLOv11改进策略【SPPF】| NeuralPS-2022 Focal Modulation : 使用焦点调制模块优化空间金字塔池化SPPF
YOLOv11改进策略【SPPF】| NeuralPS-2022 Focal Modulation : 使用焦点调制模块优化空间金字塔池化SPPF
319 14
YOLOv11改进策略【SPPF】| NeuralPS-2022 Focal Modulation : 使用焦点调制模块优化空间金字塔池化SPPF
|
机器学习/深度学习 存储 测试技术
【YOLOv8改进】iRMB: 倒置残差移动块 (论文笔记+引入代码)
该专栏聚焦YOLO目标检测的创新改进与实战案例,提出了一种融合CNN和Transformer优点的轻量级模型——倒置残差移动块(iRMB)。iRMB旨在平衡参数、运算效率与性能,适用于资源有限的移动端。通过集成多头自注意力和卷积,iRMB在ImageNet-1K等基准上超越SOTA,同时在iPhone14上展现出比EdgeNeXt快2.8-4.0倍的速度。此外,iRMB设计简洁,适用于各种计算机视觉任务,展示出良好的泛化能力。代码示例展示了iRMB模块的实现细节。更多详细信息和配置可在相关链接中找到。
|
机器学习/深度学习 编解码 Java
YOLO11创新改进系列:卷积,主干 注意力,C3k2融合,检测头等创新机制(已更新100+)
《YOLO11目标检测创新改进与实战案例》专栏已更新100+篇文章,涵盖注意力机制、卷积优化、检测头创新、损失与IOU优化、轻量级网络设计等多方面内容。每周更新3-10篇,提供详细代码和实战案例,帮助您掌握最新研究和实用技巧。[专栏链接](https://blog.csdn.net/shangyanaf/category_12810477.html)
YOLO11创新改进系列:卷积,主干 注意力,C3k2融合,检测头等创新机制(已更新100+)
|
机器学习/深度学习 人工智能 文字识别
ultralytics YOLO11 全新发布!(原理介绍+代码详见+结构框图)
本文详细介绍YOLO11,包括其全新特性、代码实现及结构框图,并提供如何使用NEU-DET数据集进行训练的指南。YOLO11在前代基础上引入了新功能和改进,如C3k2、C2PSA模块和更轻量级的分类检测头,显著提升了模型的性能和灵活性。文中还对比了YOLO11与YOLOv8的区别,并展示了训练过程和结果的可视化
19437 0
|
并行计算 数据挖掘 PyTorch
【YOLOv8改进 - 特征融合】DySample :超轻量级且高效的动态上采样器
【YOLOv8改进 - 特征融合】DySample :超轻量级且高效的动态上采样器
【YOLOv8改进 - 特征融合】DySample :超轻量级且高效的动态上采样器
|
机器学习/深度学习 计算机视觉 异构计算
YOLOv8优改系列一:YOLOv8融合BiFPN网络,实现网络快速涨点
该专栏专注于YOLOv8的 Neck 部分改进,融合了 BiFPN 网络,大幅提升检测性能。BiFPN 通过高效的双向跨尺度连接和加权特征融合,解决了传统 FPN 的单向信息流限制。文章详细介绍了 BiFPN 的原理及其实现方法,并提供了核心代码修改指导。点击链接订阅专栏,每周定时更新,助您快速提升模型效果。推荐指数:⭐️⭐️⭐️⭐️,涨点指数:⭐️⭐️⭐️⭐️。
983 0
|
机器学习/深度学习 编解码 测试技术
【YOLOv8改进-SPPF】 Focal Modulation :使用焦点调制模块替代SPPF
YOLOv8专栏介绍了FocalNets,一种取代自注意力的新型模块,提升模型在图像分类、检测和分割任务中的性能。Focal Modulation包括局部聚焦、全局调制和多尺度处理,通过融合CNN和自注意力优点。代码展示了FocalModulation模块的实现。论文和代码已开源。在多个基准测试中,FocalNets超越了Swin等先进模型。