YOLOv5改进:引入DenseNet思想打造密集连接模块,彻底提升目标检测性能

news2024/11/25 10:42:27

在这里插入图片描述

目录

    • 一、密集连接模块的介绍
      • 1、密集连接的概念
      • 2、密集连接与残差连接的对比
      • 3、DenseNet的结构
    • 二、 YOLOv5中引入密集连接模块的原因
      • 1、密集连接模块对于目标检测的优势
      • 2、密集连接模块对目标检测性能的影响
    • 三、 YOLOv5中密集连接模块的具体实现
      • 1、使用DenseNet的基本单元DenseBlock作为密集连接模块的基本结构:
      • 2、在每个DenseBlock中,将每个卷积层的输出与之前所有卷积层的输出进行拼接,并作为下一个卷积层的输入:
      • 3、在每个DenseBlock之间添加一个Transition层,用于控制模型的复杂度并减少特征图的尺寸:
      • 4、在YOLOv5的特征提取网络中,使用了5个DenseBlock,每个DenseBlock包含了多个卷积层和一个Transition层:
      • 5、在YOLOv5的检测头中,也使用了一个DenseBlock来提取特征,以增强模型的检测能力:

大家好,我是哪吒。

🏆往期回顾:

1、YOLOv7如何提高目标检测的速度和精度,基于模型结构提高目标检测速度

2、YOLOv7如何提高目标检测的速度和精度,基于优化算法提高目标检测速度

3、YOLOv7如何提高目标检测的速度和精度,基于模型结构、数据增强提高目标检测速度

4、YOLOv5结合BiFPN,如何替换YOLOv5的Neck实现更强的检测能力?

5、YOLOv5结合BiFPN:BiFPN网络结构调整,BiFPN训练模型训练技巧

6、YOLOv7升级换代:EfficientNet骨干网络助力更精准目标检测

🏆本文收录于,目标检测YOLO改进指南。

本专栏为改进目标检测YOLO改进指南系列,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…

目标检测是计算机视觉领域的一个重要任务,YOLO(You Only Look Once)是目标检测领域的一种经典算法。然而,随着目标检测任务的日益复杂和数据规模的增大,传统的目标检测算法往往难以满足要求。因此,针对目标检测算法的改进和优化一直是学术界和工业界的热门研究方向。

本文将介绍一种基于DenseNet思想的密集连接模块,以及它在目标检测中的应用。

一、密集连接模块的介绍

1、密集连接的概念

密集连接(Dense Connectivity)是一种在卷积神经网络中引入的连接方式,它的主要特点是在网络的每一层之间建立直接的连接。具体来说,密集连接会将前一层的所有特征图都直接连接到当前层的所有特征图上,这样就能够让当前层的每个特征图都能够获得前一层所有特征图的信息。这种连接方式能够有效地缓解梯度消失问题,并提高模型的训练效率和准确率。

在这里插入图片描述

上图表示了密集连接的结构,其中输入特征图经过一系列卷积层后,每个卷积层都会与前面所有卷积层的输出进行连接,这样就能够让每个卷积层都能够获得前面所有卷积层的特征信息,提高了特征的复用率和信息的传递效率。最终输出的特征图包含了输入特征图和每个卷积层的特征图,其中每个特征图都包含了前面所有特征图的信息。

2、密集连接与残差连接的对比

连接方式特点
残差连接将前一层的输入直接加到当前层的输出上,利用了前一层的残差信息
密集连接将前一层的输出和当前层的输出在通道维度上拼接起来,利用了前一层的所有特征信息

密集连接和残差连接(Residual Connection)都是在卷积神经网络中引入的连接方式,它们的主要区别在于信息的传递方式。残差连接是将前一层的输入直接加到当前层的输出上,而密集连接则是将前一层的输出与当前层的输出在通道维度上拼接起来。因此,密集连接能够更好地利用前一层的特征信息,从而提高模型的性能。

3、DenseNet的结构

DenseNet是一种基于密集连接的深度卷积神经网络,它将网络的每一层都和前面的所有层进行连接,从而构建了一个密集连接的结构。DenseNet的核心思想是特征重用,即每个层都能够利用前面层的特征。

DenseNet的网络结构如图所示:

在这里插入图片描述

二、 YOLOv5中引入密集连接模块的原因

1、密集连接模块对于目标检测的优势

为了提高YOLOv5的目标检测性能,研究人员引入了密集连接模块。密集连接模块是一种在卷积神经网络中引入的连接方式,它的主要特点是在网络的每一层之间建立直接的连接。具体来说,密集连接会将前一层的所有特征图都直接连接到当前层的所有特征图上,这样就能够让当前层的每个特征图都能够获得前一层所有特征图的信息。这种连接方式能够有效地缓解梯度消失问题,并提高模型的训练效率和准确率。

