YOLO11多任务学习:目标检测与实例分割一次搞定
2026/9/6 16:24:18 网站建设 项目流程

简介:这是一份面向计算机视觉开发者的YOLOv11进阶文档,聚焦目标检测与实例分割的联合训练框架,系统讲解如何用单阶段模型一次推理同时完成多任务识别,并解决多任务学习中的特征共享、损失平衡与训练优化等关键问题。整包为单个PDF文件,压缩包约2.18MB,文档共52页,支持目录章节跳转、阅读器大纲显示与章节快速定位,排版与图表清晰完整。内容按完整技术链路展开:从YOLO系列发展回顾、YOLOv11核心创新,到多任务学习原理、检测与分割双分支设计、联合损失函数、数据增强、训练优化策略及实验结果分析,读者可按目录逐章学习或快速定位所需模块。目前已有274人学习下载,适合需要提升检测效率、入门或深入YOLOv11多任务建模的算法工程师与研究人员作为系统参考资料。 目标检测做到后半程,几乎所有人都会遇到同一种“尴尬需求”:光是框出目标位置已经不够,还得把目标轮廓一起拿出来。我做水下鱼类监测时,客户要统计每条鱼的体长和朝向,矩形框完全顶不住;做无人机鸟类调查时,一堆鸟挤在一起,检测框会把好几个个体重叠成一个;做工业零件缺陷检测时,划痕的边缘形态比中心坐标更有价值。这种“既要框、又要轮廓”的场景,正是目标检测和实例分割必须同时上场的时刻。YOLOv11多任务学习提供了一套很务实的解法:一个网络、一套训练流程,推理时同时输出检测框和像素级mask。官方命名其实是YOLO11,社区里叫YOLOv11的更多,下面的正文我统一用YOLO11来写,这并不影响任何代码和配置。

这篇博客我把这套联合训练框架从网络结构、数据准备、训练参数、loss机制到推理保存一次理清楚,最后再聊几个实测最容易翻车的地方。适合已经跑通过YOLO检测模型、想往实例分割方向进阶的同学,也适合手里数据集只有检测框、正在纠结要不要转分割的同行。

1. 一次前向同时拿到框和mask:YOLO11的多任务设计逻辑

1.1 很多人以为的多任务,其实是两遍串行推理

先纠正一个常见的理解偏差。网上聊“检测+分割”时,有人会提出这样的方案:先用检测模型框出目标,再按裁剪区域把每个目标送进分割模型,最后把掩膜贴回原图。这种方案问题非常明显——推理时间几乎翻倍,而且误差会一级一级放大。检测框稍微偏一点,裁剪区域就把目标切掉一块,分割模型再努力也救不回来。

YOLO11的seg系列模型不是这么玩的。训练阶段,模型同时接收检测分支的监督信号和分割分支的监督信号,两者共享同一个Backbone提取的特征。推理时只需前向一次,检测Head输出类别和框,分割Head输出掩膜。这才是真正的multi-task,而不是流水线式的task-chaining。它学到的特征同时对两个任务负责,检测和分割互为正则,泛化能力比两个独立模型轮流跑更稳。

1.2 从网络结构看双Head:共享的Backbone,专精的各分支

YOLO11的网络结构大致可以切成三段:Backbone负责提特征,Neck负责把不同尺度的特征融合起来,Head输出最终结果。多任务的秘密全部集中在Head部分。以yolo11n-seg为例,它的Head里既有类似Detect的子分支,用于输出box、类别和置信度,又有专门的分割分支,输出mask系数。推理时,分割分支拿这些系数和网络生成的一组原型mask做线性组合,再上采样回原图尺寸,就得到每个实例的像素级分割结果。

这个设计与“共享视觉皮层、专科医生各看各的”很像。Backbone像是大脑的初级视觉区,把边缘、纹理、形状这些通用信息都抽出来;检测分支只看“东西在哪”,分割分支还要回答“边界精确到什么程度”。因为两个分支复用同样的特征,训练时不会出现一个是另一个的“上游结果”这种纠缠关系,各自梯度的冲突反而被共享层缓解,收敛过程比分开训练两个模型省心不少。很多人把多任务和多模态混为一谈,这里说清楚:YOLO11的多任务是指同一张图像上的检测任务和分割任务,而不是多模态融合。

1.3 代价与收益:参数只多了一点点,功能多了一大截

多一个分割分支,代价没有想象中大。以Ultralytics官方实现为参考,yolo11n纯检测版本参数量在2.6M左右,yolo11n-seg的参数量大概在2.9M上下,多出来的就是分割分支那一小部分。推理耗时确实会增加,但远低于“检测+裁剪+再分割”的串行方案。单张640分辨率图片,GPU上det版本耗时约4~6ms,seg版本大约6~8ms,整体多了两三毫秒,这对绝大多数实时应用都不是问题。

