Link to this section如何对自定义数据集微调 YOLO#
微调 通过从已学习的权重开始,而不是随机初始化,来使预训练模型适应识别新类别。微调不需要从零开始进行数百个 epoch 的训练,而是利用预训练的 COCO 特征,并能以极短的时间在自定义数据上收敛。
本指南涵盖了在自定义数据集上微调 YOLO26 的方法,从基本用法到冻结层和两阶段训练等高级技术。
Link to this section微调与从零开始训练的区别#
预训练模型已经从数百万张图像中学习了通用的视觉特征,例如边缘检测、纹理识别和形状理解。迁移学习通过微调来重用这些知识,只教会模型新类别是什么样子的,这就是它为什么收敛更快且需要更少数据的原因。从零开始训练则会抛弃所有这些知识,迫使模型从像素级的模式开始学习一切,这需要消耗更多的资源。
| 微调 | 从零开始训练 | |
|---|---|---|
| 起始权重 | 在 COCO 上预训练(80 个类别) | 随机初始化 |
| 命令 | YOLO("yolo26n.pt") | YOLO("yolo26n.yaml") |
| 收敛 | 更快 - 主干网络已经训练过 | 更慢 - 所有层都从零开始学习 |
| 数据需求 | 更低 - 预训练特征可以弥补数据不足 | 更高 - 模型必须仅从数据集中学习所有特征 |
| 适用场景 | 带有自然图像的自定义类别 | 与 COCO 领域完全不同的场景(医疗、卫星、雷达) |
When a .pt file is loaded with YOLO("yolo26n.pt"), the pretrained weights are stored in the model. Calling .train(data="custom.yaml") after that automatically transfers all compatible weights to the new model architecture, reinitializes any layers that don't match (such as the detection head when the number of classes differs), and begins training. No manual weight loading, layer manipulation, or custom transfer learning code is required.
Link to this section预训练权重迁移的工作原理#
当预训练模型在类别数量不同的数据集上进行微调时(例如从 COCO 的 80 个类别到 5 个自定义类别),Ultralytics 会执行形状感知的权重迁移:
- 主干和颈部完全迁移 - 这些层提取通用视觉特征,它们的形状与类别数量无关。
- 检测头部分重新初始化 - 分类输出层(
cv3、one2one_cv3)的形状与类别计数(80 vs 5)相关联,因此它们无法迁移并会被随机初始化。检测头中的边界框回归层(cv2、one2one_cv2)无论类别数量如何都具有固定形状,因此它们会正常迁移。 - 当更改类别数量时,绝大多数权重都会迁移。例如,将 YOLO26n 从 COCO(80 个类别)微调到 5 类数据集时,708 个权重张量中有 606 个被迁移:只有与类别计数相关的分类层被重新初始化,而主干、颈部和边界框回归分支保持不变。
对于与预训练模型类别数量相同的数据集(例如,在另一个 80 类数据集上微调 COCO 预训练权重),100% 的权重(包括检测头)都会迁移。
Link to this section基本微调示例#
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # load pretrained model
model.train(data="custom.yaml", epochs=50, imgsz=640)Link to this section选择模型大小#
较大的模型具有更高的容量,但也有更多的参数需要更新,这在训练数据有限时可能会增加过拟合的风险。从较小的模型(YOLO26n 或 YOLO26s)开始,仅在验证指标停滞时扩大模型规模是一种实用的方法。最佳模型大小取决于任务的复杂性、类别数量、数据集的多样性以及可用于部署的硬件。请参阅完整的 YOLO26 模型页面 以了解可用的大小和性能基准。
Link to this section优化器和学习率选择#
默认的 optimizer=auto 设置会根据训练迭代的总数自动选择优化器和学习率:
- < 10,000 次迭代(小型数据集或少量 epoch):使用较低的、自动计算的学习率的 AdamW
- > 10,000 次迭代(大型数据集):MuSGD(一种混合 Muon+SGD 优化器),lr=0.01
对于大多数微调任务,默认设置无需任何手动调整即可良好运行。在以下情况请考虑显式设置优化器:
- 训练不稳定(损失峰值或发散):尝试
optimizer=AdamW, lr0=0.001以获得更稳定的收敛 - 在小型数据集上微调大型模型:较低的学习率(如
lr0=0.001)有助于保留预训练特征
当 optimizer=auto 时,lr0 和 momentum 值将被忽略。要手动控制学习率,请显式设置优化器:optimizer=SGD, lr0=0.005。
Link to this section冻结层#
冻结可以防止特定层在训练期间更新。当数据集相对于模型容量较小时,这可以加速训练并减少过拟合。
freeze 参数接受整数或列表。整数 freeze=10 会冻结前 10 层(索引 0-9),这涵盖了大部分 YOLO26 主干。主干跨越 0-10 层,因此 freeze=10 会使最后的 C2PSA 块(第 10 层)保持可训练;使用 freeze=11 可冻结整个主干。列表可以包含层索引(例如 freeze=[0, 3, 5])进行局部主干冻结,或者包含模块名称字符串(例如 freeze=["23.cv2", "23.one2one_cv2"])对层内的特定分支进行精细控制(此处指检测头的两个边界框回归分支)。
model.train(data="custom.yaml", epochs=50, freeze=10)正确的冻结深度取决于目标领域与预训练数据的相似程度以及可用训练数据的数量:
| 场景 | 建议 | 依据 |
|---|---|---|
| 大数据集,相似领域 | freeze=None(默认) | 有足够的数据来调整所有层而不会过拟合 |
| 小数据集,相似领域 | freeze=10 | 保留主干特征,减少可训练参数 |
| 非常小的数据集 | freeze=23 | 仅训练检测头,最大限度降低过拟合风险 |
| 领域与 COCO 相差巨大 | freeze=None | 主干特征可能无法很好地迁移,需要重新训练 |
冻结深度也可以视为超参数——尝试几个值(0, 5, 10)并比较验证 mAP 是为特定数据集找到最佳设置的实用方法。
Link to this section微调的关键超参数#
与从零开始训练相比,微调通常需要较少的超参数调整。最关键的参数是:
epochs:微调比从零开始训练收敛得更快。从一个中等的值开始,并利用patience在验证指标停滞时提前停止。patience:默认值 100 是为长时间运行的训练设计的。将其减小到 10-20 可以避免在已经收敛的运行上浪费时间。warmup_epochs:默认的热身(3 个 epoch)会逐渐增加学习率,这可以防止大的梯度更新在早期迭代中损坏预训练特征。即使在微调时也建议保留默认值。
有关训练参数的完整列表,请参阅训练配置参考。
Link to this section两阶段微调#
两阶段微调将训练分为两个阶段。第一阶段冻结主干并仅训练颈部和头部,使检测层在不干扰预训练特征的情况下适应新类别。第二阶段解冻所有层,并以较低的学习率训练完整模型,以针对目标领域精炼主干。
当目标领域与 COCO 差异显著(如医疗图像、航空影像、显微镜图像)时,这种方法特别有用。在这种情况下,主干可能需要调整,但同时训练所有内容会导致不稳定。有关使用基于回调的方法进行自动解冻的信息,请参阅冻结和解冻主干。
from ultralytics import YOLO
# Stage 1: freeze backbone, train head and neck
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=20, freeze=10, name="stage1", exist_ok=True)
# Stage 2: unfreeze all, fine-tune with lower lr
model = YOLO("runs/detect/stage1/weights/best.pt")
model.train(data="custom.yaml", epochs=30, lr0=0.001, name="stage2", exist_ok=True)Link to this section常见问题#
Link to this section模型不产生任何预测结果#
- 训练数据不足:使用极少量样本进行训练是最常见的原因——模型无法从太少的数据中学习或泛化。在调查其他原因之前,请确保每个类别都有足够且多样的示例。
- 检查数据集路径:
data.yaml中的路径不正确会静默地导致标签缺失。在训练前运行yolo detect val model=yolo26n.pt data=custom.yaml以确认标签是否正确加载。 - 降低置信度阈值:如果存在预测但被过滤掉了,请尝试在推理时使用
conf=0.1。 - Verify class count: ensure
ncindata.yamlmatches the actual number of classes in the label files.
Link to this section验证 mAP 过早停滞#
- 添加更多数据:微调极大地受益于额外的训练数据,尤其是具有不同角度、光照和背景的多样化示例。
- 检查类别平衡:代表性不足的类别会有较低的 AP。使用
cls_pw应用反频率类别加权(中度不平衡从cls_pw=0.25开始,严重不平衡增加到1.0)。 - 减少增强:对于非常小的数据集,强力的增强可能会弊大于利。尝试
mosaic=0.5或mosaic=0.0。 - 增加分辨率:对于具有小对象的数据集,尝试
imgsz=1280以保留细节。
Link to this section微调后原始类别性能下降#
这被称为灾难性遗忘——模型在仅针对新数据进行微调时丢失了以前学到的知识。如果不将原始数据集图像与新数据一起包含,遗忘在很大程度上是不可避免的。缓解措施:
- 合并数据集:在微调期间,将原始类别的示例与新类别一起包含。这是防止遗忘的唯一可靠方法。
- 冻结主干和颈部:冻结主干和颈部,仅训练检测头,有助于在较低的学习率下进行短期的微调。
- 减少训练 epoch:模型在仅针对新数据上训练的时间越长,遗忘现象就越严重。
Link to this section常见问题解答#
Link to this section我需要多少图像来微调 YOLO?#
没有固定的最小值——结果取决于任务的复杂性、类别数量以及领域与 COCO 的相似程度。更多样化的图像(变化的光照、角度、背景)比纯粹的数量更重要。从你现有的数据开始,如果验证指标不足,再增加数据量。
Link to this section如何对自定义数据集微调 YOLO26?#
Load a pretrained .pt file and call .train() with the path to a custom data.yaml. Ultralytics automatically handles weight transfer, detection head reinitialization, and optimizer selection. See the Basic Fine-Tuning section for the complete code example.
Link to this section为什么我微调后的 YOLO 模型什么也没检测到?#
最常见的原因是 data.yaml 中的路径不正确(会导致静默地产生零标签)、YAML 中的 nc 与实际标签文件不匹配,或者是置信度阈值设置得太高。查看常见问题获取完整的故障排除清单。
Link to this section微调时应该冻结哪些 YOLO 层?#
这取决于数据集的大小和领域相似性。对于与 COCO 领域相似的小型数据集,冻结主干 (freeze=10) 可防止过拟合。对于与 COCO 差异很大的领域,保持所有层不冻结 (freeze=None) 可以让主干进行调整。有关详细建议,请参阅冻结层。
Link to this section在对新类别微调 YOLO 时如何防止灾难性遗忘?#
在训练数据中同时包含原始类别的示例和新类别。如果无法做到这一点,冻结更多层(freeze=10 或更高)并使用较低的学习率有助于保留预训练知识。有关更多详细信息,请参阅微调后原始类别性能下降。