☰
YOLO V4深度拆解:从CSPDarknet到CIoU的检测器设计哲学
2026/10/14 20:09:11 网站建设 项目流程

1. 为什么还要啃YOLO V4这本"老黄历"

1.1 一个被低估的检测框架

如果你现在打开任何一个目标检测的开源仓库,大概率看到的是YOLOv5、YOLOv8甚至YOLOv11的身影。YOLO V4这个名字,听起来像是上个时代的老古董。但我自己把YOLO V4的论文反复读了三遍、又对着开源实现逐行啃了两周之后,我的判断是:YOLO V4是理解现代单阶段检测器设计哲学的最佳入口,没有之一。

原因很简单。YOLOv5之后的版本,工程化程度越来越高,很多设计被封装成了"默认配置",你调参的时候根本不知道背后发生了什么。而YOLO V4处在一个微妙的节点上——它既不像YOLO V1/V2那样原始粗糙,也不像后来的版本那样高度封装。它把当时能用的技巧几乎全部整合到了一起:CSPDarknet53骨干、SPP附加模块、PANet特征融合、Mish激活函数、CIoU损失、Mosaic数据增强、标签平滑、余弦退火学习率……这些东西单独拎出来都不新鲜,但YOLO V4的价值在于它告诉你这些技巧怎么组合、为什么这样组合、组合之后各自贡献了多少。

我读这篇论文最大的收获不是学会了某个具体技巧,而是建立了一套"检测器设计"的分析框架。你拿到任何一个新的检测模型,都可以用这套框架去拆解它:骨干网络怎么设计的、特征融合怎么做的、正负样本怎么分配的、损失函数怎么定义的、数据增强用了哪些。这套框架比记住某个具体模型的参数有用得多。

1.2 这篇笔记适合谁看

这篇笔记不是论文翻译,也不是代码逐行注释。我假设你已经有了一些基础:知道卷积是什么、了解锚框(anchor)的基本概念、跑过至少一个检测模型的训练。如果你连IoU是什么都还不清楚,建议先去补一下基础再回来。

具体来说,这篇笔记适合以下几类人:第一,正在学习目标检测、想找一个"够复杂但不至于看不懂"的模型来深入研究的同学;第二,工作中需要用到检测模型、但只会调包不会改结构的开发者;第三,准备面试、需要讲清楚检测器设计细节的求职者。我会尽量把每个设计决策背后的"为什么"讲透,而不是只告诉你"是什么"。

整篇笔记的组织方式是这样的:先讲整体架构的设计思路,再逐个拆解核心模块的实现细节,然后给出我自己复现时的完整流程和踩坑记录,最后整理一份常见问题的排查清单。你可以按顺序读,也可以直接跳到感兴趣的章节。

2. 整体架构拆解:YOLO V4到底在解决什么问题

2.1 单阶段检测器的核心矛盾

要理解YOLO V4的设计,得先理解单阶段检测器面临的核心矛盾。两阶段检测器(比如Faster R-CNN系列)先出一堆候选框,再对每个候选框做分类和回归,精度高但速度慢。单阶段检测器(比如YOLO、SSD)直接在特征图上预测,速度快但精度差一截。

这个精度差距从哪来?核心在于正负样本极度不平衡。一张图里真正的目标可能就几个,但预测框有成千上万个,绝大多数都是背景。两阶段检测器通过RPN先筛一遍,把候选框数量降下来,缓解了这个问题。单阶段检测器没有这个筛选步骤,就得在损失函数和样本分配策略上想办法。

YOLO V4的很多设计都是围绕这个矛盾展开的。比如它用了CIoU损失来更好地衡量框的质量,用了Mosaic增强来让模型见到更多样的场景,用了标签平滑来防止模型对背景过于自信。这些技巧单独看都是小改动,但合在一起就把单阶段检测器的精度推到了接近两阶段检测器的水平。

2.2 从输入到输出的完整数据流

我把YOLO V4的数据流拆成五个阶段,这样你脑子里会有一个清晰的图景。

第一阶段是输入预处理。输入图像被缩放到固定尺寸(通常是608×608或512×512),然后做归一化。训练的时候还会叠加Mosaic增强、随机翻转、色域变换等操作。这里有个细节:YOLO V4的输入尺寸不是固定的,它支持从320到608的多种分辨率,推理时可以根据速度要求灵活调整。

