YOLOv8改进 | 主干网络| 可变形卷积网络C2f_DCN【CVPR2017】

news2024/11/23 15:49:34

💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡


专栏目录:《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有40+篇内容,内含各种Head检测头、损失函数Loss、Backbone、Neck、NMS等创新点改进


卷积神经网络(CNN)由于其构建模块中固定的几何结构,天生就局限于对几何变换的建模。为此,引入了两个新的模块来增强CNN的变换建模能力,即可变形卷积和可变形RoI池化。两者都是基于在模块的空间采样位置增加附加偏移量的思想,并从目标任务中学习这些偏移量,而不需要额外的监督。这些新模块可以很容易地替换现有CNNs中的普通对应模块,并且可以通过标准的反向传播轻松地进行端到端的训练,从而产生可变形卷积网络。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。

专栏地址YOLOv8改进——更新各种有效涨点方法——点击即可跳转

目录

1.原理

2. 将C2f_DCN添加到YOLOv8中

2.1 Deformable Convolutional Networks代码实现

2.2 更改init.py文件

2.3 添加yaml文件

2.4 在task.py中进行注册

2.5 执行程序

3. 完整代码分享

4. GFLOPs

5. 进阶

6. 总结


1.原理

论文地址:Deformable Convolutional Networks——点击即可跳转

官方代码:官方代码仓库——点击即可跳转

可变形卷积网络 (DCN) 旨在通过引入可变形卷积和可变形 RoI(感兴趣区域)池化模块来增强卷积神经网络 (CNN) 的建模能力。这些模块旨在解决 CNN 在处理几何变换方面的局限性。以下是 DCN 主要原理的概述:

可变形卷积网络的关键原理:

几何变换

  • 标准 CNN 难以处理缩放、旋转和变形等几何变换,因为它们的卷积操作基于固定网格结构。

  • DCN 通过允许卷积网格根据输入图像特征进行调整和变形来解决这个问题。

可变形卷积

  • 标准卷积:使用固定网格对输入特征图进行采样。例如,3x3 内核对输入特征图中的九个固定点进行采样。

  • 可变形卷积:在标准网格采样位置引入可学习的偏移量。这些偏移量是从前面的特征图中学习到的,使网格能够变形并适应图像中对象的形状和比例。 -实现:将偏移量应用于网格点,并使用双线性插值在这些新位置进行采样以处理分数偏移。

可变形 RoI 池化

标准 RoI 池化

将给定的 RoI 划分为固定的空间箱,并在每个箱内应用最大池化以将该区域转换为固定大小的特征图。 -可变形 RoI 池化:将可学习的偏移量添加到箱化位置,使池化操作能够适应 RoI 内对象的形状。 -实现:偏移量是通过额外的卷积层学习到的,并在池化操作期间应用以动态调整箱位。

训练和集成

可变形卷积和 RoI 池化都可以在任何 CNN 架构中取代其标准对应物。

  • 偏移学习过程引入的附加参数使用反向传播进行端到端训练。

  • 可变形卷积网络可轻松集成到最先进的 CNN 架构(如 ResNet 和 Inception-ResNet)中,用于对象检测和语义分割等任务。

优点:

  • 灵活性: 通过允许采样网格和 RoI 区域变形,DCN 可以更准确地模拟复杂的几何变换和对象形状的变化。

  • 性能: 实证结果表明,DCN 显著提高了对象检测和分割等复杂视觉任务的性能,尤其是对于具有不同尺度和变形的对象。

视觉插图:

  • 可变形卷积: 采样点不是固定的 3x3 网格,而是根据学习到的偏移进行位移,从而产生更灵活和自适应的感受野。

  • 可变形 RoI 池化:动态调整 RoI 箱以更好地适应对象的形状,从而增强池化操作的有效性。

应用:

  • 对象检测:更好地处理不同大小和形状的对象。

  • 语义分割:提高复杂场景中像素标记的准确性。

综上所述,DCN 通过引入可变形卷积和 RoI 池化增强了 CNN 的几何变换建模能力。这些模块为网络提供了根据输入特征调整其结构的能力,从而提高了各种计算机视觉任务的性能。

2. 将C2f_DCN添加到YOLOv8中

2.1 Deformable Convolutional Networks代码实现

关键步骤一: 将下面代码粘贴到在/ultralytics/ultralytics/nn/modules/block.py中,并在该文件的__all__中添加“C2f_DCN”

