万字详解YOLOv8网络结构Backbone/neck/head以及Conv、Bottleneck、C2f、SPPF、Detect等模块

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

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

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

简介

YOLOv8是由Ultralytics开发的最先进的目标检测模型,推升了速度、准确性和用户友好性的界限。YOLO这一缩写代表“你只看一次”(You Only Look Once),通过在一次网络传递中同时预测所有边界框,提升了算法的效率和实时处理能力。相比之下,其他一些目标检测技术需要经过多个阶段或过程来完成检测。YOLOv8在流行的YOLOv5架构上进行了扩展,在多个方面提供了改进。YOLOv8模型与其前身的主要区别在于使用了无锚点检测,这加速了非极大值抑制(Non-Maximum Suppression, NMS)的后处理过程。YOLOv8能够以惊人的速度和精度识别和定位图像和视频中的物体,并处理图像分类和实例分割等任务。

YOLOv8网络架构图1

下图是GitHub 用户 RangeKing 制作的YOLOv8网络架构的可视化结结构图。

这里的Neck和Head分开了

img

YOLOv8网络架构图2

下图是另一个版本的网络架构图,这个版本并没有区分neck和head。 但本质上两张图是一样的

img

yolov8的模型

  • n:最小的模型,最快的推理,但最低的准确性
  • S:型号小,速度和精度平衡好
  • M:中等模型,比推理速度适中的小型模型精度更高
  • L:模型大,准确率最高但推理速度最慢
  • XL:超大模型,资源密集型应用的最佳精度

img

YOLOV8的网络结构概述

YOLOv8的网络结构主要由以下三个大部分组成:

Backbone

Backbone部分负责特征提取,采用了一系列卷积和反卷积层,同时使用了残差连接和瓶颈结构来减小网络的大小并提高性能。该部分采用了C2f模块作为基本构成单元,与YOLOv5的C3模块相比,C2f模块具有更少的参数量和更优秀的特征提取能力。具体来说,C2f模块通过更有效的结构设计,减少了冗余参数,提高了计算效率。此外,Backbone部分还包括一些常见的改进技术,如深度可分离卷积(Depthwise Separable Convolution)和膨胀卷积(Dilated Convolution),以进一步增强特征提取的能力。

Neck

Neck部分负责多尺度特征融合,通过将来自Backbone不同阶段的特征图进行融合,增强特征表示能力。具体来说,YOLOv8的Neck部分包括以下组件:

  • SPPF模块(Spatial Pyramid Pooling Fast):用于不同尺度的池化操作,将不同尺度的特征图拼接在一起,提高对不同尺寸目标的检测能力。
  • PAA模块(Probabilistic Anchor Assignment):用于智能地分配锚框,以优化正负样本的选择,提高模型的训练效果。
  • PAN模块(Path Aggregation Network):包括两个PAN模块,用于不同层次特征的路径聚合,通过自底向上和自顶向下的路径增强特征图的表达能力。

Head

Head部分负责最终的目标检测和分类任务,包括一个检测头和一个分类头:

  • 检测头:包含一系列卷积层和反卷积层,用于生成检测结果。这些层负责预测每个锚框的边界框回归值和目标存在的置信度。
  • 分类头:采用全局平均池化(Global Average Pooling)对每个特征图进行分类,通过减少特征图的维度,输出每个类别的概率分布。分类头的设计使得YOLOv8能够有效地处理多类别分类任务。

其他优化

除了上述结构外,YOLOv8还引入了一些新的优化技术,如:

  • Anchor-free机制:减少了锚框的超参数设置,通过直接预测目标的中心点来简化训练过程。
  • 自适应NMS(Non-Maximum Suppression):改进了传统的NMS算法,通过自适应调整阈值,减少误检和漏检,提高检测精度。
  • 自动混合精度训练(Automatic Mixed Precision Training):通过在训练过程中动态调整计算精度,加快训练速度,同时减少显存占用。

YOLOv8架构中使用的模块

卷积块(Conv Block)

image-20240526215025196

这是架构中最基本的模块,包括Conv2d层、BatchNorm2d层和SiLU激活函数。

Conv2d层

卷积是一种数学运算,涉及将一个小矩阵(称为核或滤波器)滑动到输入数据上,执行元素级的乘法,并将结果求和以生成特征图。“2D”在Conv2d中表示卷积应用于两个空间维度,通常是高度和宽度。

  • k k k(kernel数量):滤波器或核的数量,代表输出体积的深度,每个滤波器负责检测输入中的不同特征。
  • s s s(stride步幅):步幅,指滤波器/核在输入上滑动的步长。较大的步幅会减少输出体积的空间维度。
  • p p p(padding填充):填充,指在输入的每一侧添加的额外零边框,有助于保持空间信息,并可用于控制输出体积的空间维度。
  • c c c(channels输入通道数):输入的通道数。例如,对于RGB图像, c c c为3(每个颜色:红色、绿色和蓝色各一个通道)。