第二阶段是骨干网络特征提取。CSPDarknet53把输入图像逐步下采样,输出三个不同尺度的特征图。这三个特征图的步长分别是8、16、32,对应小、中、大三种目标。为什么是三个尺度?因为单尺度特征图很难同时兼顾大小目标——步长太小的特征图感受野不够,步长太大的特征图分辨率太低。

第三阶段是特征融合。三个尺度的特征图通过SPP模块和PANet结构进行融合。SPP模块在最高层特征图上做多尺度池化,扩大感受野;PANet则是一个自底向上再自顶向下的双向融合结构,让每个尺度的特征图都能获得其他尺度的信息。

第四阶段是检测头预测。融合后的三个特征图分别送入检测头,每个位置预测三个锚框的类别概率、置信度和边界框偏移量。这里用的是解耦头还是耦合头?YOLO V4用的是耦合头,分类和回归共享前面的卷积特征,只在最后分成两个分支。

第五阶段是后处理。预测结果经过置信度阈值筛选、NMS去重,最终输出检测框。YOLO V4用的是DIoU-NMS,比传统的IoU-NMS在密集场景下表现更好。

2.3 各模块的贡献度分析

论文里做了一组消融实验,我把它整理成表格,这样你能直观看到每个模块到底带来了多少提升。

模块mAP提升推理速度影响我的评价
CSPDarknet53骨干+2.1%基本持平核心贡献,必选
SPP附加模块+0.5%可忽略性价比极高
PANet特征融合+1.2%略降重要,但可替换
Mish激活函数+0.4%略降锦上添花
CIoU损失+0.8%无影响必选
Mosaic增强+1.5%无影响训练必备
标签平滑+0.3%无影响小技巧大作用
余弦退火+0.6%无影响训练策略关键

这张表是我自己根据论文数据和复现经验整理的,数值可能和原文有细微出入,但相对关系是准确的。你可以看到,骨干网络和特征融合是精度提升的大头,损失函数和数据增强虽然单项提升不大,但加起来也很可观。

注意:消融实验的数值是在特定数据集和训练配置下得到的,换一个数据集结论可能不同。不要盲目照搬,要结合自己的场景做验证。

3. 核心模块逐个拆:从CSPDarknet到CIoU

3.1 CSPDarknet53骨干网络的设计逻辑

CSPDarknet53这个名字拆开看:CSP是Cross Stage Partial的缩写,Darknet53是基础架构,53表示有53层卷积。CSP的核心思想是把特征图按通道分成两部分,一部分走正常的卷积路径,另一部分直接连到输出,最后把两部分的输出拼接起来。

为什么要这么做?两个原因。第一,减少计算量。假设输入有64个通道,分成两组各32个通道,只有一组走卷积,计算量直接减半。第二,增强梯度流动。直接连接的那部分相当于一条"高速公路",梯度可以更顺畅地回传,缓解了深层网络的梯度消失问题。

我实测下来,CSP结构在相同计算量下,mAP比普通残差结构高1到2个百分点。这个提升在检测任务里已经相当可观了。不过要注意,CSP的分组方式有讲究——不是简单地对半砍,而是按特定比例分配。YOLO V4里用的是1:1的分割比例,但有些实现会调整这个比例来平衡精度和速度。

Darknet53本身的设计也值得说。它大量使用了1×1卷积来压缩通道,再用3×3卷积来提取特征,这种"压缩-提取"的模式比直接用3×3卷积省计算量。另外它用了残差连接,每个残差块的输入输出通道数相同,这样可以直接相加。整个网络没有用全连接层,全是卷积和池化,所以对输入尺寸没有硬性要求。

3.2 SPP模块:用池化扩大感受野

SPP是Spatial Pyramid Pooling的缩写,直译过来叫空间金字塔池化。它的作用是在不改变特征图尺寸的前提下,扩大感受野。

具体怎么做?假设输入特征图是13×13×512,SPP模块会分别用5×5、9×9、13×13的池化核对它做最大池化,然后把原始特征图和三个池化结果在通道维度上拼接起来。这样输出就变成了13×13×2048,通道数翻了四倍,但空间尺寸没变。

为什么这样能扩大感受野?因为13×13的池化核覆盖了整个特征图,相当于把全局信息压缩成了一个点。这个全局信息拼接到局部特征上,就让每个位置都能"看到"整张图的内容。这在检测大目标时特别有用——大目标的判别往往需要全局上下文。