*注:代码过长,只放置部分代码,需要可以查看第三部分的完整代码

class DCNv2(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1,
                 padding=1, dilation=1, groups=1, deformable_groups=1):
        super(DCNv2, self).__init__()

        self.in_channels = in_channels
        self.out_channels = out_channels
        self.kernel_size = (kernel_size, kernel_size)
        self.stride = (stride, stride)
        self.padding = (padding, padding)
        self.dilation = (dilation, dilation)
        self.groups = groups
        self.deformable_groups = deformable_groups

        self.weight = nn.Parameter(
            torch.empty(out_channels, in_channels, *self.kernel_size)
        )
        self.bias = nn.Parameter(torch.empty(out_channels))

        out_channels_offset_mask = (self.deformable_groups * 3 *
                                    self.kernel_size[0] * self.kernel_size[1])
        self.conv_offset_mask = nn.Conv2d(
            self.in_channels,
            out_channels_offset_mask,
            kernel_size=self.kernel_size,
            stride=self.stride,
            padding=self.padding,
            bias=True,
        )
        self.bn = nn.BatchNorm2d(out_channels)
        self.act = Conv.default_act
        self.reset_parameters()

    def forward(self, x):
        offset_mask = self.conv_offset_mask(x)
        o1, o2, mask = torch.chunk(offset_mask, 3, dim=1)
        offset = torch.cat((o1, o2), dim=1)
        mask = torch.sigmoid(mask)
        x = torch.ops.torchvision.deform_conv2d(
            x,
            self.weight,
            offset,
            mask,
            self.bias,
            self.stride[0], self.stride[1],
            self.padding[0], self.padding[1],
            self.dilation[0], self.dilation[1],
            self.groups,
            self.deformable_groups,
            True
        )
        x = self.bn(x)
        x = self.act(x)
        return x

    def reset_parameters(self):
        n = self.in_channels
        for k in self.kernel_size:
            n *= k
        std = 1. / math.sqrt(n)
        self.weight.data.uniform_(-std, std)
        self.bias.data.zero_()
        self.conv_offset_mask.weight.data.zero_()
        self.conv_offset_mask.bias.data.zero_()


class Bottleneck_DCN(nn.Module):
    # Standard bottleneck with DCN
    def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5):  # ch_in, ch_out, shortcut, groups, kernels, expand
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        if k[0] == 3:
            self.cv1 = DCNv2(c1, c_, k[0], 1)
        else:
            self.cv1 = Conv(c1, c_, k[0], 1)
        if k[1] == 3:
            self.cv2 = DCNv2(c_, c2, k[1], 1, groups=g)
        else:
            self.cv2 = Conv(c_, c2, k[1], 1, g=g)
        self.add = shortcut and c1 == c2

    def forward(self, x):
        return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))

可变形卷积网络 (DCN) 以一种将适应性引入标准卷积神经网络操作的方式处理数据。

可变形卷积网络中的主要处理流程

输入数据

  • 网络的输入通常是一张图像或一批图像。

初始卷积层

  • 输入图像通过初始标准卷积层处理以提取基本特征。这些层的功能与传统 CNN 中的层类似,应用固定网格卷积操作。

可变形卷积层

  • 在初始特征提取之后,应用可变形卷积层。

  • 偏移生成:对于特征图上的每个位置,使用单独的卷积操作来预测采样网格的偏移量。这会产生一个动态学习的偏移场。

  • 可变形采样:使用预测的偏移量,调整卷积的采样网格。卷积运算不是从固定位置采样,而是从偏移定义的位置采样,这些偏移通常是分数,需要双线性插值。

  • 卷积运算:然后使用新的变形网格位置应用卷积运算,生成具有增强的对输入几何结构的适应性的输出特征图。

可变形 RoI 池化(用于对象检测/分割任务)

  • RoI 提取:根据区域提议网络 (RPN) 等方法生成的提议,从特征图中提取感兴趣区域 (RoI)。

  • RoI 的偏移生成:与可变形卷积类似,预测 RoI 箱的偏移。

  • 可变形箱化:根据学习到的偏移量调整 RoI 池化中的箱,使池化区域能够适应 RoI 内对象的形状和位置。

  • 池化操作:在这些调整后的箱内执行最大池化或平均池化,以为每个 RoI 生成固定大小的特征图。