BatchNorm2d层

批归一化(BatchNorm2d)是一种在深度神经网络中使用的技术,用于提高训练稳定性和收敛速度。在卷积神经网络(CNN)中,BatchNorm2d层特定地对2D输入进行批归一化,通常是卷积层的输出。它通过在每个小批次的数据中标准化特征,使每个特征在小批次中的均值接近0、方差接近1,确保通过网络的数据不会太大或太小,这有助于防止训练过程中出现的问题。

SiLU激活函数

SiLU(Sigmoid Linear Unit)激活函数,也称为Swish激活函数,是神经网络中使用的激活函数。SiLU激活函数定义如下:

[ SiLU ( x ) = x ⋅ σ ( x ) ] [ \text{SiLU}(x) = x \cdot \sigma(x) ] [SiLU(x)=xσ(x)]

其中, σ ( x ) \sigma(x) σ(x)是Sigmoid函数,定义为:

[ σ ( x ) = 1 1 + e − x ] [ \sigma(x) = \frac{1}{1 + e^{-x}} ] [σ(x)=1+ex1]

SiLU的关键特性是它允许平滑的梯度,这在神经网络训练过程中是有益的。平滑的梯度可以帮助避免如梯度消失等问题,这些问题会阻碍深度神经网络的学习过程。

瓶颈块(Bottleneck Block)

在深度神经网络,尤其是残差网络(ResNet)中,Bottleneck Block(瓶颈块)是一种常用的模块设计。Bottleneck Block旨在通过引入瓶颈结构,减少计算复杂度和参数数量,同时保留模型的性能。以下是Bottleneck Block的详细介绍。

Bottleneck Block 的典型结构

Bottleneck Block 典型地由三个卷积层(Conv2d)组成:

  1. 第一个 1x1 卷积层:用于减少通道数(压缩瓶颈)。
  2. 第二个 3x3 卷积层:用于在减少后的通道数上进行卷积操作。
  3. 第三个 1x1 卷积层:用于恢复通道数(扩展瓶颈)。

这些卷积层之间通常会插入 BatchNorm 和激活函数。一个 Bottleneck Block 还包括一个恒等映射(Identity Mapping)或一个卷积映射(Convolutional Mapping),用于实现残差连接。残差连接使得输入可以绕过中间卷积层,直接加到输出上,从而减轻梯度消失的问题。

具体结构

假设输入张量为 X X X,输出张量为 Y Y Y。Bottleneck Block 的具体结构如下:

  1. 第一个 1x1 卷积层

    • 输入: X X X
    • 卷积: C o n v 2 d ( 1 × 1 ) Conv2d(1 \times 1) Conv2d(1×1)
    • 批归一化: B a t c h N o r m 2 d BatchNorm2d BatchNorm2d
    • 激活函数: S i L U SiLU SiLU
    • 输出: X 1 X_1 X1
  2. 第二个 3x3 卷积层

    • 输入: X 1 X_1 X1
    • 卷积: C o n v 2 d ( 3 × 3 ) Conv2d(3 \times 3) Conv2d(3×3)
    • 批归一化: B a t c h N o r m 2 d BatchNorm2d BatchNorm2d
    • 激活函数: S i L U SiLU SiLU
    • 输出: X 2 X_2 X2
  3. 第三个 1x1 卷积层

    • 输入: X 2 X_2 X2
    • 卷积: C o n v 2 d ( 1 × 1 ) Conv2d(1 \times 1) Conv2d(1×1)
    • 批归一化: B a t c h N o r m 2 d BatchNorm2d BatchNorm2d
    • 输出: X 3 X_3 X3
  4. 残差连接

    • 输入: X X X X 3 X_3 X3
    • 输出: Y = X + X 3 Y = X + X_3 Y=X+X3

这种结构设计使得 Bottleneck Block 在减少计算量的同时,保留了网络的表达能力和训练稳定性。

总结

Bottleneck Block 的设计通过在中间引入较少通道的卷积操作,实现了计算效率和性能之间的平衡。以下是 Bottleneck Block 的主要特点:

  • 降维和升维:通过 1x1 卷积实现通道数的压缩和扩展,降低计算复杂度。
  • 残差连接:通过残差连接保留输入信息,有助于缓解梯度消失问题,提高网络的训练效果。
  • 高效计算:通过减少中间层的通道数,在保证性能的同时减少计算量和参数数量。