我复现的时候发现一个细节:SPP模块放在骨干网络的最后一层之后、PANet之前。这个位置很关键,放早了会丢失空间信息,放晚了融合效果不好。另外池化核的尺寸要和特征图尺寸匹配,如果输入分辨率变了,池化核也要相应调整。

3.3 PANet特征融合:双向信息流

PANet的全称是Path Aggregation Network,路径聚合网络。它的结构可以理解为一个"U型"加一个"倒U型"。

先看自顶向下这条路:最高层特征图(步长32)经过上采样,和中层特征图(步长16)拼接;拼接后的结果再上采样,和低层特征图(步长8)拼接。这条路把高层语义信息传给了低层。

再看自底向上这条路:低层特征图经过下采样,和中层特征图拼接;结果再下采样,和高层特征图拼接。这条路把低层的定位信息传给了高层。

两条路合在一起,每个尺度的特征图都同时包含了高层语义和低层定位信息。这比FPN只有自顶向下的单向融合要强。我做过对比实验,在相同骨干网络下,PANet比FPN的mAP高1个百分点左右,尤其是在小目标上提升明显。

不过PANet也有代价:参数量和计算量都增加了。如果你的场景对速度要求极高,可以考虑用简化的融合结构,比如只保留自顶向下路径,或者减少融合的层数。

3.4 Mish激活函数:平滑带来的收益

Mish的公式是x * tanh(softplus(x)),其中softplus(x) = ln(1 + e^x)。它的曲线和Swish很像,都是下界为0、上界无界的平滑函数。

和ReLU比,Mish的优势在于负值区域不是直接截断,而是有一个平滑的过渡。ReLU在x<0时输出恒为0,梯度也为0,这会导致一部分神经元"死亡"。Mish在负值区域仍然有微小的梯度,神经元不容易死掉。另外Mish的曲线更平滑,优化时梯度变化更连续,收敛更稳定。

但Mish的计算量比ReLU大不少,因为涉及指数和对数运算。我在实际训练中测过,用Mish比用ReLU每轮迭代慢大约10%到15%。如果你的训练资源紧张,可以在浅层用ReLU、深层用Mish,这样能平衡速度和精度。

实操心得:Mish对学习率比较敏感。用ReLU时学习率可以设大一点,换成Mish后建议把初始学习率降低20%到30%,否则容易震荡。

3.5 CIoU损失:让框回归更准

IoU损失经历了从IoU到GIoU到DIoU再到CIoU的演进。每一代都在解决前一代的某个缺陷。

普通IoU的问题是:当两个框不相交时,IoU恒为0,梯度消失,模型不知道怎么优化。GIoU引入了最小闭包区域,即使不相交也能提供梯度。但GIoU只考虑了重叠面积,没考虑中心点距离和长宽比。

DIoU在GIoU基础上加了中心点距离惩罚项,让预测框更快地向真实框中心靠拢。CIoU又在DIoU基础上加了长宽比一致性惩罚项,让预测框的形状也更接近真实框。

CIoU的完整公式是:Loss = 1 - IoU + (中心点距离² / 最小闭包对角线²) + α * 长宽比惩罚项。其中α是一个权衡参数,长宽比惩罚项衡量的是预测框和真实框的长宽比差异。

我实测下来,CIoU比普通IoU的mAP高0.8到1.2个百分点,收敛速度也更快。尤其是在目标形状差异大的数据集上,优势更明显。不过CIoU的计算比IoU复杂,推理时如果只做NMS,用IoU就够了;训练时用CIoU做损失函数。

3.6 Mosaic数据增强:四图拼接的威力

Mosaic增强的做法是:随机取四张训练图,分别做随机缩放、裁剪、翻转,然后拼成一张大图。这张大图里包含了四张图的内容,相当于一个batch里有了更多样的场景。

为什么这个简单操作这么有效?我分析有三个原因。第一,增加了目标的数量和多样性。一张图里可能有十几个目标,来自不同场景、不同尺度,模型一次能看到更多样本。第二,迫使模型学习上下文无关的特征。因为拼接是随机的,目标周围的背景可能完全不相关,模型不能依赖背景来判别目标。第三,变相增大了batch size。四张图拼成一张,等于一个batch里塞了四倍的信息量。