模型输出内容参数量级推理耗时(参考)适合场景
yolo11n.pt检测框+类别约2.6M只需要定位的普通检测
yolo11n-seg.pt检测框+类别+实例掩膜约2.9M需要轮廓、面积、朝向分析

如果你在犹豫“要不要加分支”,我的建议是:只要下游业务可能用到轮廓信息,直接上seg版本,后面省去二次开发的成本远大于这点参数损耗。

2. 联合训练前的三件套:环境、权重文件与数据标注

2.1 环境配置别贪多,能跑通就行

yolov11环境配置是提问率非常高的话题,但实际一点都不复杂。Python版本建议3.9到3.12之间,核心依赖就是PyTorch和Ultralytics。装好Python之后,一条命令解决:

pip install -U ultralytics

如果机器上有NVIDIA GPU,先根据自己显卡驱动装对应CUDA版本的PyTorch,再装ultralytics。没有GPU也不用灰心,CPU能跑训练和推理,只是速度慢很多,做实验调通流程完全够用。实例分割训练比纯检测吃显存,我自己用8GB显存跑yolo11n-seg、imgsz=640、batch=16是稳的,再往上提imgsz就得降batch。先跑通最小案例再调参,比一开始就追求大模型靠谱得多。

装完后命令行里敲:

yolo predict model=yolo11n-seg.pt source=bus.jpg

能看到一张自动标好框和掩膜的bus图,环境就算彻底通了。

2.2 权重文件、任务类型和YAML配置的对应关系

初学的人经常在权重文件上栽跟头。yolo11n.pt是纯检测模型,你拿它调segment接口,它不会输出mask。yolo11n-seg.pt才是检测+分割联合模型。官方提供的yolo11n-seg.yaml是模型结构的定义文件,里面是Backbone和Head的结构描述,不是数据集配置。

做自定义数据集时,需要同时准备两样东西。第一份是数据集yaml,文件里写明数据集路径、类别名和类别数。典型内容如下:

path: ./datasets/my_dataset train: images/train val: images/val names: 0: fish 1: crab

第二份是模型结构yaml,yolo11n-seg.yaml里有一个关键字段nc,要和数据集yaml里的类别数保持一致。如果你有5类目标,就把nc改成5,然后基于它去训练。运行时,Ultralytics会根据你加载的是det还是seg权重自动推断任务类型。所以文件用错,后面全是坑,第一步先分清这两份yaml的作用。

2.3 分割标注是硬门槛,检测框只是顺带的产物

联合训练的数据要求非常直接:每张训练图,既要能提供检测框监督,也要能提供mask监督。YOLO格式的分割标注和检测标注不同,每一行代表一个实例,格式是:

类别ID x1 y1 x2 y2 x3 y3 ...

坐标全部是归一化到0~1之间的浮点数,按顺序描述多边形轮廓的所有顶点。比如一行标注可能是这样:

0 0.682 0.380 0.620 0.420 0.560 0.390 0.580 0.460

有意思的地方来了:检测框根本不用单独标。从这些多边形顶点里取横纵坐标的最小值和最大值,就是目标框的左上角和右下角:

x_min = min(px); x_max = max(px) y_min = min(py); y_max = max(py)

所以只要你老老实实标好了轮廓,检测框是“免费”生成的。反过来则不成立——只有矩形框的数据集,补不出轮廓。很多人迁移训练时拿纯检测数据集强行跑seg模型,训练日志里seg_loss纹丝不动,预测出来的mask糊成一团,就是这个原因。

如果你用的是LabelMe这类标注工具,导出的是JSON格式,需要转成YOLO txt。一个最小可用的转换脚本大概长这样:

import json import numpy as np def labelme_to_yolo(json_path, txt_path, class_names): with open(json_path, "r", encoding="utf-8") as f: data = json.load(f) img_w, img_h = data["imageWidth"], data["imageHeight"] lines = [] for shape in data["shapes"]: label = shape["label"] if label not in class_names: continue cls_id = class_names.index(label) pts = np.array(shape["points"], dtype=np.float32) pts_norm = pts / [img_w, img_h] poly = " ".join(f"{x:.6f} {y:.6f}" for x, y in pts_norm) lines.append(f"{cls_id} {poly}\n") with open(txt_path, "w", encoding="utf-8") as f: f.writelines(lines)

如果只是想先跑通流程,官方自带的coco8-seg数据集是最合适的实验对象,切好图、标好格式,直接拿来验证训练命令没问题。