后续卷积层

  • 可变形卷积和/或 RoI 池化层的输出将输入到后续卷积层和全连接层中,具体取决于特定架构(例如 ResNet、Faster R-CNN)。

  • 这些层继续处理特征图以执行分类、边界框回归和分割等任务。

输出层

  • 网络的最后几层产生所需的输出,例如用于对象检测的类别分数和边界框坐标,或用于语义分割的逐像素分类。

训练

  • 使用反向传播对包括可变形模块在内的网络进行端到端训练。

  • 使用适合特定任务的损失函数(例如,分类的交叉熵损失、边界框回归的平滑 L1 损失)来指导训练过程。

  • 除了标准卷积参数外,还学习了可变形卷积和 RoI 池化层的偏移量和权重。

优点

  • 适应性:网络可以适应不同的物体形状和尺度,从而提高涉及不同几何变换的任务的性能。

  • 提高性能:实证结果表明,DCN 在物体检测和语义分割等任务中的表现优于传统 CNN。

结论

DCN 通过引入可变形卷积和 RoI 池化增强了传统 CNN,使其更有能力处理复杂的几何变化。这种适应性对于提高各种计算机视觉任务的性能至关重要。

2.2 更改init.py文件

关键步骤二:修改modules文件夹下的__init__.py文件,先导入函数

然后在下面的__all__中声明函数

2.3 添加yaml文件

关键步骤三:在/ultralytics/ultralytics/cfg/models/v8下面新建文件yolov8_DCN.yaml文件,粘贴下面的内容

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect

# Parameters
nc: 80  # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'
  # [depth, width, max_channels]
  n: [ 0.33, 0.25, 1024 ]  # YOLOv8n summary: 225 layers,  3157200 parameters,  3157184 gradients,   8.9 GFLOPs

# YOLOv8.0n backbone
backbone:
  # [from, repeats, module, args]
  - [ -1, 1, Conv, [ 64, 3, 2 ] ]  # 0-P1/2
  - [ -1, 1, Conv, [ 128, 3, 2 ] ]  # 1-P2/4
  - [ -1, 3, C2f_DCN, [ 128, True ] ]   
  - [ -1, 1, Conv, [ 256, 3, 2 ] ]  # 3-P3/8
  - [ -1, 6, C2f_DCN, [ 256, True ] ]
  - [ -1, 1, Conv, [ 512, 3, 2 ] ]  # 5-P4/16
  - [ -1, 6, C2f_DCN, [ 512, True ] ]
  - [ -1, 1, Conv, [ 1024, 3, 2 ] ]  # 7-P5/32
  - [ -1, 3, C2f_DCN, [ 1024, True ] ]
  - [ -1, 1, SPPF, [ 1024, 5 ] ]  # 9

# YOLOv8.0n head
head:
  - [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ]
  - [ [ -1, 6 ], 1, Concat, [ 1 ] ]  # cat backbone P4
  - [ -1, 3, C2f_DCN, [ 512 ] ]  # 12

  - [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ]
  - [ [ -1, 4 ], 1, Concat, [ 1 ] ]  # cat backbone P3
  - [ -1, 3, C2f_DCN, [ 256 ] ]  # 15 (P3/8-small)

  - [ -1, 1, Conv, [ 256, 3, 2 ] ]
  - [ [ -1, 12 ], 1, Concat, [ 1 ] ]  # cat head P4
  - [ -1, 3, C2f_DCN, [ 512 ] ]  # 18 (P4/16-medium)

  - [ -1, 1, Conv, [ 512, 3, 2 ] ]
  - [ [ -1, 9 ], 1, Concat, [ 1 ] ]  # cat head P5
  - [ -1, 3, C2f_DCN, [ 1024 ] ]  # 21 (P5/32-large)

  - [ [ 15, 18, 21 ], 1, Detect, [ nc ] ]  # Detect(P3, P4, P5)

温馨提示:本文只是对yolov8基础上添加模块,如果要对yolov8n/l/m/x进行添加则只需要指定对应的depth_multiple 和 width_multiple。


# YOLOv8n
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.25  # layer channel multiple
 
# YOLOv8s
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple
 
# YOLOv8l 
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple
 
# YOLOv8m
depth_multiple: 0.67  # model depth multiple
width_multiple: 0.75  # layer channel multiple
 
# YOLOv8x
depth_multiple: 1.33  # model depth multiple
width_multiple: 1.25  # layer channel multiple