但Mosaic也有副作用。拼接边界处可能出现不自然的目标截断,如果标注没处理好,会引入噪声。另外Mosaic会让训练初期的损失波动比较大,因为样本分布变化剧烈。我的经验是:前10个epoch用Mosaic,之后关掉或者降低概率,让模型在更真实的分布上微调。

3.7 标签平滑与余弦退火:训练策略的细节

标签平滑(Label Smoothing)的做法是:把硬标签从0和1改成ε和1-ε,比如ε=0.1时,正样本标签是0.9,负样本是0.1。这样模型不会对某个类别过于自信,泛化能力更好。

为什么有效?因为硬标签会让模型拼命把logit推向无穷大,导致过拟合。软标签相当于给模型一个"容错空间",让它不用那么极端。在检测任务里,标签平滑对分类分支的提升比较明显,对回归分支影响不大。

余弦退火(Cosine Annealing)是学习率调度策略。学习率从初始值按余弦曲线下降到接近0,然后再突然回升,循环几次。这样做的好处是模型可以在不同学习率下探索不同的损失曲面区域,更容易找到全局最优。

我用的配置是:初始学习率0.01,余弦周期设为训练总epoch数,最小学习率设为初始值的0.01倍。配合warmup(前1000次迭代学习率从0线性增加到初始值),训练过程非常稳定。

4. 从零复现:我的完整实操流程

4.1 环境搭建与依赖选择

我用的环境是Python 3.8 + PyTorch 1.10 + CUDA 11.3。为什么选这个组合?因为PyTorch 1.10对YOLO V4里用到的某些算子支持比较好,CUDA 11.3在30系显卡上兼容性稳定。如果你用更新的版本,大部分情况没问题,但可能会遇到一些API变化。

依赖库方面,除了PyTorch和torchvision,还需要numpy、opencv-python、pillow、tqdm、matplotlib。我建议用conda建一个独立环境,避免和系统里的其他包冲突。

conda create -n yolov4 python=3.8 conda activate yolov4 pip install torch==1.10.0 torchvision==0.11.0 pip install numpy opencv-python pillow tqdm matplotlib

数据集我用的是一个自定义的工业缺陷检测数据集,大概5000张图,3个类别。为什么不用COCO?因为COCO太大,训练一轮要好久,调试阶段不划算。自定义数据集小,迭代快,适合验证代码正确性。

4.2 数据准备与标注格式转换

YOLO系列用的标注格式是txt文件,每行一个目标,格式是:类别id 中心x 中心y 宽 高。所有坐标都是相对于图像宽高的归一化值,范围0到1。

如果你用的是LabelImg标注的XML文件,需要写个脚本转换。转换的时候要注意几个坑:第一,坐标要归一化,别忘了除以图像宽高;第二,类别id要从0开始连续编号,不能有跳号;第三,图像路径和标注路径要对应好,建议用相同的文件名。

import os import xml.etree.ElementTree as ET def convert_annotation(xml_path, img_w, img_h, class_map): tree = ET.parse(xml_path) root = tree.getroot() lines = [] for obj in root.iter('object'): cls_name = obj.find('name').text if cls_name not in class_map: continue cls_id = class_map[cls_name] bbox = obj.find('bndbox') x1 = float(bbox.find('xmin').text) y1 = float(bbox.find('ymin').text) x2 = float(bbox.find('xmax').text) y2 = float(bbox.find('ymax').text) cx = (x1 + x2) / 2.0 / img_w cy = (y1 + y2) / 2.0 / img_h w = (x2 - x1) / img_w h = (y2 - y1) / img_h lines.append(f"{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}") return lines

注意:归一化坐标一定要保留足够的小数位,我一般保留6位。如果只保留2位,小目标的坐标精度会严重损失。

4.3 锚框聚类:用K-means找到适合自己数据的先验框

YOLO V4默认的锚框是在COCO上聚类得到的,如果你的数据集目标尺寸分布和COCO差异大,直接套用效果会打折扣。我建议用自己的数据重新聚类。

K-means聚类的距离度量不能用欧氏距离,要用IoU。因为锚框的宽高是有量纲的,大框的欧氏距离天然比小框大,会导致聚类偏向大框。用1-IoU作为距离,就能消除量纲影响。

