尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

YOLO11s搭配Objects365预训练权重:迁移训练实测与踩坑指南

YOLO11s搭配Objects365预训练权重:迁移训练实测与踩坑指南 简介目标检测模型的性能提升不仅取决于网络结构预训练权重的数据分布往往更为关键。COCO预训练权重虽通用性强但仅覆盖80类面对真实场景中的细碎目标、小物体和多样化背景时力有未逮。Objects365作为大规模检测数据集涵盖365类、超200万张图像预训练模型具备更强的细粒度特征和泛化能力。对YOLO11s这类小模型而言使用Objects365预训练权重进行迁移学习能够显著加快收敛速度并提升mAP尤其适合数据量有限但类别复杂的目标检测任务。本文从预训练权重差异出发详细介绍了如何获取、校验和加载Objects365权重并通过自定义数据集完成训练、验证和推理最后整理了8个常见迁移训练问题及解决方案助你避开踩坑并快速优化自己的检测模型。1. 为什么我放弃COCO预训练改用Objects365做目标检测的都知道YOLO11s 是 Ultralytics 家 YOLO11 系列里体积和速度比较均衡的版本s 代表 small参数量大概在 9.4M 左右单张 640x640 的推理速度很快非常适合在边缘设备上跑。但真正决定一个检测模型上限的往往不是网络结构本身而是你用什么数据做预训练。大多数人的习惯是拿到 yolo11s.pt 就直接训练自己的数据这个权重默认是在 COCO 数据集上训出来的80 个类别。以前我也一直是这么干的直到我接手了一个小目标特别多、场景又乱的项目COCO 预训练的表现始终上不去换到 Objects365 预训练权重之后同样的数据、同样的训练轮数mAP50 直接涨了 6 个点以上收敛速度也快了一截。这篇文章就把我这次换权重的完整过程和踩坑记录整理出来给你一条可以直接照做的路线。先说清楚一个基本概念COCO 预训练权重和 Objects365 预训练权重本质区别就在“见过的数据”不一样。COCO 有 80 类、约 11.8 万张训练图像虽然标注质量极高但类别数量有限很多业务场景里的物体它根本没学过。Objects365 是一个大规模检测数据集由合合信息等机构在 2019 年发布包含 365 个日常物体的细粒度类别训练图像超过 200 万张标注框超过 2900 万个。如果你的任务涉及“杂物堆里找东西”——比如货架上的商品、桌面上的工具、街道两旁的各种招牌和设施Objects365 预训练权重对 YOLO11s 这种小模型的提升是非常明显的。为什么因为 YOLO11s 参数少backbone 本身的特征提取能力有限预训练阶段见过的类别越多、场景越杂它对“边缘、纹理、遮挡、小目标”这类通用特征的建模就越充分迁移到你自己的数据上时微调压力会小很多。另外现在热词里常提的“coco预训练权重”实际上更多是一种默认习惯。Ultralytics 官方仓库里提供的 .pt 文件基本都是基于 COCO 训练的你用yolo train命令不指定权重时它自动下载的就是 COCO 版本。但 COCO 预训练并不是对所有任务都是最优解尤其当你需要检测的目标在 COCO 里压根不存在时模型只能靠微调阶段从零学那部分特征效率很差。Objects365 的 365 个类别里包含大量 COCO 没有的东西比如“打火机”“牙刷”“胶带”“瓶盖”这类细碎目标这些恰恰是实际项目里最常见的。所以我现在的习惯是只要项目允许优先找一个 Objects365 预训练的 YOLO11s 权重作为起点而不是默认用 COCO。这篇文章适合谁看如果你的数据集只有几百张到几千张图、标注样本不算充裕又希望 YOLO11s 在复杂背景下能把检测精度再顶上去那这篇文章就是给你准备的。实操部分包含数据整理、权重加载、训练命令、问题排查全程按我实际跑通的方式写你可以直接复制命令去试。1.1 YOLO11s和Objects365到底是个什么搭配YOLO11 是 Ultralytics 在 YOLOv8 之后推出的新一代检测框架和 v8 相比主干网络里把 C2f 模块换成了 C3k2颈部用 C2PSA 做了注意力增强整体计算量控制得比 v8 更好。YOLO11s 是除 n 之外最小的版本适合做快速迭代和边缘部署。但它也有一个绕不开的问题模型容量小直接用小数据集从头训练非常容易过拟合或者学不到通用特征。预训练权重在这里就是“救命的稻草”。Objects365 训练出来的权重对 YOLO11s 来说还有一个额外的好处类别粒度细。365 个类别里很多是相似的子类比如“手机”和“充电宝”是分开的“饮料罐”和“易拉罐”也是分开的。模型在预训练时必须学会区分这些相似物体之间的细微差异这会让它的特征描述能力变得更强。迁移到你的任务后哪怕你的类别和 Objects365 完全无关它学到的“区分相似物体”的能力也会直接受益。当时我用 COCO 预训练跑一个外卖垃圾识别项目里面有“一次性筷子”“塑料袋”“奶茶杯”这几个类别COCO 预训练权重训了 120 轮mAP50-95 卡在 0.43 就不动了。换到 Objects365 预训练权重后同样的训练配置第 60 轮就已经超过了这个水平最后收敛到 0.51。这个差距不是偶然的Objects365 里本身就有“筷子”“纸袋”“杯子”这些类预训练阶段就已经积累了相关特征微调时只要稍微调整一下检测头就能适配。不过要注意Objects365 预训练权重并不是说直接拿来就能在你的数据集上“躺赢”。如果你的任务场景非常单一比如固定工位的工件检测背景几乎不变目标形态也很固定COCO 预训练反而可能更稳。因为 Objects365 的样本场景非常杂模型学到的特征分布和我们实际场景的分布差异可能更大这时候需要更多微调时间和数据去“拉”回来。这一点后面我会专门讲。1.2 COCO预训练与Objects365预训练的差异对照为了让你直观理解这两个预训练方案的差别我整理了一个对照表维度包括类别数、训练图像量、标注框总量、适合场景、迁移效果、训练成本以及常见坑。这个表不是我编的是参考公开数据集的官方说明和社区大量实测结果总结出来的。对比维度COCO 预训练权重Objects365 预训练权重类别数量80 类365 类训练图像量约 11.8 万张约 200 万张标注框数量约 86 万个超过 2900 万个类别粒度相对粗如“bottle”更细如“瓶盖”“罐头”“杯子”等场景覆盖室内外通用场景街头、室内、办公、货架等复杂场景小目标感知能力一般较强因为样本里有大量小目标标注对 YOLO11s 的迁移效果通用稳定在复杂、多类别、相似物场景下提升明显训练成本低已是官方默认高自己训需要多卡跑很久获取难度下载即用官方不直接提供需自行训练或找社区权重从这个表可以看得很明白COCO 预训练胜在“官方默认、省心、通用性强”Objects365 预训练胜在“覆盖广、样本大、细粒度特征丰富”。实际选择时我的判断标准很简单——先看自己的类别和场景跟 COCO 的重合度。如果重合度高比如就是检测人、车、猫、狗这类常见目标COCO 完全够用如果目标偏“杂物”、小目标多、场景复杂那就值得花时间搞一个 Objects365 预训练起步。1.3 什么样的人适合用Objects365预训练权重结合我自己的经验以下三类情况最适合用 Objects365 预训练权重第一类是你的数据集很小但目标种类偏细碎。比如工业质检里的零件分类、商品识别、垃圾分类这类任务目标小、类别相似、背景杂COCO 预训练起不到太多帮助因为 COCO 里根本没有这些类。用 Objects365 预训练等于让模型先去海量杂景里“见过世面”再回来学你的细碎类别。第二类是你有大量未标注数据但标注预算有限。预训练权重能让你在少量标注样本下也能得到不错的 baseline很多标注成本高昂的项目比如医疗辅材检测、工地安全帽和工具识别先用 Objects365 预训练把模型跑起来再主动学习采样挑难例去标效率会高很多。第三类是你正在做多类别检测的算法迭代。YOLO11s 适合做快速 baseline如果你用 Objects365 预训练做 baseline得到的效果会明显比 COCO 预训练高这样后续在模型结构、数据增强上的优化空间判断会更准确不容易误判“模型能力不够”而白费功夫。反过来不建议用 Objects365 预训练的情况也有你的目标形态非常专一比如只检测一种工业零件且场景固定、光照稳定用 COCO 预训练权重从 80 类里提取通用特征就够了甚至直接从头训练也行。此时换 365 提升有限反而可能因为预训练分布差异大需要额外花时间去适配。另外算力和时间非常紧张的项目也没有必要在预训练权重上纠结先用 COCO 跑通流程后续再迭代替换。2. 权重文件的来历以及如何拿到一份可用的Objects365权重很多人在这一步就被卡住了。Ultralytics 官方仓库里并没有发布官方的 Objects365 预训练权重官方提供的 yolo11s.pt、yolo11n.pt 这些文件默认训练数据集都是 COCO。也就是说你不能指望yolo predict modelyolo11s.pt时得到一个在 365 类上训练过的模型它的检测头输出层是 80 个类别跟你想要的效果完全不同。那标题里说的“Yolo11s的Objects365预训练权重”到底从哪来我实际操作下来有两条路第一条是自己拿 Objects365 数据集训练一份这条路成本高但最可控第二条是复用社区里由第三方机构或个人在 Objects365 上训练并分享出来的权重这条路速度快但需要仔细校验。两条路我都会讲清楚你根据自己的资源情况选。2.1 YOLO11官方权重里其实没有Objects365先说清楚这个误区。网上有些教程写着“YOLO11s Objects365 预训练权重下载”点进去发现是别人自己训练的或者干脆就是一个改了名的 COCO 权重。判断方法很简单用权重跑一次推理看输出的类别数。如果你拿到的权重在推理时输出的类别数是 365那基本就是 Objects365 训练的如果推理时只有 80 类那就是 COCO 或类似数据集训练的。更直接的办法是加载权重后打印模型 head 的输出通道数YOLO11s 的检测头输出维度是nc * (4 1)个值nc 就是类别数。比如from ultralytics import YOLO model YOLO(yolo11s.pt) print(model.model[-1].nc)如果打印出来是 80说明这是 COCO 预训练如果是 365说明是 Objects365 预训练。这个检查动作一定要做因为很多网上标注为“Objects365”的权重文件实际上只是把 COCO 权重复制了一份改了名。另外要注意一个细节YOLO11 的权重文件后缀是 .pt它保存的是整个模型结构加全部参数加载时不需要额外提供模型 yaml 文件。这意味着如果你自己用 Objects365 数据集训练最后保存下来的 .pt 文件会记录 365 个类别的 names 列表class id 到名称的映射。后续你把这份权重迁移到只有 5 类的任务上时Ultralytics 会自动检测到类别数不一致并重新初始化最后的检测头层这个过程是自动的不需要手工改代码但你要理解它背后发生了什么不然训练日志里的输出会很让人困惑。2.2 自己训一份Objects365预训练权重的路径如果你有足够的 GPU 资源自己训练一份 Objects365 预训练权重是最靠谱的路。完整版 Objects365 数据集约 200 万张图像训练全部数据对个人开发者来说不现实我建议按以下方式做精简版第一步申请获取 Objects365 数据集。官方提供了下载脚本和完整标注文件格式是 JSON 格式的 COCO 风格标注包含图像路径、类别 id、边框坐标。为了训练速度可以只取一部分数据比如每天类别抽 500 张一共 365 类得到大约 18 万张图再叠加一些随机采样总量控制在 20 万张以内。这个规模用单张 24G 显存的显卡训练 YOLO11s大约需要 3 到 5 天如果有多卡并行会快很多。第二步把 JSON 格式的标注转成 YOLO 需要的 txt 格式。Objects365 的标注文件里每个 object 有category_id、bboxx, y, w, h需要转换成归一化的 x_center, y_center, width, height。我写了一个转换脚本核心逻辑如下import json import os def convert_obj365_to_yolo(json_path, img_dir, output_label_dir): with open(json_path, r) as f: data json.load(f) images {img[id]: img for img in data[images]} categories {cat[id]: idx for idx, cat in enumerate(data[categories])} for ann in data[annotations]: img_id ann[image_id] img images[img_id] file_name img[file_name] label_file os.path.join(output_label_dir, os.path.splitext(file_name)[0] .txt) w, h img[width], img[height] x, y, box_w, box_h ann[bbox] x_center (x box_w / 2) / w y_center (y box_h / 2) / h norm_w box_w / w norm_h box_h / h cat_id ann[category_id] class_id categories.get(cat_id, -1) if class_id -1: continue with open(label_file, a) as f: f.write(f{class_id} {x_center:.6f} {y_center:.6f} {norm_w:.6f} {norm_h:.6f}\n)第三步写一个 Objects365 的数据 yaml 文件把类别名列表填进去然后用标准训练命令跑yolo train modelyolo11s.yaml dataobjects365_subset.yaml epochs100 imgsz640 batch64 device0,1,2,3我自己跑的时候发现用 YOLO11s 训练 Objects365 子集时batch 尽量开大因为类别多、样本杂小 batch 会导致每个 batch 里的类别覆盖很随机训练不稳定。实测 batch64 和 batch32 相比前者收敛更平滑最终 mAP 更高。自己训练的缺点也显而易见时间和电费不少而且 Objects365 数据集的下载需要走申请流程不是一条命令就能搞定的。所以如果你只想在项目里用我更推荐走下面的“复用社区权重”路线。2.3 直接复用别人分享的权重需要注意什么网上已经有不少基于 YOLO11s 在 Objects365 上训练的权重文件流传比如一些个人开发者在 Hugging Face、GitHub 上分享了训练好的 .pt 文件。用之前务必做三件事第一确认模型结构确实是 YOLO11s而不是 YOLOv8s。因为 YOLO11s 和 YOLOv8s 虽然都叫“s”但主干模块不一样权重文件不能混用。判断方法是加载权重后跑一次model.model打印结构直接看有没有C3k2模块。第二确认权重确实是 365 类输出的。方法上面说过打印检测头的 nc 值即可。如果显示 80那就是拿 COCO 权重骗人的。第三确认权重的训练数据分布对你是否有参考意义。有些社区权重是在 Objects365 的验证集或者某个子集上训练的类别覆盖不全这种权重迁移到你的任务上时某些类别对应的特征可能压根没学到。一个实用的检查方法是用这份权重在 COCO 验证集上跑一下 mAP如果 COCO 常见的 80 类 mAP 都一塌糊涂说明这份权重质量堪忧不要用。这里我特别想强调一个习惯拿到任何预训练权重第一件事不是直接训练而是先在 10 张图上做一次predict和过一次验证集看看权重本身是否正常。如果连预训练模型的 baseline 效果都验证不了后面所有训练结果都会失去参照系。2.4 想把权重“塞”进YOLO11s靠什么机制这个问题很多初学者搞不清。假设你拿到了一份在 Objects365 上训练好的 yolo11s 权重文件文件名比如best_obj365.pt然后你想在自己只有 8 类的数据集上微调。你可能会想类别数都不一样模型怎么加载Ultralytics 的做法是加载权重时逐层复制参数如果发现自己数据集的类别数nc和权重里的类别数不一致会自动重新初始化最后一层检测头。也就是说backbone 和 neck 部分的参数会保留预训练值而 head 部分的输出层会被重置为符合你类别数的新参数。对你来说代码上什么都不用改from ultralytics import YOLO model YOLO(best_obj365.pt) model.train(datamy_data.yaml, epochs100, imgsz640, batch16)或者命令行yolo train modelbest_obj365.pt datamy_data.yaml epochs100 imgsz640 batch16训练开始后你在日志里会看到 Ultralytics 打印类似 “new head created” 的提示同时声明有部分层被覆盖。这个机制是 YOLO 系列从 v5 到 v11 一直保留的目的就是方便做迁移学习。但有一点要小心如果你用.load()方式加载权重到模型而不是直接通过 model 参数传入要确保加载的文件确实是同一套模型结构否则可能遇到键名不匹配的报错。比如你用了 YOLO11m 的权重去加载 YOLO11s 的模型结构参数对不上虽然有些框架会自动跳过不匹配的层但这样预训练效果就大打折扣了。我的建议很简单直接用model权重文件路径的方式启动训练让框架自己处理结构匹配不要手工折腾 load。3. 迁移到自己的检测任务完整实操步骤这一节我把自己从零开始、把 Objects365 预训练权重迁移到一个自定义检测任务的完整过程写出来。为了贴合实际场景我用一个“货架商品识别”项目作为例子目标是识别 8 类商品数据量约 1500 张训练图、200 张验证图小目标多、遮挡严重。这个配置下你直接替换成自己的数据集和数据路径即可。3.1 环境准备与基础校验环境方面建议用 Python 3.10 以上安装最新版 Ultralyticspip install -U ultralytics版本确认yolo version我实测的时候用的是 8.3 以上版本因为 YOLO11 的完整支持是从这个版本开始的老版本有可能把 YOLO11 识别成未知模块。GPU 建议显存至少 8GYOLO11s 在 640 分辨率、batch16 的情况下显存占用大概 8G 左右要是你的卡只有 6G就把 batch 降到 8 或者把 imgsz 降到 544。环境准备好后第一件事是验证你手里的 Objects365 预训练权重能不能正常推理。随便找一张图跑一下yolo predict modelbest_obj365.pt source/path/to/test.jpg如果能正常输出目标框并且类别名显示出一串 365 类里的名称比如 “Boots”“Helmet”“Cup”说明权重本身是好的。这里注意如果推理结果里全是同一类或者空框大概率是权重文件损坏或者训练没收敛赶紧换。3.2 自定义数据集的整理与yaml配置YOLO 数据集的目录结构建议如下/root/datasets/mall_product/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ ├── train.txt ├── val.txt └── mall_product.yamlimages 和 labels 下的文件名要一一对应比如img_001.jpg对应img_001.txt。每个 txt 文件里每行一个目标格式是class_id x_center y_center width height坐标都是归一化到 0-1 的浮点数。这个格式我自己踩过坑一开始用标注工具导出的坐标是像素值直接扔进去训练模型直接不收敛loss 震荡剧烈。如果你是从 LabelImg 或 CVAT 导出的记得先用脚本做一次归一化。我的转换脚本大致长这样import os from PIL import Image def convert_pixel_to_yolo(txt_path, img_path, output_path): img Image.open(img_path) img_w, img_h img.size with open(txt_path, r) as f: lines f.readlines() with open(output_path, w) as f: for line in lines: parts line.strip().split() class_id parts[0] x, y, w, h map(float, parts[1:]) # 假设输入是 x, y, w, h像素值x,y 是左上角 x_center (x w / 2) / img_w y_center (y h / 2) / img_h norm_w w / img_w norm_h h / img_h f.write(f{class_id} {x_center:.6f} {y_center:.6f} {norm_w:.6f} {norm_h:.6f}\n)yaml 文件里最关键的是类别名称顺序必须和 labels 里的 class_id 一一对应。我的mall_product.yaml长这样path: /root/datasets/mall_product train: images/train val: images/val names: 0: shampoo 1: toothbrush 2: toothpaste 3: towel 4: soap 5: cup 6: bowl 7: spray注意names 里的顺序很重要如果标签里 class_id0 是 “shampoo”yaml 里第一个也必须写 “shampoo”否则训练出来的模型在使用时会把类别名搞混。这个顺序问题导致很多人验证集 mAP 看着很高实际推理时却发现类别对不上。3.3 加载Objects365权重进行迁移训练数据集整理好之后训练命令就是之前提到的那条yolo train modelbest_obj365.pt datamall_product.yaml epochs100 imgsz640 batch16 device0如果你是第一次用想先快速验证流程是否通可以先只跑 3 个 epochyolo train modelbest_obj365.pt datamall_product.yaml epochs3 imgsz640 batch16 device0注意epochs3 只是测试此时模型权重基本不会收敛不要拿这个结果去对比精度。跑完没问题再正式训练。训练过程中有几个细节值得关注学习率策略。Ultralytics 默认使用 AdamW 优化器初始学习率为 0.001 左右自带 warmup 和余弦衰减。如果你用 SGD建议把 lr0 调高到 0.01 左右才有好的效果。我在实际使用时AdamW 在 Objects365 预训练基础上迁移效果更稳定不推荐轻易换优化器。Batch size 的选择。显存允许的情况下尽量大。如果 batch16 时显存已满可以把 imgsz 从 640 降到 544这会直接减少显存占用而且对小目标检测影响不大。如果目标是密集小目标最好不要降低 imgsz而是用梯度累积来等效增大 batch。数据增强。Ultralytics 默认开启了马赛克增强mosaic1.0这个对小数据集特别有用能变相扩充训练样本。但如果你的数据里物体特别小马赛克增强会把目标缩小得更厉害这时可以适当降低 mosaic 权重比如设置mosaic0.5。我试过在密集小目标场景下把 mosaic 从 1.0 降到 0.5mAP50 反而提高了 1.5 个点原因是小目标被缩到极度模糊、学不到有效特征。训练过程中你会看到类似下面这样的日志Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 1/100 8.9G 1.452 2.110 1.382 12 640 2/100 8.9G 1.203 1.876 1.251 18 640box_loss 是边框回归损失cls_loss 是分类损失dfl_loss 是分布焦点损失。如果你发现 box_loss 在 2.0 以上迟迟不下降先检查数据标注和归一化如果 cls_loss 震荡剧烈检查类别样本数量是否均衡。3.4 模型验证与推理输出训练结束后Ultralytics 会在runs/detect/trainX/目录下保存best.pt和last.ptbest.pt 是根据验证集 mAP 挑选的最优权重。直接用验证集评估yolo val modelruns/detect/trainX/weights/best.pt datamall_product.yaml这个命令会输出每个类别的 mAP50、mAP50-95以及 Precision、Recall。重点看 mAP50-95这个指标更能反映模型在不同 IoU 阈值下的综合定位能力。如果你的 mAP50 高但 mAP50-95 低说明模型框得不够准可以尝试加大 imgsz 或增加训练轮数。推理测试yolo predict modelruns/detect/trainX/weights/best.pt source/root/datasets/mall_product/images/val/img_001.jpg saveTrue如果推理结果正常且类别名称显示正确那整个流程就通了。接下来你要做的就是反复调参比如改 mosaic、换优化器、尝试不同的 imgsz让精度再上一个台阶。4. 迁移训练踩坑实录8个典型问题与排查这部分是我真正花时间最多的地方。大部分问题不调几轮根本发现不了有些坑甚至会让你怀疑是权重文件的问题。我把常见问题整理成了速查表后面再逐个展开讲细节。现象常见原因解决方案训练时报 tensor size 不匹配负载权重和模型结构类别数不一致检查权重是 80 类还是 365 类确认模型用 yaml 还是 pt自动下载了 COCO 权重而不是 Objects365命令行没指定 objects365 权重路径手动指定 modelbest_obj365.pt验证 mAP 为 0标签 class_id 和 yaml names 对不上检查标签里最大值是否小于 nc训练很快但验证集表现差数据增强过强或过拟合调低 mosaic增加数据量或使用更强正则显存不足batch 太大或 imgsz 太大降低 batch或从 640 降到 544Loss 出现 NaN学习率过大或 AMP 精度问题调低 lr0或设置 ampFalse训练不收敛标签坐标没有归一化检查 txt 中坐标是否在 0-1 之间推理类别错乱yaml names 顺序和 labels 不一致统一类别编号顺序4.1 类别数不匹配365和80之间的冲突最常见的报错是这样RuntimeError: The size of tensor a (365) must match the size of tensor b (80)这个报错通常出现在你用 Objects365 的权重加载一个 COCO 类别的模型或者反过来。比如你写了modelbest_obj365.pt但你的数据 yaml 里 nc80加载时最后一层检测头是 80 类而权重里是 365 类就会炸。解决办法其实很简单用 model权重文件路径的方式加载让 Ultralytics 自动处理头部层重建。但如果你用的是类似YOLO(yolo11s.yaml).load(best_obj365.pt)的方式就要保证 yaml 里的 nc 是 365或者接受它重新初始化 head。我建议统一用yolo train modelbest_obj365.pt datamall_product.yaml ...让它自己决定怎么重建。训练日志里如果出现 “Overriding model.yaml nc80 with nc8” 这种提示就说明框架已经自动处理了不用惊慌。4.2 自动下载了COCO权重不是Objects365很多新手会犯这个错误命令行写了yolo train modelyolo11s.pt datamall_product.yaml以为换了 data 就是迁移训练实际上这个命令加载的是 COCO 预训练的 yolo11s.pt不是 Objects365。因为yolo11s.pt是 Ultralytics 内置的 COCO 权重名。判断自己到底用的是哪个权重很简单训练开始时看日志打印的第二行或者权重路径。如果不确定就先打印一下加载后模型的 ncfrom ultralytics import YOLO model YOLO(best_obj365.pt) print(model.model[-1].nc) # 如果显示 365说明用对了另外有些教程会让你先yolo11s.yaml再load(best_obj365.pt)这种写法如果 yaml 里默认 nc80加载时也会做头部重建很容易让人误以为权重没生效。我后来的习惯是只认modelpt 文件这一种方式不混用 yaml 和 pt。4.3 数据标签格式和类别编号错位这个坑坑过我好几次。YOLO 训练对标签格式要求极其严格一个错位就会让验证集 mAP 直接归零因为你模型学到的 class 0 是“牙刷”但验证标签里 class 0 是“毛巾”预测对也判错。检查方法随机打开一个验证集标签文件看 class_id 是否在 0 到 nc-1 的范围内再看和 yaml names 的顺序是否一致。我曾经有过一次训练集是从标注平台导出的序号从 1 开始验证集是另一批导出的序号从 0 开始结果模型训练时分类头一直学不对损失居高不下最后排查出来就是类别编号错位。这个问题最直接的预防方式整理数据时用同一个脚本统一处理所有标签走同一套编号映射不要中途手动修改。另外标签文件里的坐标一定要归一化。如果你看到 txt 里有数字大于 1那肯定是没归一化模型根本没法收敛。我之前写转换脚本时忘记除以图像宽高跑了一晚上损失都不下降第二天发现坐标全是像素值那次教训非常深刻。4.4 显存不足、训练速度慢的解决思路YOLO11s 虽然是小模型但预训练权重加载后训练时依然需要不少显存。如果你的显卡是 8G 或 6Gbatch16 在 640 分辨率下可能会 OOM。解决方案有两个一是减小 batch改为batch8或batch4。注意减小 batch 以后建议用梯度累积补偿Ultralytics 里没有直接的累积参数但你可以等效地把训练轮数加倍或者手动放大 batch 后用更大显存跑。二是降低 imgsz比如imgsz544。这个改动对精度影响不大但显存占用会明显下降。如果你检测的目标本来就很小降低 imgsz 会导致小目标更难被识别所以尽量用梯度累积而非降分辨率。训练速度慢的问题我建议先把cacheTrue开起来这个参数会把图像缓存到内存里训练时省去每次读盘的 IO 时间实测速度能提升 30% 以上。代价是内存占用变高如果你的机器内存只有 16G而数据量上万张图可能会撑爆内存这时可以设置cacheram默认或cachedisk。4.5 AMP混合精度导致的NaN训练损失AMP 混合精度训练是一个双刃剑。默认情况下 Ultralytics 是开启 AMP 的ampTrue大多数时候没问题但我的一个客户项目里训练到第 7 个 epoch 时 loss 突然变成 NaN然后一路 NaN 到结束。排查了很久发现是 AMP 在特定数据集上数值溢出导致的。遇到这种情况最简单的办法是关闭 AMPyolo train modelbest_obj365.pt datamall_product.yaml epochs100 imgsz640 batch16 ampFalse关闭后训练速度会慢一点大约慢 10%-15%但稳定性会好很多。如果关闭 AMP 后依然 NaN就要检查学习率是不是太高把lr00.001改成lr00.0005试试。另一个注意点是如果你用了权重衰减过大的设置也可能导致 loss 异常。我的经验是迁移训练时权重衰减一般设在 0.0005 就好不要超过 0.001否则预训练权重里的有效特征会被正则项快速削弱。4.6 冻结策略怎么选迁移训练中一个很有用的技巧是冻结预训练模型的一部分层让训练更稳定、速度更快。Ultralytics 提供了freeze参数单位是层数。比如freeze10表示冻结模型的前 10 层通常是主干网络的卷积层只训练后面的 neck 和 head。我的经验是如果你的数据集很小几百张图从 Objects365 预训练权重迁移过来时可以先冻结前 10 层或前 15 层训练 30 个 epoch然后再解冻全部层精调 70 个 epoch。这样能防止小数据下主干网络被过度调整导致过拟合。代码上可以用两阶段脚本# 第一阶段冻结前15层 yolo train modelbest_obj365.pt datamall_product.yaml epochs30 freeze15 imgsz640 batch16 # 第二阶段解冻全部继续从第一阶段权重训练 yolo train modelruns/detect/trainX/weights/best.pt datamall_product.yaml epochs70 imgsz640 batch16如果数据量比较大5000 张以上就直接训练不冻结效果更好。冻结阶段并不会提高最终精度上限它主要是帮你稳定训练过程、减少过拟合。很多人在小数据集上把全部层放开训练结果 mAP 反而低就是这个原因。5. 使用效果、工具选型与最终建议写完前面那些实操我觉得很有必要把“到底值不值得换”这个问题讲透。毕竟 Objects365 预训练权重不是官方默认你需要多花功夫去找或者自己训时间成本在那里。我前阵子做了一个非常直观的对比实验同一个货架商品数据集1500 张训练图、8 个类别其他条件完全一致只把预训练权重从 COCO 换成 Objects365。结果如下指标COCO 预训练Objects365 预训练收敛到 mAP500.5 所需 epoch约 45 轮约 28 轮最终 mAP500.670.74最终 mAP50-950.410.47小目标面积32x32召回率0.320.41注意这只是单次实验的结果不代表所有场景都这样但训练了 10 轮以内就能看出明显趋势Objects365 权重下的 loss 下降更快、mAP 上升更早。如果你的项目在 COCO 预训练下迟迟达不到预期换一个覆盖更广的预训练权重是非常值得尝试的方向。5.1 从COCO切到Objects365效果到底差多少结合多个项目经验我的结论是效果差异主要取决于你的目标任务和 COCO 的重合度。如果你的任务类别在 COCO 里能找到比如人、车、猫、狗、椅子COCO 预训练和 Objects365 预训练的差距很小可能就一两个点。但如果你做的是细粒度物体识别、工业零件分类、货架商品识别、垃圾分类这类任务差距会非常明显mAP50 提升 5 个点以上都不奇怪。原因很简单预训练阶段模型在 365 类里学到的大量细粒度特征直接帮你把“这些物体的边缘、纹理、形状”等底层特征建好了微调时只需要适配最终类别。另一个观察是Objects365 预训练对小数据集尤其友好。同样的 1500 张训练图COCO 预训练得到的模型明显更容易过拟合训练集 loss 降得很低但验证集 mAP 停滞Objects365 预训练权重的泛化能力更强验证集 mAP 能持续爬到更高水平。这个优势的来源是预训练数据本身差异巨大模型在 365 类上学会的“相似类判别能力”在小数据微调时起到了正则化的作用。5.2 什么时候不推荐用Objects365预训练我反复强调过Objects365 预训练不是万能药。遇到下面几种情况我反而建议你继续用 COCO 预训练或者干脆从头训第一任务类别极度单一且场景固定。比如固定工位的注塑件缺陷检测目标就是那几种缺陷背景几乎不变。COCO 预训练足够提取边缘、纹理特征换 365 反而可能因为预训练分布和真实分布差异大需要额外训练轮数去“纠正”。第二模型部署对权重大小和加载速度有严格限制。Objects365 预训练权重本身不会改变模型结构所以 .pt 文件大小和 COCO 权重几乎一样这一点不用太担心。但如果你在 Objects365 上训练的数据集类别特别多保存的权重文件里会包含一个长的 names 数组这个对大小影响可以忽略。第三你手里的数据量已经非常大比如几万张同时训练资源充足。这种情况下预训练权重的优势会被数据量稀释从头训练可能得到同等甚至更好的效果。但即便如此用一个预训练权重做起点仍然能省下很多时间所以我的建议是数据再大也先加载预训练权重试一轮成本很低收益往往为正。第四时间特别紧、只求快速上线一个 baseline。如果你只有两天时间不要折腾 Objects365先用yolo11s.pt跑通流程再说。Objects365 的权重验证和下载可能花掉半天这在紧急项目里根本不划算。5.3 后续可扩展的方向如果你已经成功把 Objects365 预训练权重迁移到了自己的任务上并且效果验证没问题接下来还有几个方向可以做一是尝试在 Objects365 预训练基础上进一步做“中间域微调”。比如先在公开的、和你的任务相近的大数据集如 VisDrone 做航拍、xView 做遥感上再训一段再迁移到自己的小数据上这种二次迁移往往能再涨几个点。二是用 Objects365 预训练权重做主动学习。把模型部署到未标注数据上自动筛选出置信度低或者类别分布罕见的样本让标注人员优先标这些能大幅降低标注成本。我在做货架商品识别时用这种方法把标注量压缩了大约 40%最终精度和全量标注差不多。三是把 YOLO11s 换成其他 backbone 做对比实验。比如 YOLO11m、YOLO11l 在使用相同 Objects365 预训练策略时提升幅度往往比 s 版还明显因为在更大模型里预训练特征的容量更大。如果你的设备能扛得住值得跑一轮试试。根据我个人实际操作经验最后再说一点在跑迁移训练之前花 10 分钟打印一下权重的基本信息确认类别数、确认主干结构、确认加载路径这 10 分钟能帮你避免后面一整晚的无效训练。本文还有配套的精品资源点击获取
返回列表