要聊 YOLO-Master 这个系列,先得把 YOLO 这件事儿的底层逻辑说透。你可能已经搜过一堆资料,看到的是各种碎片:有人给你讲损失函数,有人给你贴网络结构图,还有人在一个视频里把 YOLOv1 讲到 YOLOv8,每个原理都提一嘴,但每个都讲不透。这就像学做饭,菜谱堆了一桌子,你还是不知道该先热锅还是先切菜。我说的 YOLO-Master,不是某个特定的开源库或者某个收费平台,而是一套完整的、从原理到落地的 YOLO 目标检测项目实战路线。你把它当成我这些年踩坑之后整理出来的一份地图就行,从理论认知、代码实现、模型训练、性能调优到边缘端部署,一条线捋下来。
我见过太多人卡在同一个位置:数据集准备好了,代码也跑通了,可训练出来的模型就是框不准。一个检测框歪一点还好说,有时候明明一个物体就在那儿,它愣是给你漏检,还有时候连续帧里同一个目标它一会儿检测到一会儿检测不到。然后你就会陷入玄学式的调参循环,盲目改 batch size、随便调学习率,最后结果更差。这一篇,是我整个系列的起点,也是我建议所有正准备入坑 YOLO 或者已经在坑里挣扎的人,先静下心来读完的一篇。先把 YOLO 到底是什么、它的发展脉络和核心原理、以及一个标准项目里你必须懂的模型指标彻底搞明白,后面我们再逐个拆解部署、量化、剪枝那些进阶动作。至少按我带的团队经验,凡是上手前花两个小时把这一篇搞清楚的人,实际做项目时踩的坑能少一大半。
1. 从 YOLOv1 到 YOLOv8,YOLO 到底在“快”什么
1.1 YOLO 家族十五年的演进主线:实时性与精度的对抗
YOLO(You Only Look Once)这套算法家族,从 2016 年 Joseph Redmon 那篇著名的论文开始,到现在的 YOLOv8、YOLOv9,核心卖点十五年没变过:单次前向推理直接输出目标类别和位置。这句话听着很简单,但它和之前主流的 two-stage 检测算法(像 Faster R-CNN)有本质区别。two-stage 的思路是先在一张图上找出若干个“可能含有目标的区域”(Region Proposal),然后对每个区域再做一次分类和框回归,相当于先粗筛一遍,再精查一遍。YOLO 的 one-stage 思路则是直接把全图分成网格,每个网格负责预测若干个框,一次推理全部搞定,所以速度天然就快。
但“快”不是白来的,它付出的代价是早期版本对小目标和密集场景不太友好。YOLOv1 把图片分成 S×S 的网格,每个网格只预测两个框和相应的置信度,如果两个目标的中心点落进了同一个格子,模型就会“左右为难”。这就引出了一个重要认知:YOLO 的检测能力,本质上是在“牺牲一部分空间精度,换取时间效率”。到了 YOLOv2(YOLO9000)引入 anchor 机制和 Batch Normalization,YOLOv3 引入多尺度特征图(FPN 的概念),YOLOv5 在工程易用性上做足了文章,YOLOv8 则把 anchor-free(无锚框)的检测头变成了主流。你去看这些版本的演进,几乎没有一次是在堆参数量,而是每次都在解决“如何在保持速度的前提下,把目标框得更准”。
注意,这里说的 YOLOv4、YOLOv5 的“版本号”并不是官方正统发布,而是社区不同团队的做法。你想入行 YOLO,不用纠结哪个版本是“正版”,只需要记住一个事实:YOLOv5 和 YOLOv8 是当前工业落地和学术研究里最主流的两个分支,YOLOv5 胜在生态成熟、部署资料多,YOLOv8 胜在特性新、功能全(实例分割、姿态估计都整合进去了)。而我这套 YOLO-Master 系列实践,主要基于 YOLOv8 展开,但原理部分对老版本同样适用。
1.2 从“网格”到“特征图”:YOLO 眼里的世界
很多人学 YOLO 原理,一上来就被各种网络结构图吓住,CSPDarknet 是什么,SPPF 是什么,C2f 模块是什么。我建议你先别管这些模块的细节,但要死死咬住一个概念:YOLO 把一个输入图片,从输入到输出,实现的是“图片 → 张量 → 检测结果”的映射。怎么映射?靠卷积层不断下采样,把 640×640×3 的输入图片,变成 80×80×channel、40×40×channel、20×20×channel 的三张特征图。这三张特征图对应的语义是:80×80 的图,相当于把原图划分成 6400 个 8×8 像素的网格,负责检测小目标;40×40 的图,相当于 1600 个 16×16 像素的网格,负责检测中等目标;20×20 的图,相当于 400 个 32×32 像素的网格,负责检测大目标。
这就是为什么 YOLO 能“在同一张图里既检测远处的车,又检测近处的行人”的原因——多尺度特征图各司其职。用一句大白话来说,YOLO 并不是让模型“看”整张图,而是让模型在高、中、低三种“分辨率视角”下分别找目标。小目标在低分辨率视角下可能像素信息不够,所以专门给它一张高分辨率特征图;大目标在整张图里已经占了很多像素,在低分辨率特征图里也依然醒目。这种设计,是 YOLO 能兼顾速度和精度的核心秘密。
理解了网格,你就理解了检测头输出的是什么。YOLOv8 的每个网格(或者说每个位置)输出若干个参数:目标的类别概率、目标的框中心坐标(x, y)、框的宽高(w, h)。在训练阶段,标签会被处理成和输出张量同形状的“目标张量”,正样本是那些“负责”预测某个真实框的网格位置,负样本是不包含任何目标的网格位置。整个训练过程,本质上是在调整网络参数,让模型输出的张量尽量接近真实标注构造出来的目标张量。哪有什么玄学,就是一个回归加分类问题。
1.3 YOLO-Master 的定位:不是某个工具,而是一套学习地图
市面上你搜“YOLO-Master”,可能会看到某个开源项目的名字,也可能看到某些平台提供的“YOLO一键部署脚本”。我的建议是,别迷信任何“一键”工具。真正能让 YOLO 项目从实验走向生产的,是你看得懂代码、调得了参数、找得到问题。所以我说,YOLO-Master 更应该被理解成一套方法论:掌握原理、学会训练、精通调优、能部署到目标硬件(不管你是 RK3588 还是 Jeston,还是普通 PC 上的 QT 调用)。
我把这条路线拆成了若干个关键节点,后续每一个都会有专门的篇幅来深挖。这一篇相当于整个系列的地基,把 YOLO 的家族历史、检测机制、指标体系一次性讲透。你不必一次全记住,但遇到问题的时候,你要知道该回来看哪一节的哪一段。这就是为什么这篇叫“与 YOLO 开始”——它不是某个算法的名字,而是你正式进入 YOLO 世界的第一站。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 一个 YOLO 目标检测项目跑起来的完整链路
2.1 数据准备:标注、格式转换和数据集划分的讲究
不管你是做道路裂缝检测、滑坡识别、无人机航拍目标检测还是水表读数识别,YOLO 项目的第一个硬骨头永远是数据。YOLO 训练用的标注格式是每个 txt 文件对应一张图片,每一行代表一个目标框,格式是:
code复制class_id x_center y_center width height
注意,这四个坐标值全部是相对于图片宽高的比例值,取值在 0 到 1 之间。不是像素坐标!这是新人最容易搞错的地方。你要用 LabelImg、X-AnyLabeling 或者 Roboflow 这类工具标注,导出时选择 YOLO 格式就行。如果是从公开数据集下载,经常会有 VOC 格式(xml)或者 COCO 格式(json)的数据,你需要写个脚本做格式转换。我的建议是,无论你用什么工具生成数据集,最后一定要抽 5-10 张图,人工打开对应的 txt 文件算一遍坐标,确认没有“坐标超出边界”“类别 ID 错位”“图片和标注名字对不上”这三类低级错误。这类错误不会让训练直接报错,但会让模型精度莫名其妙地低,而且极难排查。
数据集的划分也很有讲究。标准做法是把数据按 8:1:1 或 9:0.5:0.5 分成训练集、验证集、测试集。训练集用于更新权重,验证集用于挑选最优模型和调整超参数,测试集用于最终评估模型的泛化能力。实操中我习惯强调一点:划分时要用脚本按“目录/文件名”随机打乱,而不是手动拖拽,否则很容易因为某些软件排序特性造成数据分布不随机。还有,如果你的数据集里某一类只有二三十张图,而其它类有几千张,模型很可能直接学“废”了。要么扩充该类的样本,要么采用类别权重的方式给稀有类更大的 loss 占比。这一点在后续的实战篇里会详细展开。
2.2 环境配置与组件选型:CUDA、PyTorch 与 YOLOv8 的版本匹配
在跑任何 YOLO 代码之前,先把环境这块硬骨头啃下来。我用的是 YOLOv8 的官方 Ultralytics 库,依赖 PyTorch 深度学习框架。环境配置的核心是版本匹配问题:PyTorch 的版本必须和 CUDA 驱动版本匹配,CUDA 驱动版本必须和显卡驱动版本匹配。新手如果在这上面乱试,会浪费掉半天时间。我给你一个可以直接落地的方案:
- 先看你的显卡型号。NVIDIA 显卡直接用
nvidia-smi命令查看右上角的 CUDA Version,那是你的驱动支持的最高版本。 - 去 PyTorch 官网选一个版本低于或等于这个 CUDA 版本的安装命令。比如驱动支持 CUDA 12.1,你就可以装
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121。 - 安装完在 Python 里跑
import torch; print(torch.cuda.is_available()),输出True就说明 GPU 可用。
如果你没有 NVIDIA 显卡,只有 CPU,也可以跑 YOLO,但训练速度会慢得让人怀疑人生。我自己试过用 CPU 训练一个中等规模的数据集,一个 epoch 要跑将近一小时,而用一张普通的 RTX 3060 只需要几分钟。所以,入门 YOLO,强烈建议至少搞一张带 CUDA 支持的 NVIDIA 显卡,哪怕是云服务器上也行,成本其实比你想的低得多。
2.3 训练命令里最容易被忽略的几个参数
YOLOv8 的训练入口是一个 model.train() 的调用,参数非常多。这里我不展开全部,只挑三个最容易反直觉的说。
第一个是 imgsz(输入图片尺寸)。默认是 640,直接决定了训练的分辨率。你如果做的是道路裂缝检测这种极小目标任务,640 可能不够,可以试试 1024 甚至 1280。注意,提高输入尺寸会让训练变慢,同时显存消耗剧增,但它往往是最粗暴有效的精度提升手段。
第二个是 batch。显存不够时很多人喜欢把 batch 调小,这没错,但 batch 太小(比如 2 或 4)会导致 Batch Normalization 层的统计量不稳定,训练收敛变慢。如果你只有 8GB 显存,一个比较省心的做法是开梯度累积:设置 batch=16, accumulate=4,相当于每 4 个 batch 才更新一次权重,但实际每个 step 只看 4 张图。这样既享受了大 batch 的稳定性,又避开了显存不足的尴尬。
第三个是 patience。这个参数控制 Early Stopping(早停)的耐心值,默认是 50,表示验证集指标连续 50 个 epoch 没变好就停止训练。这个值在数据量大的时候非常有用,可以帮你省时间。但我见过一个坑:数据集不大,模型一开始收敛很快,后来开始过拟合,验证集 mAP 卡在一个值上反复横跳,patience=50 硬是让它跑了 200 多个 epoch 才停。所以,我的经验是 patience 设在 30-50 之间比较合理,如果训练过程中明显看到验证集 mAP 不再上升,手动 Ctrl+C 停掉,然后回去加载最近一次最优权重,没必要傻等。
3. 训练完成之后:参数量不一致、重叠框和指标,这些才是真坑
3.1 为什么训练一开始统计的参数量和训练完得到的参数量不一致
这是我在社区里被问过无数次的问题,也是我自己第一次接触时困惑了很久的问题。你用 model.parameters() 统计参数量,训练开始时会打印一个值,训练结束后保存模型再加载,又统计出一个不同的值,很多人就慌了,以为自己哪里设置错了。实际上这大多不是 bug,而是因为你统计的方式不对。
一个常见原因:训练时打印的参数量包含的是整个模型的参数,包括检测头、Backbone(主干网络)、Neck(颈部结构)所有模块。而训练结束后你如果直接加载的是 best.pt,PyTorch 默认会附带一些训练相关缓存(比如 ema 参数,EMA 指数滑动平均的备份权重),整个 .pt 文件占用的显存和参数量会比纯推理模型大。另外,YOLOv8 的检测头里有类似 cv2=Conv(256, 4*reg_max, 3) 这样的结构,reg_max 在训练和推理时的处理方式不同,也会造成统计口径不一致。
真正到了部署阶段,你还会发现导出的 ONNX 或 TensorRT 模型统计出的参数量,和你 Python 里的 PyTorch 模型又不一样。这通常是量化、剪枝、算子融合这些优化手段带来的正常差异。所以,我的结论是:你不需要过度纠结这个数值的绝对一致,只需要确认训练过程的参数量是相对稳定的,没有在某个 epoch 突然暴涨或变成 0。真正需要警觉的是 loss 曲线异常,那个比参数量重要得多。如果你的参数量不一致是因为误加载了检查点文件、模型结构被意外修改,这些属于代码逻辑问题,要单独排查。
3.2 模型“重叠框”问题的根源:NMS 参数和置信度阈值的博弈
你训练出来的模型,推理时检测出的每一个目标,常常会输出好几个相互重叠的候选框。这是很正常的,因为模型在推理阶段会对同一个目标产生多个“高置信度”的预测,你需要用 NMS(非极大值抑制,Non-Maximum Suppression)把这些框合并成一个。新版 YOLO 默认用的是 NMS 的变体(如 DIoU-NMS),逻辑是:先按置信度把所有框排序,保留最高分框,删除和它 IoU 大于某个阈值的框,然后重复这个过程。
很多人直接采取默认参数,然后抱怨“我的模型怎么框这么多”。这往往不是模型没训练好,而是 NMS 的 iou 阈值和 conf 阈值没配对好。conf 阈值是一个候选框被判为“正目标”的最低置信度,默认是 0.25。如果你把 conf 降到 0.1,模型会输出非常多的候选框,NMS 如果不给力,重叠框就多。反过来,如果你把 iou 阈值设得很低(比如 0.3),NMS 会显得“很激进”,果断删除 IoU 超过 0.3 的一切重叠框,相邻很近的两个目标很容易被误删一个(这种情况叫“抑制过度”)。
我的建议是,在测试阶段先去验证集上跑一批图片,直接观察模型输出的原始候选框(在 model.val() 里把 conf 调低,iou 调高,输出所有候选框可视化),看看模型究竟产生了什么样的预测,再决定 NMS 参数怎么调。以我的经验,通用场景下 iou=0.45, conf=0.25 是个不错的起点,交通事故检测、卫星遥感这种密集小目标场景,iou 可以降到 0.4,conf 提到 0.3。如果场景里两个目标经常紧挨着,别急着调参数,先去检查你的训练数据是不是本身就缺这类“紧挨着”的样本。
3.3 mAP、precision、recall:模型指标到底在说什么
YOLO 训练结束,控制台会打印一系列指标:precision(精度)、recall(召回率)、mAP50、mAP50-95。我看到很多新手只关注 mAP50 高不高,其实这几个指标各说各话,缺一个都是盲人摸象。
precision(查准率):模型预测出的所有框中,真正含有目标的框占多少。高 precision 意味着模型“很少误报”。recall(查全率):所有真实目标中,被模型正确检出的比例。高 recall 意味着模型“很少漏报”。mAP50:在 IoU 阈值为 0.5 时计算的平均精度,代表“大致框准了就算对”。mAP50-95:从 0.5 到 0.95 每隔 0.05 计算一次 IoU 阈值下的平均精度,再取平均。这个值对框的精确度非常苛刻,IoU=0.95 意味着预测框必须和真实框几乎完全重合才算对。所以它更接近真实工程落地的严格标准。
实际项目里,精度和召回率往往此消彼长,你需要根据场景权衡。举个例子,工业质检场景,误报一次就要停线人工复核,我会更看重 precision;而安防监控的入侵检测,漏报一次可能人已经溜进去了,我更看重 recall。YOLO 的 conf 阈值就是调节这种权衡的旋钮:把 conf 调高,precision 升 recall 降;把 conf 调低,recall 升 precision 降。理解了这个博弈,你才算真正能读懂训练日志,而不是看个数字高低。
4. 从模型到产品:导出和部署的那些“最后一公里”问题
4.1 ONNX、TensorRT 和 RKNN:不同硬件的不同导出姿势
训练好的 YOLO 模型不能直接塞进工业现场。你需要在训练框架之外,把 PyTorch 的 .pt 权重文件转换成目标平台能高效运行的格式。这中间有几种主流方案:
- ONNX(Open Neural Network Exchange):相当于深度学习模型的“通用语言”。几乎所有框架都能导出,几乎所有推理引擎都能导入。它是跨平台部署的第一步,但直接拿 ONNX 在 CPU 上跑,速度不一定快。
- TensorRT:NVIDIA 显卡专属的高性能推理引擎,能把模型算子做融合、量化,推理速度可以比 PyTorch 原版快几倍。RK3588 这类边缘设备上如果带 NVIDIA GPU,或者你有 NVIDIA 显卡服务器,TensorRT 是首选。
- RKNN:瑞芯微(Rockchip)系列芯片(如 RK3588、RV1126)的专用模型格式,需要通过
rknn-toolkit2工具把 ONNX 模型转换成.rknn文件,再在板子上的 RKNN Runtime 里调用。这个过程涉及量化、算子映射、死区处理,坑非常密集,我后续会出一篇专门讲 RK3588 上跑 YOLO 的实操。
你的部署硬件决定了你导出哪种格式。如果只是普通 PC 上的 Qt 界面调用,导出 ONNX 然后用 OpenCV DNN 模块或者 ONNX Runtime 推理就行;如果想在工业相机工控机上跑实时检测,TensorRT 几乎必选;如果是嵌入式设备,那就要看芯片平台选 RKNN 或者其它专用格式。千万别拿一套部署方案去套所有场景,每个平台的优化目标和适配范围都不同。
4.2 训练好的模型如何导出,才能便于 Qt 这类 GUI 调用
热搜词里有一条特别具体的需求:“训练模型后如何导出便于 qt 调用”。我估计提问的人是想做一个桌面的检测工具,用 Qt 画出检测框、显示类别和置信度。这里我要给他的答案是:不要试图在 Qt 里加载 .pt 文件直接跑 PyTorch 推理,那样做问题很多——目标机器不一定装了完整的 PyTorch 环境,推理速度也慢,打包分发更是噩梦。
正确做法是导出 ONNX,然后通过 ONNX Runtime 以 C++ 接口推理,再把推理结果送给 Qt 渲染。大致流程是:
- 训练完成,用
model.export(format="onnx", dynamic=True)导出动态尺寸的 ONNX 模型。 - 在 C++ 工程里引入 ONNX Runtime 的库和头文件,用
Ort::Session加载模型。 - 把图像从 Qt 的
QImage转成 RGB 数据,做 letterbox(保持长宽比加灰边)和归一化,变成模型要求的输入张量。 - 模型推理,拿到输出张量,然后做后处理(解码、NMS),得到检测框。
- 在 Qt 的 paintEvent 里绘制矩形框和标签文字。
这里有一个让很多初学 Qt 的人崩溃的细节:YOLOv8 的输出张量维度是 [1, 84, 8400],其中 8400 是所有特征图位置的总数(80×80 + 40×40 + 20×20),84 是 4 个框坐标加 80 个类别概率(如果你训练的是 COCO 80 类)。你需要在 C++ 里正确解析这 8400 个候选框,做一次 NMS,再转成你要画出来的结果。很多人在这一步直接把一维数组拉平,结果画出来的框完全乱套。这部分代码我会在后续 Qt 部署专项篇里完整给出,这里你先把“导出 ONNX → 预处理 → 后处理”这个链路记住。
4.3 边缘设备上的 YOLO 项目,为什么别人能跑 50 帧,你只能跑 8 帧
在 RK3588、RV1126 这类边缘设备上部署 YOLO,很多人抱怨帧率太低。这里头的原因基本可以归为四类,你可以照着我这个清单排查:
一是模型没有量化。FP16 或 FP32 模型在边缘端推理很慢,RKNN 工具链支持 INT8 量化,量化后模型体积缩小到原来的四分之一,推理速度通常能提升 2-3 倍,但精度会有一定损失。需要用少量校准图片做量化校准,选出损失最小的量化方式。
二是用了不合适的输入分辨率。很多人在边缘设备上依然用 1280×1280 输入,当然慢。边缘端如果检测目标不是特别小,建议从 640 起步;如果实在要检测小目标,再逐步加到 960 或 1280,通过测试帧率找到一个你能接受的平衡点。
三是后处理代码写得不好。YOLO 的 NMS 也是计算密集操作,如果直接在 Python 里逐框遍历,速度会非常难看。用 C++/Cython 实现向量化的 NMS,或者在板子上用带 NEON 指令的优化矩阵库,效果立竿见影。
四是板子的 NPU 没被真正用起来。RK3588 有 6 TOPS 的 NPU,很多人却只用了 CPU 在跑。检查一下你的 RKNN Runtime 调用是否真的把模型加载到了 NPU 设备上,而不是默默回退到了 CPU。这一条是最常见的隐形坑,我见过不少项目就是栽在这上面。
5. 知其所以然:主干网络替换、多模态和检测头设计的门道
5.1 换主干网络(Backbone)到底换的是什么
热搜词里有一条很典型:“yolov8 替换主干网络之 convnextv2”。很多人把换主干网络当成一种“性能提升魔法”,换上更强的 Backbone,就指望 mAP 涨一截。但换 Backbone 的本质是在“感受野、计算量、表达能力”三者之间做权衡。YOLOv8 默认的 Backbone 是 CSPDarknet 结构,它用跨阶段局部连接(CSP)的方式减少了重复梯度计算,控制了计算量。ConvNeXtV2 则是借鉴了 Swin Transformer 的宏观设计,用纯卷积的方式模拟了全局注意力,理论上能捕获更长的依赖关系,对小目标或者背景复杂的场景或许有帮助,但参数量和计算量也明显上涨。
换 Backbone 不是改一行配置的事。你要在 ultralytics/nn/modules/convnextv2.py 里定义好网络结构,然后在 yolov8_convnextv2.yaml 里重新组装 Backbone 和检测头的连接关系,还要考虑输出通道数是否对齐。如果尺寸对不上,后续的 Neck 直接报错。我的建议是,在你没有充分理解 YOLO 默认 Backbone 为什么这么设计之前,先不要盲目换。先把默认结构的消融实验做足,跑通基线,再开始尝试替换,并且用对照实验验证替换后的收益。我见过太多人换了 Backbone 之后精度没提升,反而因为显存爆炸把训练搞崩了。
5.2 多模态、双模态与 YOLO:不只是“图像+文本”这么简单
YOLO 社区现在也流行起多模态,比如“yolo 多模态”“yolo 双模态代码”。这里面的多模态,通常指的是把除了 RGB 图像之外的其它数据源(红外图、深度图、点云、文本描述)融合进检测框架。双模态最常见的一种形式就是双光相机:一个可见光镜头加一个红外镜头,同一场景同时输出两路图像,然后让模型同时利用两路信息做检测。这种需求在夜间监控、消防救援、自动驾驶里越来越常见。
实现方案大致有两种:一种是在预处理阶段把两路图拼成一个多通道输入(比如 RGB + IR 组成 4 通道),然后修改 YOLO 的第一个卷积层输入通道数。这种做法简单,但对两路信息的融合比较粗放。另一种是在 Backbone 之后做特征级融合,即双分支 Backbone 分别提取特征,然后在 Neck 之前拼接或相加。这样做效果更好,但参数量翻倍,训练难度也变大。你如果遇到“双模态代码”的需求,先想清楚你的两路信息到底是互补的还是冗余的,互补才值得做融合,如果两路信息高度相关,融合收益可能微乎其微,还不如只跑一路。
5.3 一个“反直觉”的调优认知:检测头比 Backbone 更常成为瓶颈
很多人以为检测不准就是 Backbone 不够强,于是折腾了一天换 ResNet、换 EfficientNet。但根据我自己的项目经验(道路裂缝、无人机视角小目标、水位识别都试过),当你的数据集达到几千张的时候,Backbone 从 YOLOv8n 换到 YOLOv8x,mAP 的提升可能只有几个点;而把注意力放到损失函数的设计、正负样本分配策略、难例挖掘上,收益反而更大。YOLOv8 的检测头看似轻量,但它的任务划分策略(比如 TAL 动态标签分配)直接决定了哪些预测框被当作正样本来学习。
举个我调过的例子:无人机航拍数据集里目标很小,模型总是漏检。我一开始以为要换更强的 Backbone,后来试着把 anchor 相关配置调成了更适合小目标的设置(在 anchor-free 结构里就是调整模型输出特征图的缩放比例),又给损失函数里带上更关注小目标的权重,效果立刻好了不少。这说明检测头和训练策略的优化空间,往往比 Backbone 本身更重要。你与其花大把时间去搜“最强 Backbone”,不如把自己的数据集可视化一下,看看模型的漏检和误检模式,对症下药。
YOLO 这个领域,大家总在追逐新模型、新算法,但真正重要的其实是建立一套自己的“排查方法论”:数据有没有问题、参数合不合理、部署流程对不对、瓶颈卡在哪一环。我这套 YOLO-Master 系列后面的文章,会一篇一个主题,从训练细节到部署实战逐个攻破。下一篇我打算先写数据标注和数据增强的完整实操,因为这是整个项目里最枯燥、但回报率最高的环节。我踩过的那些坑,一次性给你讲清楚。