2.4 在task.py中进行注册

关键步骤四:在parse_model函数中进行注册,添加C2f_DCN,

2.5 执行程序

关键步骤五:在ultralytics文件中新建train.py,将model的参数路径设置为yolov8_DCN.yaml的路径即可

from ultralytics import YOLO
 
# Load a model
# model = YOLO('yolov8n.yaml')  # build a new model from YAML
# model = YOLO('yolov8n.pt')  # load a pretrained model (recommended for training)
 
model = YOLO(r'/projects/ultralytics/ultralytics/cfg/models/v8/yolov8_DCN.yaml')  # build from YAML and transfer weights
 
# Train the model
model.train(device = [3], batch=16)

建议大家写绝对路径,确保一定能找到

🚀运行程序,如果出现下面的内容则说明添加成功🚀

3. 完整代码分享

https://pan.baidu.com/s/1kN1rW_tmKbefMKIkUXcqLw?pwd=ybu6

提取码: ybu6 

4. GFLOPs

关于GFLOPs的计算方式可以查看百面算法工程师 | 卷积基础知识——Convolution

未改进的YOLOv8nGFLOPs

img

改进后的GFLOPs

5. 进阶

可以结合损失函数和注意力机制进行改进

6. 总结

可变形卷积网络 (DCN) 通过引入可变形卷积和可变形 RoI(感兴趣区域)池化模块增强了传统的卷积神经网络 (CNN)。这些模块允许采样网格和 RoI 区域通过学习偏移量动态适应输入图像中对象的形状和比例。这种适应性使网络能够更有效地处理几何变换和变化,从而显著提高对象检测和语义分割等复杂视觉任务的性能。  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1862535.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于 ESP8266 和 MQ 气体传感器的微信告警系统设计与实现

接线: ESP8266MQ3vVCCGND GND A0 A0微信通知截图: 摘要:本文主要探讨了一种利用 ESP8266 微控制器与 MQ 气体传感器构建的气体检测微信告警系统。详细阐述了系统的硬件组成、软件设计以及与微信平台的交互机制。通过该系统,能够实时监测环境中的气…

vxe-表尾单元格进行合并后更改其表尾背景颜色

1.场景 在vxe-table的官网API中可以使用footer-cell-class-name给单元格添加背景颜色或者其他样式,但是本人场景进行了表尾合并的操作;参考API进行更改背景颜色失败; 2.解决 利用表尾css类名的区别,用子类选择器进行对应的选择设…

mulesoft --环境安装与搭建

1.mavenjdkpostman 2.anypoint statdio 下载安装 下载 Anypoint Studio & Mule |骡子软件 (mulesoft.com) 填好基本信息后,会发邮件,在邮件中下载,跳到官网下载 3注册账号 Download Anypoint Studio & Mule | MuleSoft 4.Connect…

StarRocks 存算分离成本优化最佳实践

序言 StarRocks 存算分离借助对象存储来实现计算和存储能力分离,而存算分离版本 StarRocks 一般来说有以下三方面成本: 计算成本,也即机器使用成本,尤其是运行在公有云上时存储成本,该部分与对象存储上存储的数据量相…

埃特巴什码加解密小程序

埃特巴什码加解密小程序 这几天在看CTF相关的课程,涉及到古典密码学和近代密码学还有现代密码学。 简单替换密码 Atbash Cipher 埃特巴什码(Atbash Cipher)其实可以视为下面要介绍的简单替换密码的特例,它使用字母表中的最后 一个字母代表第一个字母…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十七)

课程地址: 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程,一套精通鸿蒙应用开发 (本篇笔记对应课程第 27节) P27《26.Stage模型-UIAbility的启动模式》 本节讲解 UIAbility的启动模式:Stage模型的应用&#x…

语言的数据结构:树与二叉树(二叉树篇)

语言的数据结构:树与二叉树(二叉树篇) 前言概念特别的二叉树满二叉树完全二叉树 存储结构顺序存储链式存储 查找方式 前言 上文说到了树,有人认为二叉树是树的每一个分支都有两个子节点。其实这也对。但二叉树在此基础上还做了限…

支持离线翻译任意语言的桌面应用程序;单张图像高效生成高质量的 3D 模型;2500种色彩映射的集合,适用于matplotlib和seaborn