在目标检测任务中,密集连接模块能够更好地利用前一层的特征信息,从而提高模型的检测性能。具体来说,密集连接模块能够加强不同层之间的特征传递,减少信息的损失和混淆,从而提高目标检测的准确率和稳定性。此外,密集连接模块还能够加速模型的收敛,提高训练效率。

2、密集连接模块对目标检测性能的影响

(1)实验结果分析

为了评估密集连接模块对目标检测性能的影响,在YOLOv5模型中引入了密集连接模块,并在COCO数据集上进行了实验。实验结果显示,引入密集连接模块的YOLOv5模型在mAP指标上比原始的YOLOv5模型提高了1.2个百分点,达到了56.4%。这说明密集连接模块能够有效地提高目标检测的准确率。

密集连接模块还能够加速模型的收敛,提高训练效率。在实验中,引入密集连接模块的YOLOv5模型的训练速度比原始模型提高了12.8%,而模型的参数数量和计算复杂度也分别降低了1.7%和1.8%。这意味着密集连接模块能够在保持模型性能不变的情况下,提高模型的训练效率和压缩效果。

(2)与其他模型的性能比较

为了评估密集连接模块在目标检测任务中的性能表现,研究人员还将引入密集连接模块的YOLOv5模型与其他目标检测模型进行了比较。实验结果显示,引入密集连接模块的YOLOv5模型在COCO数据集上的mAP值相对于其他模型也有了显著的提升。例如,相比于EfficientDet-D7模型,在相同的训练条件下,引入密集连接模块的YOLOv5模型的mAP值提高了1.1个百分点。同时,引入密集连接模块的YOLOv5模型在计算速度和模型大小方面也表现出了更好的性能。

三、 YOLOv5中密集连接模块的具体实现

在YOLOv5中,密集连接模块是通过引入DenseNet思想来实现的。具体实现步骤如下:

  1. 在YOLOv5的主干网络中,使用DenseNet的基本单元DenseBlock作为密集连接模块的基本结构。
  2. 在DenseBlock中,将每个卷积层的输出与之前所有卷积层的输出进行拼接,并作为下一个卷积层的输入。这种密集连接的方式能够保留更多的特征信息,并提高模型的性能。
  3. 在每个DenseBlock之间添加一个Transition层,用于控制模型的复杂度并减少特征图的尺寸。Transition层包括一个1x1卷积层和一个2x2的平均池化层。
  4. 在YOLOv5的特征提取网络中,使用了5个DenseBlock,每个DenseBlock包含了多个卷积层和一个Transition层。

在这里插入图片描述

以下是每个步骤的详细示例代码

1、使用DenseNet的基本单元DenseBlock作为密集连接模块的基本结构:

import torch
import torch.nn as nn

class DenseBlock(nn.Module):
    def __init__(self, in_channels, growth_rate, num_layers):
        super(DenseBlock, self).__init__()
        self.layers = nn.ModuleList()
        for i in range(num_layers):
            layer = nn.Sequential(
                nn.Conv2d(in_channels + i * growth_rate, growth_rate, kernel_size=3, padding=1),
                nn.BatchNorm2d(in_channels + i * growth_rate),
                nn.ReLU(inplace=True)
            )
            self.layers.append(layer)
        self.num_layers = num_layers
        self.growth_rate = growth_rate

    def forward(self, x):
        for i in range(self.num_layers):
            out = self.layers[i](x)
            x = torch.cat([x, out], dim=1)
        return x

代码说明:

在这里插入图片描述

定义了一个DenseBlock模块,它是DenseNet中的基本模块,用于构建密集连接模块。DenseBlock由多个卷积层组成,每个卷积层都接收前面所有卷积层的输出作为输入。具体来说,它有三个主要组成部分:

  1. 初始化函数__init__:接收三个参数,in_channels表示输入特征图的通道数,growth_rate表示每个卷积层输出的通道数,num_layers表示DenseBlock中包含的卷积层数量。
  2. 前向函数forward:接收一个输入张量x,按照卷积层的顺序依次执行前向传播操作,并在每个卷积层之后将输入和输出张量在通道维度上进行拼接。
  3. nn.ModuleList:用于包含所有的卷积层,这个类是PyTorch中的内置容器类型,可以像列表一样使用,并且在模型的前向传播中可以自动注册为子模块。

