Ultralytics YOLOv5 架构#
YOLOv5(v6.0/6.1)是由 Ultralytics 开发的一种强大的目标检测算法。本文将深入探讨 YOLOv5 架构、数据增强策略、训练方法和损失计算技术。全面理解这些内容将有助于你提升目标检测在监控、自动驾驶车辆和图像识别等不同领域中的实际应用。
1. 模型结构#
YOLOv5 的架构由三个主要部分组成:
- 主干网络:这是网络的主体。对于 YOLOv5,主干网络采用
CSPDarknet53结构设计,这是对早期版本所使用的 Darknet 架构的改进。 - 颈部网络:该部分连接主干网络和检测头。在 YOLOv5 中,采用了
SPPF(空间金字塔池化 - 快速)和PANet(路径聚合网络)结构。 - 检测头:该部分负责生成最终输出。YOLOv5 使用
YOLOv3 Head来完成此任务。
模型结构如下图所示。你可以在 models/yolov5l.yaml 中查看模型结构的详细信息。

与前代版本相比,YOLOv5 引入了一些显著改进:
- 早期版本中的
Focus结构被6x6 Conv2d结构取代。这一变化提升了效率 #4825。 SPP结构被SPPF取代。这一改动使处理速度提升了一倍以上,同时保持相同的输出。
可以使用以下代码测试 SPP 和 SPPF 的速度:
SPP vs SPPF speed profiling example (click to open)
import time
import torch
from torch import nn
class SPP(nn.Module):
def __init__(self):
"""Initializes an SPP module with three different sizes of max pooling layers."""
super().__init__()
self.maxpool1 = nn.MaxPool2d(5, 1, padding=2)
self.maxpool2 = nn.MaxPool2d(9, 1, padding=4)
self.maxpool3 = nn.MaxPool2d(13, 1, padding=6)
def forward(self, x):
"""Applies three max pooling layers on input `x` and concatenates results along channel dimension."""
o1 = self.maxpool1(x)
o2 = self.maxpool2(x)
o3 = self.maxpool3(x)
return torch.cat([x, o1, o2, o3], dim=1)
class SPPF(nn.Module):
def __init__(self):
"""Initializes an SPPF module with a specific configuration of MaxPool2d layer."""
super().__init__()
self.maxpool = nn.MaxPool2d(5, 1, padding=2)
def forward(self, x):
"""Applies sequential max pooling and concatenates results with input tensor."""
o1 = self.maxpool(x)
o2 = self.maxpool(o1)
o3 = self.maxpool(o2)
return torch.cat([x, o1, o2, o3], dim=1)
def main():
"""Compares outputs and performance of SPP and SPPF on a random tensor (8, 32, 16, 16)."""
input_tensor = torch.rand(8, 32, 16, 16)
spp = SPP()
sppf = SPPF()
output1 = spp(input_tensor)
output2 = sppf(input_tensor)
print(torch.equal(output1, output2))
t_start = time.time()
for _ in range(100):
spp(input_tensor)
print(f"SPP time: {time.time() - t_start}")
t_start = time.time()
for _ in range(100):
sppf(input_tensor)
print(f"SPPF time: {time.time() - t_start}")
if __name__ == "__main__":
main()结果:
True
SPP time: 0.5373051166534424
SPPF time: 0.207807064056396482. 数据增强技术#
YOLOv5 采用多种数据增强技术,以提升模型的泛化能力并减少过拟合。这些技术包括:
-
马赛克增强:一种图像处理技术,将四张训练图像合并为一张,从而帮助目标检测模型更好地处理不同的目标尺度和位移。

-
复制粘贴增强:一种创新的数据增强方法,从一张图像中复制随机图像块,并将其粘贴到另一张随机选择的图像上,从而有效生成新的训练样本。

-
随机仿射变换:包括对图像进行随机旋转、缩放、平移和错切。

-
MixUp 增强:通过对两张图像及其对应标签进行线性组合来创建合成图像的方法。