yoloV8中Bottleneck Block结构

下图是yoloV8中Bottleneck Block结构,并不是典型的结构。

YOLOv8瓶颈块结构说明
  1. 卷积层 1(Conv 1):首先输入通过一个卷积层,通常卷积核大小为 ( 1 × 1 ) (1 \times 1) (1×1),用于减少特征图的通道数。

  2. 卷积层 2(Conv 2):紧接着输入通过一个卷积层,通常卷积核大小为 ( 3 × 3 ) (3 \times 3) (3×3),用于提取特征并增加感受野。

  3. 跳跃连接(Skip Connection):在卷积层之间加入跳跃连接,将输入直接连接到输出。这种连接方式可以缓解梯度消失问题,帮助网络更好地学习。

  4. 拼接(Concatenate):最后,将跳跃连接后的输出与卷积层的输出进行拼接,形成最终输出。

参数表解读
  1. 输入(Input):输入特征图的尺寸,例如 ( 64 × 64 × 256 ) (64 \times 64 \times 256) (64×64×256)

  2. Conv 1:第一个卷积层的参数,通常包括卷积核大小、步长和填充方式等。例如,卷积核大小为 ( 1 × 1 ) (1 \times 1) (1×1),输出通道数为 64。

  3. Conv 2:第二个卷积层的参数,通常包括卷积核大小、步长和填充方式等。例如,卷积核大小为 ( 3 × 3 ) (3 \times 3) (3×3),输出通道数为 128。

  4. 跳跃连接(Skip Connection):表示是否使用跳跃连接。

  5. 输出(Output):输出特征图的尺寸。

功能和优势
  • 减少参数和计算量:通过 ( 1 × 1 ) (1 \times 1) (1×1) 卷积层减少特征图的通道数,降低计算复杂度。
  • 增加网络深度和非线性能力:通过增加 ( 3 × 3 ) (3 \times 3) (3×3) 卷积层,提取更多特征,提高模型表达能力。
  • 跳跃连接:缓解梯度消失问题,帮助训练更深的网络。
结论

YOLOv8 的瓶颈块通过减少参数、增加网络深度和缓解梯度消失问题,显著提高了模型的性能和训练效果。该结构在保持计算效率的同时,增强了特征提取的能力,使得 YOLOv8 在目标检测任务中表现出色。

image-20240526215510931

C2f 模块

下图显示了YOLOv8的C2f模块结构:

结构概述

  • C2f块:首先由一个卷积块(Conv)组成,该卷积块接收输入特征图并生成中间特征图。
  • 特征图拆分:生成的中间特征图被拆分成两部分,一部分直接传递到最终的Concat块,另一部分传递到多个Bottleneck块进行进一步处理。
  • Bottleneck块:输入到这些Bottleneck块的特征图通过一系列的卷积、归一化和激活操作进行处理,最后生成的特征图会与直接传递的那部分特征图在Concat块进行拼接(Concat)。
  • 模型深度控制:在C2f模块中,Bottleneck模块的数量由模型的depth_multiple参数定义,这意味着可以根据需求灵活调整模块的深度和计算复杂度。
  • 最终卷积块:拼接后的特征图会输入到一个最终的卷积块进行进一步处理,生成最终的输出特征图。

模块功能

  • 特征提取:通过初始的卷积块提取输入图像的基本特征。
  • 特征增强:通过多个Bottleneck块进一步提炼和增强特征,这些Bottleneck块可以捕捉更复杂的模式和细节。
  • 特征融合:通过Concat块将直接传递的特征图和处理后的特征图进行融合,使得模型可以综合利用多尺度、多层次的信息。
  • 输出生成:通过最后的卷积块生成最终的特征图,为后续的检测和分类任务提供丰富的特征表示。

image-20240526220617015

空间金字塔池化快速(SPPF)模块:

SPPF(Spatial Pyramid Pooling - Fast)块是为了高效地捕捉多尺度信息而设计的,它利用简化版的空间金字塔池化。这个块允许网络处理不同尺度的特征,这在目标检测任务中特别有用,因为目标在图像中可能以不同的大小出现。