3. 训练实操:命令、参数和训练日志解读

3.1 一个能直接照抄的训练命令

数据备好后,训练命令比想象中简短。终端里执行:

yolo segment train data=coco8-seg.yaml model=yolo11n-seg.pt epochs=100 imgsz=640 batch=16

想更灵活就写Python脚本:

from ultralytics import YOLO model = YOLO("yolo11n-seg.pt") # 加载预训练联合模型 model.train(data="coco8-seg.yaml", epochs=100, imgsz=640, batch=16, device=0)

跑起来后,训练好的权重默认保存在runs/segment/train/weights/best.pt。注意,保存路径是segment目录而不是detect目录,因为任务类型已经变了。这个细节经常有人找不到输出文件。

3.2 参数怎么定:imgsz管精度,batch管显存

训练参数里面,最值得花时间调的是imgsz和batch。imgsz决定输入分辨率,目标越小,越需要大分辨率。640起步是常规选择,小目标明显的场景可以提到1024甚至1280,代价是显存和训练时间同步上涨。batch受到显存限制,8GB显存跑imgsz=640时batch=16比较稳,显存不够就降batch,别硬撑。epochs通常从100开始,加上早停机制,模型收敛后会自动停下来,不会白白烧算力。

参数推荐起始值影响
imgsz640分辨率越高,小目标越准,显存占用越大
batch8~16主要受显存限制,过小影响BN稳定性
epochs100配合早停,收敛后自动停止
device0指定GPU,CPU训练极慢
cacheTrue小数据集可以缓存到内存,加速训练

另一个容易被忽略的是增强策略。Ultralytics默认最后10个epoch会关闭mosaic增强,让模型在接近真实分布的数据上微调。如果你发现训练后期loss震荡得厉害,优先检查是不是增强策略和早停设置打架。

3.3 训练日志里的“双mAP”怎么读

目标检测训练过程中的评价标准,在联合训练里要看成双份的。YOLO11训练日志会同时输出box_mAP和mask_mAP,前者衡量检测框的定位精度,后者衡量分割掩膜和真实轮廓的吻合程度。早停的逻辑也是“谁涨都不行”,两个mAP都稳定不涨才真正停。

除了mAP,还要盯几项loss:box_loss、cls_loss、dfl_loss是检测分支的,seg_loss是分割分支的。正常曲线是前几十个epoch快速下降,之后慢慢走平。如果seg_loss长期不降,大概率是数据里mask标注质量太差,而不是网络结构的问题。训练结束后,runs/segment/train/里会生成results.png、confusion_matrix.png、PR_curve.png这些图,PR曲线上不同类别的曲线越贴右上角越好,混淆矩阵对角线越深越好。很多人只看一个mAP数值,忽略了PR曲线里的类别不均衡信息,这个习惯得改。

4. 多任务loss机制和调优方向

4.1 检测分支的loss不是单一指标

YOLO11检测分支的总损失由几个部分拼成:分类损失关注每个框的类别对不对,常用BCE;框回归损失关注预测框和真实框的重合度,用的是一类基于IoU的损失;还有一个分布焦点损失DFL,负责让回归输出的概率分布更锐利。这三个损失各自作用在不同维度,训练时按权重加总,反向传播梯度。

分类损失高,说明目标被认错,或背景被误认;回归损失高,说明框的位置或者宽高偏了;DFL高,说明边界不够果断。实战中我发现,多数框不准的问题出在回归损失上,尤其小目标的框,因为大分辨率下gt标注的小偏移会被放大。

4.2 分割分支如何生成mask

分割分支的思路可以理解为“先有原型,再做组合”。网络会生成固定数量的原型mask,相当于一组基础形状模板;同时对每个实例输出一组mask系数。推理时把系数和原型mask加权求和,再上采样到原图分辨率,得到这个实例的像素级掩膜。这套机制最大的好处是计算量可控,不会像全卷积逐像素分类那样在内存上爆炸。

训练时,分割损失计算的是预测mask和真实标注mask之间的差异,常见的是带权重的二值交叉熵。Ultralytics默认实现里会用mask_ratio下采样mask再算loss,mask_ratio=4意味着mask在下采样到特征图分辨率后参与计算,这样既保留了轮廓信息,又不会吃掉太多显存。同时训练还支持overlap_mask,即同一像素允许多个实例的mask重叠,适合密集遮挡场景。

4.3 梯度同时回流,Backbone才是最大受益者

联合训练最核心的机制在这里:检测分支的梯度和分割分支的梯度会同时回流到Backbone。这意味着主干网络被“两路监督”夹击,既能学到判别性强的语义特征,又保留了精细的边界特征。孤立的检测模型会倾向于只关注可分的局部区域,而多加一路分割监督后,模型被迫保留更多几何细节,这类细节对后续小目标检测同样有益。