-
Albumentations:一个功能强大的图像增强库,支持多种数据增强技术。详细了解如何使用 Albumentations 增强。
-
HSV 增强:随机改变图像的色调、饱和度和值。

-
随机水平翻转:一种随机水平翻转图像的数据增强方法。

3. 训练策略#
YOLOv5 采用多种先进的训练策略来提升模型性能,包括:
- 多尺度训练:在训练过程中,输入图像会在其原始尺寸的 0.5 至 1.5 倍范围内随机缩放。
- AutoAnchor:该策略会优化先验锚框,使其匹配你自定义数据中真实框的统计特征。
- 预热和余弦学习率调度器:一种调整学习率以提升模型性能的方法。
- 指数移动平均(EMA):通过使用过去步骤中的参数平均值来稳定训练过程并减少泛化误差的策略。
- 混合精度训练:以半精度格式执行运算,从而减少内存使用并提升计算速度的方法。
- 超参数演化:自动调节超参数以实现最佳性能的策略。详细了解超参数调优。
4. 其他功能#
4.1 计算损失#
YOLOv5 中的损失由三个独立的损失组件组合计算得出:
- 类别损失(BCE Loss):二元交叉熵损失,用于衡量分类任务中的误差。
- 目标置信度损失(BCE Loss):另一种二元交叉熵损失,用于计算检测特定网格单元中是否存在目标时产生的误差。
- 位置损失(CIoU Loss):完整 IoU 损失,用于衡量在网格单元中定位目标时产生的误差。
整体损失函数如下图所示:
4.2 平衡损失#
三个预测层(P3、P4、P5)的目标置信度损失采用不同的权重。平衡权重分别为 [4.0, 1.0, 0.4]。这种方法确保不同尺度的预测以适当的方式贡献到总损失中。
4.3 消除网格敏感性#
与早期 YOLO 版本相比,YOLOv5 架构对边界框预测策略进行了一些重要改动。在 YOLOv2 和 YOLOv3 中,边界框坐标是通过最后一层的激活值直接预测的。
然而,在 YOLOv5 中,边界框坐标的预测公式经过更新,以降低网格敏感性,并防止模型预测无界的边界框尺寸。
计算预测边界框所使用的修订公式如下:
比较缩放前后的中心点偏移。中心点偏移范围从 (0, 1) 调整为 (-0.5, 1.5)。因此,偏移量可以轻松达到 0 或 1。
比较调整前后相对于锚框的高度和宽度缩放比例。原始的 yolo/darknet 边界框公式存在严重缺陷。由于宽度和高度只是 out=exp(in),因此完全没有界限;这很危险,因为它可能导致梯度失控、训练不稳定、NaN 损失,并最终导致训练完全失败。更多详情请参阅此问题。
4.4 构建目标#
YOLOv5 中的目标构建过程对于训练效率和模型准确率至关重要。该过程包括将真实框分配给输出图中的适当网格单元,并将其与适当的锚框进行匹配。
该过程遵循以下步骤:
- 计算真实框尺寸与每个锚框模板尺寸的比率。
- 如果计算出的比率在阈值范围内,则将真实框与对应的锚框进行匹配。
- 将匹配的锚框分配给适当的单元格。需要注意的是,由于修订后的中心点偏移,真实框可以分配给多个锚框,因为中心点偏移范围已从 (0, 1) 调整为 (-0.5, 1.5),从而支持额外的匹配。
通过这种方式,目标构建过程确保每个真实目标在训练过程中都能得到正确分配和匹配,使 YOLOv5 能够更有效地学习目标检测任务。
结论#
YOLOv5 是实时目标检测发展过程中的重要一步。相较于早期 YOLO 版本,其架构选择、训练策略和工程改进带来了出色的性能和效率。
YOLOv5 的主要改进包括采用动态架构、丰富的数据增强技术、创新的训练策略,以及对损失计算和目标构建过程进行重要调整。所有这些创新都在保持 YOLO 模型标志性高速特性的同时,显著提升了目标检测的准确率和效率。