SPPF块的结构

  1. 初始卷积块:

    • 输入特征图首先通过一个卷积块处理。 卷积核大小为1x1,输出通道数与输入特征图相同。这个卷积层的作用是减少计算量,同时提取初步特征。
    • 组件:
      • 卷积层(Conv2d)
      • 批归一化(BatchNorm2d)
      • 激活函数(通常是SiLU或ReLU)
  2. MaxPool2d层:

    池化层用于下采样输入体积的空间维度,减少网络的计算复杂度并提取主要特征。最大池化是一种特定的池化操作,对于输入张量的每个区域,仅保留最大值,其他值则被丢弃。

    在MaxPool2d的情况下,池化在输入张量的高度和宽度维度上进行。该层通过指定池化核的大小和步幅来定义。核大小决定每个池化区域的空间范围,步幅则决定连续池化区域之间的步长。

    • 初始卷积块的输出特征图经过三个MaxPool2d层。
    • 每个MaxPool2d层使用特定的卷积核大小和步幅对特征图进行池化,下采样特征图。
    • 这些层通过在特征图的不同区域上进行池化来捕捉不同尺度的信息。
  3. 拼接:

    • 三个MaxPool2d层的输出特征图在通道维度上拼接。
    • 这个操作将多尺度特征结合到一个特征图中,丰富了特征表示。
  4. 最终卷积块: 拼接后的特征图再经过一个卷积层,卷积核大小为1x1,输出通道数与初始输入特征图相同。这个卷积层的作用是融合不同尺度的特征,生成最终的输出特征图。

    • 组件:
      • 卷积层(Conv2d)
      • 批归一化(BatchNorm2d)
      • 激活函数(通常是SiLU或ReLU)

SPPF块的伪代码

以下是SPPF块的概念伪代码表示:

import torch
import torch.nn as nn