✨ 1: Lingo Lingo是一款支持离线翻译任意语言的桌面应用程序 Lingo 是一款支持离线翻译的桌面应用程序,用户可以在不连接互联网的情况下进行多语言翻译。这款软件利用了Meta公司提供的nllb-200-distilled-600M 多语言模型,以实现高效的翻译功能。 没…

jupyter notebook的markdown语法不起作用

在这个界面编辑,发现markdown你编辑的是什么就是什么,不起作用,然而点一下: 右上角“Notebook转发”,就会单独跳出一个jupyter notebook的界面,此时就会奏效:

6.25作业

1.整理思维导图 2.终端输入两个数,判断两数是否相等,如果不相等,判断大小关系 #!/bin/bash read num1 read num2 if [ $num1 -eq $num2 ] then echo num1num2 elif [ $num1 -gt $num2 ] then echo "num1>num2" else echo &quo…

大学生搜题神器网站?分享七个支持答案和解析的工具 #职场发展#学习方法

在现代科技的帮助下,大学生们有幸能够利用各种日常学习工具来提升自己的学习效果。 1.全球翻译官 是一款在线翻译语言的服务平台,在app中,用户能够在线通过语音,拍照来翻译语言,非常的便捷,也支持文字翻译哦 全球翻…

SDA626 3A,4.5V-16V输入,500kHz同步降压型转换器

一般说明 该SDA626是一个完全集成,高效率的3A同步整流降压转换器。该SDA626工作在一个宽的输出电流负载范围高效率该设备提供两种工作模式,PWM控制和PFM模式切换控制,这使得在更广泛的负载范围内具有较高的效率。 SDA626需要最…

浦语·灵笔2 模型部署图片理解实战

效果图镇楼 1、使用 huggingface_hub 下载模型中的部分文件(演示练习与模型实战无关) 使用 Hugging Face 官方提供的 huggingface-cli 命令行工具。安装依赖: pip install -U huggingface_hub 然后新建 python 文件,填入以下代码&#xf…

Ubuntu20.04使用Samba

目录 一、Samba介绍 Samba 的主要功能 二、启动samba 三、主机操作 四、Ubuntu与windows系统中文件互联 五、修改samba路径 一、Samba介绍 Samba 是一个开源软件套件,用于在 Linux 和 Unix 系统上实现 SMB(Server Message Block)协议…

iptables(4)规则匹配条件(源、目、协议、接口、端口)

简介 前面我们已经介绍了iptables的基本原理,表、链,数据包处理流程。如何查询各种表的信息。还有基本的增、删、改、保存的基础操作。 经过前文介绍,我们已经能够熟练的管理规则了,但是我们只使用过一种匹配条件,就是将”源地址”作为匹配条件。那么这篇文章中,我们就来…

为什么小程序每次提交会有很多unpackage下的文件

解决办法.gitignore 文件 .DS_Store /unpackage# local env files .env.local .env.*.local# Log files npm-debug.log* yarn-debug.log* yarn-error.log*# Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln *.sw?

获取 S 参数仿真中属性所对应的值

获取 S 参数仿真中属性所对应的值 引言正文对 S41 参数进行获取方法一方法二方法三引言 应该有很多小伙伴有过困惑,在进行 S 参数扫描后,想要可视化一下对应参数的图像,每次手动点击一个是比较麻烦,另一个是显示的效果并不是很美观。此时,如果我们可以使用 Lumerical 脚本…

工作之建造者模式

刚刚开通了一个公众号,会分享一些技术博客和自己觉得比较好的项目,同时会更新一些自己使用的工具和图书资料,后面会整理一些面试资料进行分享,觉得有兴趣的可以关注一下。 项目场景: 工作中最近对接的第三方系统的AP…

数组,链表,红黑树介绍以及性能对比实验

作者:晓宜 🌈🌈🌈 个人简介:携程javaer,阿里云专家博主,csdn后端优质创作者,算法爱好者 ❤️❤️❤️ 一起进步!!!😊 前言 以前学了数…

安装zabbix时报错Could not resolve host: mirrors.huaweicloud.com;Unknown error解决办法

目录 1、问题原因 2、解决办法 3、知识拓展 DNS的区别 DNS配置文件解析 域名解析过程 4、书籍推荐 当安装Zabbix server,Web前端,agent时出现: [rootsc-zabbix-server ~]# yum install zabbix-server-mysql zabbix-agent安装过程中会出…