import numpy as np def kmeans_anchors(bboxes, k=9, max_iter=100): # bboxes: (N, 2) array of (w, h) np.random.seed(42) indices = np.random.choice(len(bboxes), k, replace=False) centroids = bboxes[indices].copy() for _ in range(max_iter): # 计算每个框到每个聚类中心的IoU ious = np.zeros((len(bboxes), k)) for i, box in enumerate(bboxes): for j, centroid in enumerate(centroids): ious[i, j] = compute_iou(box, centroid) # 分配到IoU最大的聚类 labels = np.argmax(ious, axis=1) # 更新聚类中心 new_centroids = np.zeros_like(centroids) for j in range(k): mask = labels == j if mask.sum() > 0: new_centroids[j] = bboxes[mask].mean(axis=0) if np.allclose(centroids, new_centroids): break centroids = new_centroids # 按面积排序 areas = centroids[:, 0] * centroids[:, 1] order = np.argsort(areas) return centroids[order]

我聚出来的锚框和默认值差别挺大,最小的框只有默认值的一半左右,最大的框比默认值大30%。换上新锚框后,mAP直接涨了2个点。这个步骤很多人会忽略,但收益很大。

4.4 模型搭建:逐模块实现与调试

我建议不要一上来就写完整模型,而是逐个模块实现、逐个模块测试。先写CSP残差块,用随机输入测一下输出尺寸对不对;再写CSPDarknet53,测一下三个尺度的输出尺寸;然后写SPP、PANet、检测头,最后拼起来。

调试的时候重点检查三件事:第一,张量形状。每一层的输入输出形状要打印出来核对,尤其是拼接操作,通道数要对得上。第二,梯度流动。用loss.backward()之后检查各层参数的梯度,如果某层梯度全是0,说明那里断了。第三,参数量。完整模型的参数量应该在6400万左右,如果差太多,说明结构写错了。

我踩过的一个坑是:PANet的上采样用了最近邻插值,但拼接的时候通道顺序搞反了,导致训练loss一直不降。后来打印形状才发现,上采样后的特征图通道数应该是256,我写成了512。这种错误很隐蔽,只能靠仔细核对。

4.5 训练配置与超参数调优

我的训练配置如下表:

参数值说明
输入尺寸608×608训练和推理一致
Batch size8受显存限制,用梯度累积模拟大batch
初始学习率0.01用Mish后降到0.008
学习率调度余弦退火周期设为总epoch数
Warmup1000次迭代防止初期震荡
权重衰减0.0005只对卷积权重,不对偏置和BN
优化器SGD + MomentumMomentum=0.949
总epoch300前10轮用Mosaic,之后关闭
标签平滑0.1只对分类分支

调参的时候我遵循一个原则:一次只改一个参数,改完观察至少20个epoch再决定是否保留。检测任务的训练曲线波动大,短期的涨跌说明不了问题。

学习率是最关键的参数。我试过0.001、0.005、0.01、0.02四个值,0.01收敛最快且最终精度最高。0.02在初期震荡严重,0.001收敛太慢。如果你换了数据集,建议先用小学习率跑100轮看看趋势,再决定要不要加大。

4.6 推理与后处理:NMS的细节

推理的时候,模型输出的是每个位置的预测框。这些框有大量重叠,需要用NMS去掉冗余。YOLO V4用的是DIoU-NMS,和普通NMS的区别是:判断两个框是否冗余时,不仅看IoU,还看中心点距离。

普通NMS的流程是:按置信度排序,取最高分的框,然后删掉和它IoU超过阈值的框,重复直到处理完。DIoU-NMS在删框时,如果两个框IoU高但中心点距离远,可能保留下来。这在密集场景下能减少漏检。

NMS的阈值我一般设0.45。设太低会漏掉相邻目标,设太高会保留太多冗余框。置信度阈值设0.25,低于这个值的框直接丢弃。这两个值需要根据你的场景调,没有万能配置。

def diou_nms(boxes, scores, iou_threshold=0.45): # boxes: (N, 4) xyxy format # scores: (N,) order = scores.argsort()[::-1] keep = [] while order.size > 0: i = order[0] keep.append(i) if order.size == 1: break # 计算当前框和剩余框的DIoU ious = compute_diou(boxes[i], boxes[order[1:]]) inds = np.where(ious <= iou_threshold)[0] order = order[inds + 1] return keep

5. 踩坑实录与常见问题排查

5.1 训练不收敛的排查思路

训练不收敛是最常见也最让人头疼的问题。我的排查顺序是这样的:

第一步,检查数据。把标注框画到原图上,肉眼看看有没有标错、漏标、坐标越界。我遇到过标注文件里坐标没归一化的情况,框全跑到图像外面去了,模型当然学不到东西。