class SPPFBlock(nn.Module):
    def __init__(self, in_channels, out_channels, pool_size=5):
        super(SPPFBlock, self).__init__()
        self.initial_conv = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0),
            nn.BatchNorm2d(out_channels),
            nn.SiLU()
        )
        
        self.pool1 = nn.MaxPool2d(kernel_size=pool_size, stride=1, padding=pool_size // 2)
        self.pool2 = nn.MaxPool2d(kernel_size=pool_size, stride=1, padding=pool_size // 2)
        self.pool3 = nn.MaxPool2d(kernel_size=pool_size, stride=1, padding=pool_size // 2)
        
        self.final_conv = nn.Sequential(
            nn.Conv2d(out_channels * 4, out_channels, kernel_size=1, stride=1, padding=0),
            nn.BatchNorm2d(out_channels),
            nn.SiLU()
        )
    
    def forward(self, x):
        x_initial = self.initial_conv(x)
        
        x1 = self.pool1(x_initial)
        x2 = self.pool2(x1)
        x3 = self.pool3(x2)
        
        x_concat = torch.cat((x_initial, x1, x2, x3), dim=1)
        
        x_final = self.final_conv(x_concat)
        
        return x_final

# 使用示例
sppf_block = SPPFBlock(in_channels=64, out_channels=128)
output = sppf_block(input_tensor)

代码解释

  1. SPPFBlock 类:

    • 构造函数初始化了三个主要组件:initial_convpool1pool2pool3final_conv
    • initial_conv是一个顺序块,包括卷积、批归一化和SiLU激活。
    • pool1pool2pool3是三个MaxPool2d层,它们通过不同的卷积核大小和步幅对特征图进行池化。
    • final_conv是一个卷积块,用于处理拼接后的特征图。
  2. forward 方法:

    • 输入张量 x 通过 initial_conv 处理。
    • 输出特征图依次通过 pool1pool2pool3 层。
    • 这些层的输出在通道维度上拼接。
    • 拼接后的特征图通过 final_conv 处理,生成最终的输出。

image-20240526221100774

检测块(Detect Block)

检测块负责检测物体。与之前版本的YOLO不同,YOLOv8是一个无锚点模型,这意味着它直接预测物体的中心,而不是从已知的锚点框的偏移量进行预测。无锚点检测减少了框预测的数量,加快了推理后筛选候选检测结果的复杂后处理步骤。检测块包含两个轨道。第一轨道用于边界框预测,第二轨道用于类别预测。这两个轨道都包含两个卷积块,随后是一个单独的Conv2d层,分别给出边界框损失和类别损失。

检测块的结构

  1. 输入特征图:
    • 输入特征图来自之前网络层的输出。
  2. 两个卷积块(每个轨道):
    • 每个卷积块包含以下组件:
      • 卷积层(Conv2d)
      • 批归一化(BatchNorm2d)
      • 激活函数(通常是SiLU或ReLU)
  3. 单独的Conv2d层(每个轨道):
    • 用于边界框预测的轨道输出一个Conv2d层,得到边界框损失。
    • 用于类别预测的轨道输出一个Conv2d层,得到类别损失。

image-20240526221642998

Backbone

由最上面的YOLOv8网络结构图我们可以看出在其中的Backbone部分,由5个卷积模块和4个C2f模块和一个SPPF模块组成,

image-20240526213048170

对应到yolo的yaml文件中的:

backbone:
  # [from, repeats, module, args]
  - [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2 第0层,-1代表将上层的输入作为本层的输入。第0层的输入是640*640*3的图像。Conv代表卷积层,相应的参数:64代表输出通道数,3代表卷积核大小k,2代表stride步长。
  - [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4 第1层,本层和上一层是一样的操作(128代表输出通道数,3代表卷积核大小k,2代表stride步长)
  - [-1, 3, C2f, [128, True]] # 第2层,本层是C2f模块,3代表本层重复3次。128代表输出通道数,True表示Bottleneck有shortcut。
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8 第3层,进行卷积操作(256代表输出通道数,3代表卷积核大小k,2代表stride步长),输出特征图尺寸为80*80*256(卷积的参数都没变,所以都是长宽变成原来的1/2,和之前一样),特征图的长宽已经变成输入图像的1/8。
  - [-1, 6, C2f, [256, True]] # 第4层,本层是C2f模块,可以参考第2层的讲解。6代表本层重复6次。256代表输出通道数,True表示Bottleneck有shortcut。经过这层之后,特征图尺寸依旧是80*80*256。
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16 第5层,进行卷积操作(512代表输出通道数,3代表卷积核大小k,2代表stride步长),输出特征图尺寸为40*40*512(卷积的参数都没变,所以都是长宽变成原来的1/2,和之前一样),特征图的长宽已经变成输入图像的1/16。
  - [-1, 6, C2f, [512, True]] # 第6层,本层是C2f模块,可以参考第2层的讲解。6代表本层重复6次。512代表输出通道数,True表示Bottleneck有shortcut。经过这层之后,特征图尺寸依旧是40*40*512。
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32 第7层,进行卷积操作(1024代表输出通道数,3代表卷积核大小k,2代表stride步长),输出特征图尺寸为20*20*1024(卷积的参数都没变,所以都是长宽变成原来的1/2,和之前一样),特征图的长宽已经变成输入图像的1/32。
  - [-1, 3, C2f, [1024, True]] #第8层,本层是C2f模块,可以参考第2层的讲解。3代表本层重复3次。1024代表输出通道数,True表示Bottleneck有shortcut。经过这层之后,特征图尺寸依旧是20*20*1024。
  - [-1, 1, SPPF, [1024, 5]]  # 9 第9层,本层是快速空间金字塔池化层(SPPF)。1024代表输出通道数,5代表池化核大小k。结合模块结构图和代码可以看出,最后concat得到的特征图尺寸是20*20*(512*4),经过一次Conv得到20*20*1024。

第0层:Conv卷积

在Block 0中,处理从大小为 ( 640 × 640 × 3 ) (640 \times 640 \times 3) (640×640×3)的输入图像开始,输入图像被送入一个卷积块,该卷积块的参数如下:卷积核大小为3,步长为2,填充为1。当使用步长为2时,空间分辨率会减少。以下是具体的计算过程:

  1. 输入图像:输入图像的尺寸为 ( 640 × 640 × 3 ) (640 \times 640 \times 3) (640×640×3),其中640表示高度和宽度,3表示颜色通道(RGB)。

  2. 卷积块参数

    • 卷积核大小:3
    • 步长:2
    • 填充:1
  3. 步长和填充的影响

    • 步长:步长为2意味着卷积核每次移动2个像素。这将输入图像的空间尺寸减半。
    • 填充:填充为1意味着在输入图像的每一边都增加一圈零,这有助于在卷积后保持空间维度。
  4. 输出计算

    • 计算卷积操作输出尺寸 ( ( W o u t × H o u t ) ) ( (W_{out} \times H_{out}) ) ((Wout×Hout))的公式为:
      W o u t = ( W i n − 卷积核大小 + 2 × 填充 ) 步长 + 1 W_{out} = \frac{(W_{in} - \text{卷积核大小} + 2 \times \text{填充})}{\text{步长}} + 1 Wout=步长(Win卷积核大小+2×填充)+1
      H o u t = ( H i n − 卷积核大小 + 2 × 填充 ) 步长 + 1 H_{out} = \frac{(H_{in} - \text{卷积核大小} + 2 \times \text{填充})}{\text{步长}} + 1 Hout=步长(Hin卷积核大小+2×填充)+1

    代入公式计算:
    W o u t = ( 640 − 3 + 2 × 1 ) 2 + 1 = 640 − 3 + 2 2 + 1 = 639 2 + 1 = 320 W_{out} = \frac{(640 - 3 + 2 \times 1)}{2} + 1 = \frac{640 - 3 + 2}{2} + 1 = \frac{639}{2} + 1 = 320 Wout=2(6403+2×1)+1=26403+2+1=2639+1=320
    H o u t = ( 640 − 3 + 2 × 1 ) 2 + 1 = 640 − 3 + 2 2 + 1 = 639 2 + 1 = 320 H_{out} = \frac{(640 - 3 + 2 \times 1)}{2} + 1 = \frac{640 - 3 + 2}{2} + 1 = \frac{639}{2} + 1 = 320 Hout=2(6403+2×1)+1=26403+2+1=2639+1=320

    因此,输出特征图的尺寸为 ( 320 × 320 ) (320 \times 320) (320×320)

  5. 输出特征图

    • 卷积块产生的特征图尺寸为 ( 320 × 320 × C ) (320 \times 320 \times C) (320×320×C),其中 ( C ) (C) (C)是卷积层的输出通道数量,由使用的卷积核数量决定。例如,如果卷积层有64个卷积核,输出特征图的尺寸将为 ( 320 × 320 × 64 ) (320 \times 320 \times 64) (320×320×64)

经过一个卷积核大小为3、步长为2、填充为1的卷积块后,输入尺寸为 ( 640 × 640 × 3 ) (640 \times 640 \times 3) (640×640×3)的图像被减少到尺寸为 ( 320 × 320 ) (320 \times 320 ) (320×320)的特征图。由于步长为2,空间分辨率减半。

第2层 C2f模块

YOLOv8中的C2f模块由多个瓶颈块组成,具有两个关键参数:

  • shortcut:一个布尔值,表示瓶颈块是否使用快捷连接。

    • 如果 shortcut = true,则C2f模块内的瓶颈块使用快捷连接(残差连接)。输入 -----> 1x1卷积 -----> 3x3卷积 -----> 1x1卷积 -----> 输出
    • 如果 shortcut = false,则C2f模块内的瓶颈块不使用快捷连接。输入 -----> 1x1卷积 -----> 3x3卷积 -----> 1x1卷积 -----> 输出
  • n

    • 该参数指定C2f模块内瓶颈块的数量。
    • 它的计算公式为 𝑛=3×𝑑n=3×d,其中 𝑑ddepth_multiple

配置项

配置项 [-1, 3, C2f, [128, True]] 提供了关于YOLOv8模型中Block 2(C2f模块)的详细信息。

  1. 输入来自前一层:

    • -1 表示此模块从网络中紧邻的前一层获取输入。
  2. 瓶颈块的数量(n):

    • 配置中的 3 表示 n 由 3 乘以 depth_multiple 参数确定。
    • 即,n = 3 \times d,其中 ddepth_multiple
  3. C2f模块:

    • 块类型是 C2f,其中包括多个瓶颈块。
  4. C2f模块的参数:

    • [128, True] 指定了C2f模块的附加参数:
      • 128: 此模块的输出通道数。
      • True: 表示瓶颈块是否使用快捷连接的 shortcut 参数。

“n” 版本YOLOv8的示例计算

对于YOLOv8模型的“n”版本:

  • “n”版本的YOLOv8模型的 depth_multiple 是0.33。
  • 因此,𝑛=3×0.33=0.99n=3×0.33=0.99,四舍五入为1。
  • 因此,在C2f模块内使用1个瓶颈块。

C2f模块的特性:

  • 分辨率:特征图的分辨率在C2f模块内保持不变。
  • 输出通道:输出通道数与输入通道数保持相同。

第8层:C2f模块

SPPF Block 在主干网中 C2f 模块的最后一个卷积层之后使用。SPPF 模块的主要功能是在图像中以各种大小生成对象的固定特征表示,而无需调整图像大小或引入空间信息丢失。(详见上文)

Neck

Neck使用多尺度特征融合,将 backbone 不同阶段的特征图融合增强特征表现能力。 YOLOv8 的 Neck包括 SPFF,一个 PAA module和两个 PAN module

image-20240526222938487

对应yaml中的参数

head:
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']] # 第10层,本层是上采样层。-1代表将上层的输出作为本层的输入。None代表上采样的size(输出尺寸)不指定。2代表scale_factor=2,表示输出的尺寸是输入尺寸的2倍。nearest代表使用的上采样算法为最近邻插值算法。经过这层之后,特征图的长和宽变成原来的两倍,通道数不变,所以最终尺寸为40*40*1024。
  - [[-1, 6], 1, Concat, [1]]  # cat backbone P4 第11层,本层是concat层,[-1, 6]代表将上层和第6层的输出作为本层的输入。[1]代表concat拼接的维度是1。从上面的分析可知,上层的输出尺寸是40*40*1024,第6层的输出是40*40*512,最终本层的输出尺寸为40*40*1536。
  - [-1, 3, C2f, [512]]  # 12 第12层,本层是C2f模块,可以参考第2层的讲解。3代表本层重复3次。512代表输出通道数。与Backbone中C2f不同的是,此处的C2f的bottleneck模块的shortcut=False。
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']] # 第13层,本层也是上采样层(参考第10层)。经过这层之后,特征图的长和宽变成原来的两倍,通道数不变,所以最终尺寸为80*80*512。
  - [[-1, 4], 1, Concat, [1]]  # cat backbone P3 第14层,本层是concat层,[-1, 4]代表将上层和第4层的输出作为本层的输入。[1]代表concat拼接的维度是1。从上面的分析可知,上层的输出尺寸是80*80*512,第6层的输出是80*80*256,最终本层的输出尺寸为80*80*768。
  - [-1, 3, C2f, [256]]  # 15 (P3/8-small) 第15层,本层是C2f模块,可以参考第2层的讲解。3代表本层重复3次。256代表输出通道数。经过这层之后,特征图尺寸变为80*80*256,特征图的长宽已经变成输入图像的1/8。
  - [-1, 1, Conv, [256, 3, 2]] # 第16层,进行卷积操作(256代表输出通道数,3代表卷积核大小k,2代表stride步长),输出特征图尺寸为40*40*256(卷积的参数都没变,所以都是长宽变成原来的1/2,和之前一样)。
  - [[-1, 12], 1, Concat, [1]]  # cat head P4 第17层,本层是concat层,[-1, 12]代表将上层和第12层的输出作为本层的输入。[1]代表concat拼接的维度是1。从上面的分析可知,上层的输出尺寸是40*40*256,第12层的输出是40*40*512,最终本层的输出尺寸为40*40*768。
  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium) 第18层,本层是C2f模块,可以参考第2层的讲解。3代表本层重复3次。512代表输出通道数。经过这层之后,特征图尺寸变为40*40*512,特征图的长宽已经变成输入图像的1/16。
  - [-1, 1, Conv, [512, 3, 2]] # 第19层,进行卷积操作(512代表输出通道数,3代表卷积核大小k,2代表stride步长),输出特征图尺寸为20*20*512(卷积的参数都没变,所以都是长宽变成原来的1/2,和之前一样)。
  - [[-1, 9], 1, Concat, [1]]  # cat head P5 第20层,本层是concat层,[-1, 9]代表将上层和第9层的输出作为本层的输入。[1]代表concat拼接的维度是1。从上面的分析可知,上层的输出尺寸是20*20*512,第9层的输出是20*20*1024,最终本层的输出尺寸为20*20*1536。
  - [-1, 3, C2f, [1024]]  # 21 (P5/32-large) 第21层,本层是C2f模块,可以参考第2层的讲解。3代表本层重复3次。1024代表输出通道数。经过这层之后,特征图尺寸变为20*20*1024,特征图的长宽已经变成输入图像的1/32。
  
  
  
  - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5) 第20层,本层是Detect层,[15, 18, 21]代表将第15、18、21层的输出(分别是80*80*256、40*40*512、20*20*1024)作为本层的输入。nc是数据集的类别数。

PAN-FAN结构

YOLOv8 的Neck部分采用了PAN-FAN结构,用于特征融合和增强。PAN(Path Aggregation Network)和 FAN(Feature Attention Network)是YOLOv8的特征金字塔网络的组成部分,分别实现特征聚合和特征注意力增强。

PAN(Path Aggregation Network)

PAN是用于目标检测模型中的一种特征金字塔网络结构,旨在通过多层特征的聚合来提升模型的检测性能。它的主要特点包括:

  • 自上而下和自下而上的路径:PAN同时采用了自上而下和自下而上的特征融合路径,自上而下路径有助于高层特征传播到低层,而自下而上的路径则将低层特征传播到高层。
  • 增强特征表示:通过特征图的多尺度融合,PAN可以有效地增强不同尺度目标的特征表示,从而提高模型的检测能力。

FAN(Feature Attention Network)

FAN主要用于对特征图进行注意力增强,强调重要特征并抑制不相关特征。它的主要特点包括:

  • 注意力机制:FAN通过通道注意力和空间注意力机制,对输入特征图进行加权,以增强关键特征。通道注意力机制关注特征图的不同通道,而空间注意力机制则关注特征图的不同空间位置。
  • 提升特征表达能力:通过注意力机制,FAN可以提升模型对目标区域的关注,提高检测精度。

处理流程

输入特征图:
  • P4 (来自Layer4): 80x80,通道数256
  • P6 (来自Layer6): 40x40,通道数512
  • P9 (来自Layer9, SPPF输出): 20x20,通道数1024
步骤 1: 特征图上采样与融合
  1. 上采样 P9:
    • P9 (20x20) 上采样2倍,得到40x40大小的特征图。
    • 将上采样后的特征图与P6 (40x40) 融合(逐元素相加),得到特征图F1 (40x40)。
  2. F1处理和上采样:
    • F1经过C2f模块处理后,上采样2倍,得到80x80大小的特征图。
    • 将上采样后的特征图与P4 (80x80) 融合(逐元素相加),得到特征图T1 (80x80)。
步骤 2: 自下而上路径融合
  1. 卷积和融合 T1 和 F1:
    • T1通过卷积操作后得到特征图,尺寸仍为80x80。
    • 将卷积后的特征图与F1 (40x40) 融合,得到特征图F2 (40x40)。
  2. F2处理:
    • F2经过C2f模块处理,得到特征图T2 (40x40)。
  3. 卷积和融合 T2 和 P9:
    • T2通过卷积操作后得到特征图,尺寸仍为40x40。
    • 将卷积后的特征图与P9 (20x20) 融合,得到特征图F3 (20x20)。
  4. F3处理:
    • F3经过C2f模块处理,得到特征图T3 (20x20)。
最终输出:
  • T1 (80x80)
  • T2 (40x40)
  • T3 (20x20)

这些特征图被送入Detect Head进行检测。

image-20240526230930012

Head

在YOLOv8中,Head部分负责将Neck部分输出的特征进行进一步处理,以生成最终的检测结果。Head部分的主要功能是将特征图转换为目标检测所需的具体信息,包括类别、位置和置信度。

结构

  1. 卷积层和激活函数
    • Head部分通常包括若干卷积层和激活函数。这些卷积层用于进一步处理Neck部分输出的特征图,以提取更多的高级特征。
    • 常见的激活函数包括ReLU或Leaky ReLU,能够引入非线性,从而提升特征表达能力。
  2. 预测层(Prediction Layers)
    • 在YOLOv8中,预测层是关键组件,负责生成最终的检测结果。预测层包括三个主要输出:
      1. 边界框回归(Bounding Box Regression):预测目标的位置和大小。通常输出四个值,分别对应边界框的中心坐标(x, y)和宽度、高度(w, h)。
      2. 置信度评分(Confidence Scores):预测每个边界框内是否包含目标,以及目标的置信度。
      3. 类别概率(Class Probabilities):预测目标属于每个类别的概率。
  3. 非极大值抑制(Non-Maximum Suppression, NMS)
    • 最终的预测结果会经过非极大值抑制处理,以去除重复的检测框。NMS保留置信度最高的边界框,并移除与之重叠度高的其他边界框,确保每个目标只被检测一次。

image-20240526231759835

对应的yaml配置参数

  - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5) 第20层,本层是Detect层,[15, 18, 21]代表将第15、18、21层的输出(分别是80*80*256、40*40*512、20*20*1024)作为本层的输入。nc是数据集的类别数。

配置[[15, 18, 21], 1, Detect, [nc]]

  • [15, 18, 21]:表示输入特征层来自于编号15、18和21的C2f块输出。
  • 1:表示有一个Detect模块(一个检测头)。
  • Detect:表示这是一个检测层,用于预测类别和边界框。
  • [nc]:表示类别数量,即要预测的目标类别数。
  1. 第一个Detect块

    • 功能:专门用于检测大型物体。
    • 输入来源:来自第15号节点的C2f块的输出,80 x 80 大小的特征图。
  2. 第二个Detect块

    • 功能:专门用于检测中型物体。
    • 输入来源:来自第18号节点的C2f块的输出,40 x 40 大小的特征图。
  3. 第三个Detect块

    • 功能:专门用于检测小型物体。
    • 输入来源:来自第21号节点的C2f块的输出,20 x 20 大小的特征图。

image-20240526231726273


在这里插入图片描述

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

YOLO大王

你的打赏,我的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值