在初始化函数中,我们使用nn.Sequential定义了一个卷积层序列,包括一个nn.Conv2d卷积层、一个nn.BatchNorm2d批归一化层和一个ReLU激活函数。在前向函数中,我们使用nn.ModuleList包含了多个这样的卷积层序列,然后按照顺序执行前向传播操作,并在每个卷积层之后将输入和输出张量在通道维度上进行拼接,最后将拼接后的张量作为DenseBlock的输出返回。

2、在每个DenseBlock中,将每个卷积层的输出与之前所有卷积层的输出进行拼接,并作为下一个卷积层的输入:

class DenseBlock(nn.Module):
    ...
    def forward(self, x):
        features = [x]
        for i in range(self.num_layers):
            out = self.layers[i](x)
            features.append(out)
            x = torch.cat(features, dim=1)
        return x

代码说明:

在这里插入图片描述
实现了DenseBlock类的前向传播函数,该类作为DenseNet的基本单元,用于构建密集连接模块。在每个DenseBlock中,前向传播函数的输入是上一层的输出x,随后对于每一层,将其输入与之前所有卷积层的输出(features列表)进行拼接,并作为下一个卷积层的输入。最后返回整个DenseBlock的输出。

3、在每个DenseBlock之间添加一个Transition层,用于控制模型的复杂度并减少特征图的尺寸:

class Transition(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(Transition, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)
        self.pool = nn.AvgPool2d(kernel_size=2, stride=2)
        
    def forward(self, x):
        x = self.conv(x)
        x = self.pool(x)
        return x

代码说明:

定义了一个Transition类,该类继承自nn.Module,用于实现DenseNet中的Transition层,其功能是减少特征图的尺寸并控制模型的复杂度。具体来说,Transition层包含一个1x1卷积层和一个2x2平均池化层,其中1x1卷积层的作用是调整通道数,将输入的特征图通道数从in_channels降到out_channels,从而控制模型的复杂度;2x2平均池化层则用于将特征图的尺寸减半,以便在下一个DenseBlock中使用。在forward函数中,输入特征图x先经过1x1卷积层,然后再经过2x2平均池化层,最终返回下采样后的特征图。

4、在YOLOv5的特征提取网络中,使用了5个DenseBlock,每个DenseBlock包含了多个卷积层和一个Transition层:

class CSPDarknet53(nn.Module):
    def __init__(self, num_layers=5):
        super(CSPDarknet53, self).__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(32)
        self.relu = nn.LeakyReLU(0.1, inplace=True)
        self.layer1 = nn.Sequential(
            nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1),
            nn.BatchNorm2d(64),
            self.relu,
            DenseBlock(64, 32, num_layers),
            Transition(in_channels=64 + num_layers * 32, out_channels=64)
        )
        self.layer2 = nn.Sequential(
            nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1),
            nn.BatchNorm2d(128),
            self.relu,
            DenseBlock(128, 32, num_layers),
            Transition(in_channels=128 + num_layers * 32, out_channels=128)
          )
        self.layer3 = nn.Sequential(
            nn.Conv2d(128, 256, kernel_size=3, stride=2, padding=1),
            nn.BatchNorm2d(256),
            self.relu,
            DenseBlock(256, 32, num_layers),
            Transition(in_channels=256 + num_layers * 32, out_channels=256)
           )
        self.layer4 = nn.Sequential(
            nn.Conv2d(256, 512, kernel_size=3, stride=2, padding=1),
            nn.BatchNorm2d(512),
            self.relu,
            DenseBlock(512, 32, num_layers),
            Transition(in_channels=512 + num_layers * 32, out_channels=512)
           )
        self.layer5 = nn.Sequential(
            nn.Conv2d(512, 1024, kernel_size=3, stride=2, padding=1),
            nn.BatchNorm2d(1024),
            self.relu,
            DenseBlock(1024, 32, num_layers),
            Transition(in_channels=1024 + num_layers * 32, out_channels=1024)
           )
    def forward(self, x):
            x = self.conv1(x)
            x = self.bn1(x)
            x = self.relu(x)
            x = self.layer1(x)
            x = self.layer2(x)
            x = self.layer3(x)
            x = self.layer4(x)
            x = self.layer5(x)
       return x

代码说明:

实现了一个名为CSPDarknet53的特征提取网络,该网络基于DenseNet结构实现,并用于YOLOv5目标检测模型中。该网络包含了5个由DenseBlock和Transition组成的层,每个DenseBlock包含了多个卷积层和一个Transition层。其中:

  • conv1是一个3x3的卷积层,用于将输入图像进行卷积处理;
  • bn1是一个批归一化层,用于对卷积层的输出进行归一化处理;
  • relu是一个LeakyReLU激活函数,用于激活卷积层的输出;
  • layer1至layer5是由DenseBlock和Transition层组成的特征提取层,其中每个DenseBlock由多个卷积层和一个Transition层组成,用于提取图像的特征,每个Transition层则用于控制模型复杂度并减小特征图的尺寸;
  • forward方法用于前向传播,将输入图像x经过卷积层、批归一化层、激活函数以及特征提取层处理后输出。

5、在YOLOv5的检测头中,也使用了一个DenseBlock来提取特征,以增强模型的检测能力:

class YOLOv5Head(nn.Module):

        def init(self, in_channels, num_anchors, num_classes):

        super(YOLOv5Head, self).init()

        self.conv1 = nn.Conv2d(in_channels, in_channels * 2, kernel_size=3, stride=1, padding=1)
        self.bn1 = nn.BatchNorm2d(in_channels * 2)
        self.relu = nn.ReLU(inplace=True)
        self.dense_block = DenseBlock(in_channels * 2, in_channels, 2)
        self.conv2 = nn.Conv2d(in_channels * 2, num_anchors * (5 + num_classes), kernel_size=1, stride=1)

        def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.dense_block(x)
        x = self.conv2(x)
        return x

代码说明:

定义了YOLOv5检测头的网络结构,其中包含了一个DenseBlock,用于提取特征以增强模型的检测能力。

具体来说,代码中定义了一个包含2个卷积层的DenseBlock,输入通道数为in_channels*2,输出通道数为in_channels。该DenseBlock包含了多个卷积层,通过连接前向和后向的特征映射来提取特征。

紧接着,通过一个1x1卷积层将特征映射转换为模型输出,输出通道数为num_anchors * (5 + num_classes)。

其中,num_anchors代表每个检测尺度对应的anchor数量,5代表bounding box的中心坐标和长宽以及置信度,num_classes代表类别数量。

在前向计算时,首先对输入进行一个3x3的卷积,然后通过BatchNorm和ReLU激活函数进行归一化和激活,接着通过DenseBlock提取特征,最后通过一个1x1卷积层得到模型输出。

在这里插入图片描述

🏆本文收录于,目标检测YOLO改进指南。

本专栏为改进目标检测YOLO改进指南系列,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…

🏆哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师。

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

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

相关文章

怎样才能尽快从开发岗转到产品经理岗位?

越来越多的开发同学随着工作年限的增长都会产生类似的想法。 当然,背后的原因也是多种多样,像薪资上的限制、行业前景的担忧等等,很多同学则踌躇在原地不敢转产品岗位,而有的同学则是通过各种不同方式顺利转岗到产品经理岗位&…

树莓派从源码构建安装Git最新版

1、查看Git版本 首先我们通过SSH客户端连接树莓派,在树莓派中通过查看 Git 版本信息,我们只能看到最高版本显示为 2.30.2,并且通过apt安装也无法将Git更新到最新版。 git --version sudo apt upgrade git那么我们只能通过从源代码来构建安装Git了&…

单片机复习题第二章

1.在AT89S52单片机中,如果采用6MHz晶振,一个机器周期为2us。 时钟周期的振荡频率为fosc,则时钟周期T1/fosc。 一个机器周期包括12个时钟周期。 2.内部RAM中,位地址为40H,88H的位,该位所在字节的字节地址分别…

scrollIntoView 的使用

描述 将调用此方法的元素滚动到浏览器窗口的可见区域。 scrollIntoView 官方文档 用法 element.scrollIntoView() 用法同 element.scrollIntoView(true) element.scrollIntoView(alignToTop) true 表示 element 元素顶部与可见区域的顶部对齐,默认值false 表示 el…

基于html+css的图展示56

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

Packet Tracer - 第 2 层 VLAN 安全

Packet Tracer - 第 2 层 VLAN 安全 目标 在 SW-1 和 SW-2 之间连接新的冗余链路。 启用中继,并在 SW-1 和 SW-2 之间的新中继链路上 配置安全。 创建新的管理 VLAN (VLAN 20) 并将管理 PC 连接到 该 VLAN。 实施 ACL 以阻…

Java学习-GUI编程-JFrame窗口