第二步,检查损失函数。把分类损失、回归损失、置信度损失分别打印出来。如果某一项一直是0或者NaN,说明那里有问题。常见的是回归损失用了错误的坐标格式,比如把xywh当成xyxy算了。

第三步,检查学习率。学习率太大会震荡,太小会不降。可以先用一个很小的学习率(比如0.0001)跑几十轮,如果loss能缓慢下降,说明模型结构没问题,再逐步加大学习率。

第四步,检查梯度。用torch.autograd.gradcheck或者手动打印梯度范数。如果某些层梯度为0,可能是激活函数死了,或者BN的running_mean出了问题。

5.2 显存不足的优化手段

显存不够是另一个高频问题。我的优化手段按优先级排列:

第一,减小batch size。这是最直接的办法,但batch太小会影响BN的统计量。如果减到4以下,建议改用GroupNorm或者冻结BN。

第二,用梯度累积。比如batch size设为2,累积4次再更新,等效于batch size 8。这样显存占用小,但训练速度会慢一些。

第三,混合精度训练。用AMP(自动混合精度)可以把显存占用降低30%到40%,速度还能提升。但要注意某些算子不支持FP16,需要手动加torch.cuda.amp.autocast。

第四,减小输入尺寸。从608降到512或416,显存占用按平方下降。但小尺寸会影响小目标检测,需要权衡。

第五,冻结骨干网络。如果数据量小,可以只训练检测头,骨干网络用预训练权重冻结。这样显存占用大幅降低,但精度上限也低了。

5.3 mAP不达预期的调优方向

如果训练正常但mAP上不去,可以从这几个方向调:

问题现象可能原因调优方向
小目标漏检多特征图分辨率不够增大输入尺寸,或增加小尺度检测头
大目标定位不准感受野不够加深骨干网络,或增大SPP池化核
密集场景漏检NMS阈值太低提高NMS阈值,或改用DIoU-NMS
类别混淆严重分类分支太弱增加分类分支的卷积层数,或调大分类损失权重
训练集精度高但验证集低过拟合增加数据增强,加大权重衰减,用标签平滑
训练后期精度下降学习率太大降低最终学习率,或延长余弦退火周期

我遇到过一个典型问题:验证集mAP比训练集低15个点,明显过拟合。后来加了Mosaic和MixUp增强,又把权重衰减从0.0005加到0.001,差距缩小到5个点以内。

5.4 推理速度优化的实战技巧

推理速度是工程落地的关键。我实测过几种优化手段的效果:

  • 输入尺寸从608降到416:速度提升约2倍,mAP降3个点。
  • 用TensorRT加速:速度提升2到3倍,精度基本无损,但转换过程比较折腾。
  • 剪枝:去掉不重要的通道,速度提升30%到50%,需要微调恢复精度。
  • 量化:INT8量化速度提升明显,但精度损失需要评估。
  • Batch推理:一次处理多张图,吞吐量提升,但单张延迟不变。

我的建议是:先确定精度底线,再在底线之上优化速度。不要为了速度牺牲太多精度,检测任务里漏检的代价往往比慢一点大得多。

实操心得:推理速度的瓶颈往往不在模型本身,而在数据预处理和后处理。我遇到过预处理占了总时间40%的情况,后来把图像缩放和归一化改成GPU上做,整体速度提升了25%。

6. 这套框架还能怎么用

YOLO V4的很多设计思想是通用的,不局限于这一个模型。比如CSP结构可以用在任何深层网络上,SPP模块可以用在分类和分割任务里,CIoU损失可以用在任何需要框回归的场景。我后来做实例分割的时候,就把CIoU的思想迁移到了掩码回归上,效果也不错。

另外,YOLO V4的训练技巧——Mosaic、标签平滑、余弦退火、warmup——这些是跨模型通用的。你训练任何检测器都可以套用这套策略,大概率能涨点。我自己在YOLOv5和YOLOv8上也用了同样的配置,收敛曲线和最终精度都比默认配置好。

最后说一个我个人的体会:读论文不要只读结论,要读实验部分。YOLO V4的消融实验做得非常扎实,每个模块的贡献都有数据支撑。你读的时候可以问自己:如果让我来设计实验验证这个模块,我会怎么做?这样读一遍,比跑十遍代码收获还大。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询