调优时,建议先动imgsz和数据增强,不要一上来就改loss权重。只有当两个任务的指标差距明显失衡时,再去调整加权系数。比如mask明显粗糙,而box精度不错,可以适当提高分割分支的loss权重;反之如果seg分支盖过了检测分支导致漏检变多,就把检测分支权重拉回来。本质上多任务模型的调优是在找平衡点,不是把某一项推到极致。

5. 推理输出、结果保存与小目标实战优化

5.1 从predict结果里同时拿检测框和mask

训练完,推理阶段才能感受到多任务的爽。predict返回的Results对象里,boxes和masks是并排躺着的:

from ultralytics import YOLO model = YOLO("best.pt") results = model.predict("test.jpg") for r in results: boxes = r.boxes.xyxy.cpu().numpy() # [N,4] confs = r.boxes.conf.cpu().numpy() # [N,1] cls_ids = r.boxes.cls.cpu().numpy().astype(int) # [N,1] masks = r.masks.data.cpu().numpy() # [N, H, W]

这里有个新手容易踩的坑:masks.data是模型输出的掩膜张量,默认在GPU上,直接访问会报类型错误。先.cpu().numpy()再处理,省得卡半天。r.masks.xy字段返回的是每个实例轮廓的多边形坐标,对面积计算、朝向判断来说比像素数组更好用。

5.2 保存推理结果的五种姿势

yolov11预测后保存结果的方式有好几种,按需求选择:

  • save=True直接在原图上画好框和mask,输出一张可视化图,适合快速看效果。
  • save_txt=True把检测结果写成txt文件,每行包括类别、置信度、框坐标,适合做后处理。
  • save_crop=True把检测到的目标从原图裁剪成独立小图,适合做目标图库采集。
  • plot()方法返回带标注的BGR numpy数组,可以自由叠加其他信息后再保存,适合定制化输出。
  • 把boxes的坐标、置信度、类别和masks的多边形坐标整理成字典,再dumps成JSON,适合对接业务接口。
output = [] for r in results: output.append({ "boxes": r.boxes.xyxy.cpu().tolist(), "confs": r.boxes.conf.cpu().tolist(), "cls": r.boxes.cls.cpu().tolist(), "mask_polygons": r.masks.xy if r.masks is not None else [] })

实际项目里我基本都会生成“可视化图+结构化JSON”两份结果,一份给人审阅,一份给程序消费,效率高很多。

5.3 小目标优化与垂直场景迁移

最后聊一点yolov11小目标优化和实际迁移的经验。很多做无人机航拍、遥感、水下检测的朋友提过小目标检测困难,检测框时有时无,mask尤其容易碎。最立竿见影的改进是提高imgsz到1024或1280。航拍图里目标很小,模型在640分辨率下能得到的有效像素太少,换大分辨率后mAP往往能涨好几个点,比改网络结构性价比高得多。

第二种方案是换用带P2层的检测头,让模型从更高分辨率的特征图上去找目标。这个需要手动改动模型结构yaml,在Neck输出中加入下采样倍数更小的特征层。第三招是用切片推理,把大图切成若干小块分别预测,再把mask拼回去。这一招对超大尺寸遥感图特别有效,代价是推理时间变长,适合离线处理场景。

数据层面也容易踩坑:小目标标注的工作量很大,很多人偷懒把目标标得很马虎,反而让模型学会了“别把目标当目标”。宁可少标一些、每张图只标清晰的实例,也不要硬凑数量。标注质量对分割效果的影响,比模型结构的影响更直接。水下目标边缘模糊、遮挡严重,分割掩膜天然不稳定,这类场景建议训练时把overlap_mask打开,推理后再用形态学闭运算把细碎空洞补掉,能明显改善视觉观感。


最后说一个我踩了不止一次的坑。很多人上来就拿着yolo11n-seg.pt做迁移训练,以为只要有检测框数据就能学分割,结果训练十几轮seg_loss一路躺平,输出的mask完全不能用——因为分割分支根本收不到监督信号。实例分割需要的是多边形轮廓标注,检测框是补不出边缘的。如果眼前的人力只够标框,就老老实实用检测模型;如果业务确实需要轮廓,宁可把标注数量减半,也要保证分割标注的质量。另一个建议是,别一上来就折腾各种改进结构,先用yolo11n-seg跑一个baseline,把imgsz提上去,把数据质量搞干净,你会发现基线模型的潜力远比你想象中大。

本文还有配套的精品资源,点击获取

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

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

立即咨询