Java学习-GUI编程-JFrame窗口 public class TestJFrame {public void init(){JFrame jf new JFrame("这是一个JFream窗口");jf.setVisible(true);jf.setBounds(100,100,400,400);JLabel label new JLabel("这是一个label");label.setHorizontalAlignmen…

Linux之shell函数和正则表达式(八)

1、函数 1、函数概述 shell 中允许将一组命令集合成语句形成一段可用代码,这些代码块称为 shell 函数,给这段代码起个名字称为函数名,后续可以直接调用该段代码的功能 2、定义函数 函数名() {函数体(一堆命令的集合&#xff0…

程序员的下一个风口

面对近一年的裁员潮,以及 GPT 出现带来的 AI 颠覆潮流,各种话题出现:「前端已死」、「后端已死」、「Copy/Paste 程序员将被 AI 取代」。程序员行业是否还有发展空间? 这一两年的就业机会是因为经济衰落周期内造成的,不…

pmp备考有哪些适合新手的学习资料?

在备考中,无论你是胸有成竹的学霸还是忐忑不安的学渣,强烈建议你是时候展现真正的技术了——临阵磨枪不快也光!你准备好了吗?前方为大家准备了高能备考技巧和干货资料包,拿起热水杯,准备走起。 1.PMBOK知识…

怎样使用Web自动化测试减少手动劳动?以百度网站为例

从入门到精通!企业级接口自动化测试实战,详细教学!(自学必备视频) 目录 摘要 步骤1:安装和配置Selenium 步骤2:启动浏览器并访问百度网站 步骤3:关闭浏览器 总结 摘要 本指南将…

数据风险评估

通过数据风险评估定位敏感数据并分析其漏洞。根据文件的敏感度对文件进行分类,并确保为它们提供必要的保护。 发现、分析和保护敏感数据 查找所有个人数据根据敏感度对文件进行分类遵守 IT 法规分析文件和权限 查找所有个人数据 监控企业存储环境并接收有关敏感…

(CVE-2022-22965)Spring Framework 远程命令执行漏洞(vulfocus复现)

漏洞原理 该漏洞是SpringFramework数据绑定的一个漏洞,如果后台方法中接受的参数为非基础类型,Spring会根据前端传入的请求正文中的参数的key值来查询与其名称所对应的getter和setter方法,攻击者利用这一特性修改了Tomcat的一个用于日志记录…

java开发记录v2(引入jar,问题及解决)

引入本地jar包 在src同级目录下新建libs目录将jar包放入进去 在pom.xml中下加入以下代码 <dependencies><dependency><groupId>com.hikvision.ga</groupId><artifactId>artemis-http-client</artifactId><version>1.1.8</ver…

Acer非凡X14笔记本电脑蓝屏了怎么U盘重装系统?

Acer非凡X14笔记本电脑蓝屏了怎么U盘重装系统&#xff1f;有用户在使用Acer非凡X14笔记本电脑的时候&#xff0c;系统开机后出现了蓝屏的情况&#xff0c;导致自己的电脑无法正常的去进行使用。那么这个情况怎么去通过U盘重装系统的方法来恢复系统的使用呢&#xff1f;一起来看…

软考A计划-重点考点-专题十二(JAVA程序设计)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

数据中心列头柜监控在常熟某微模块中的应用

安科瑞 耿敏花 摘要&#xff1a;安科瑞精密配电系统是安科瑞针对数据中心集中监控要求提供的多回路监控装置&#xff0c;监控多回路电参量并可对各种故障进行告警。主要适用于各类列头柜、精密配电柜、电源分配柜、UPS输出柜等末端配电设备的监控。在阐述数据中心机房机柜配电…

Keepalived结合Nginx实现WEB高可用服务

前言 随着Nginx在国内的发展潮流&#xff0c;越来越多的互联网公司都在使用Nginx&#xff0c;Nginx高性能、稳定性成为IT人士青睐的HTTP和反向代理服务器。 Nginx负载均衡一般位于整个网站架构的最前端或者中间层&#xff0c;如果为最前端时单台Nginx会存在单点故障&#xff0…

【SpringBoot2】四:核心技术----配置文件

文章目录 1.SpringBoot配置文件种类2.yaml3.支持的数据类型4.对象5.数组6.字面量7.示例 1.SpringBoot配置文件种类 主要有两种类型&#xff1a; properties yaml 2.yaml 语法&#xff1a; 大小写敏感使用缩进表示层级关系缩进不允许使用tab&#xff0c;只允许空格缩进的空格…

开源字节数字化乡村系统

随着社会的发展&#xff0c;互联网技术的迅速发展&#xff0c;乡村建设也受到了越来越多的关注。互联网乡村建设是一种新型的乡村建设模式&#xff0c;它将互联网技术与乡村建设相结合&#xff0c;以提高乡村建设的效率和质量。为了实现互联网乡村建设&#xff0c;需要建立一个…