YOLO11 整体架构、多任务能力:目标检测、实例分割、人体关键点 (姿态) 检测、图像分类;模型缩放设计、骨干网络、FPN 特征金字塔、参数冻结迁移学习、损失函数、NMS 非极大值抑制、训练与部署最佳实践。
一、YOLO 顶层设计理念
1. 网络两大组成部分
- Backbone 骨干网络(特征提取器):从图像提取多层次图像特征。
- Head 输出头:基于骨干网输出的特征,完成检测 / 分割 / 关键点 / 分类任务。
2. "大小杯" 模型缩放策略
通过调节depth_multiple 深度系数、width_multiple 宽度系数、max_channels 最大通道数,生成 5 个规格模型适配不同硬件:
表格
| 型号 | 等级 | 适用场景 |
|---|---|---|
| n | Nano 超小杯 | 移动端、边缘设备,追求速度 |
| s | Small 小杯 | 轻量业务,速度精度均衡 |
| m | Medium 中杯 | 平衡精度与速度,多数业务首选 |
| l | Large 大杯 | 追求较高精度,GPU 资源充足 |
| x | Extra‑Large 超大杯 | 极致精度,算力消耗大 |
scales 配置示例
scales:
n: [0.50, 0.25, 1024]
s: [0.50, 0.50, 1024]
m: [0.50, 1.00, 512]
l: [1.00, 1.00, 512]
x: [1.00, 1.50, 512]
3. YOLO 三层层次化封装
- 底层:原生 PyTorch 基础算子
- 中间层(自定义基础模块)
- Conv:基础卷积
- C3k2:改进 CSP 跨阶段部分模块
- C2PSA:位置敏感注意力模块,强化空间位置信息
- SPPF:空间金字塔池化,多尺度特征融合
- 顶层(任务模型):检测 Detection、分割 Segmentation、关键点 Pose、分类 Classification。
二、YOLO11 内部网络架构
1. Backbone 骨干网络
- 多次
Conv卷积做下采样,得到 P1/2、P2/4、P3/8、P4/16、P5/32 不同尺度特征; C3k2模块提取深层特征;SPPF空间金字塔池;C2PSA位置注意力模块增强特征表达。
2. FPN 特征金字塔 Head 头部
采用自顶向下上采样融合 + 自底向上下采样增强:
- 上采样,高层语义特征和中层特征 Concat 拼接融合;得到小、中、大多尺度输出;
- 对不同大小目标分别使用对应尺度特征图检测;小目标用浅层,大目标用深层特征。
三、四大任务:检测|实例分割|关键点检测|图像分类
YOLO11 一套框架支持四类 CV 任务,更换 yaml/pt 权重即可切换。
1. 实例分割 Instance Segmentation
在目标检测(框出物体)基础上,额外输出每个物体的像素掩码 mask。
- 原理:检测头基础上增加分割分支,使用掩码原型 Mask Prototypes,通过原型掩码线性组合得到实例掩码,兼顾速度。
- 推理关键属性
results[idx].masks.data:掩码张量results[idx].masks.xy:物体轮廓多边形坐标
- 训练:使用
yolo11n‑seg.yaml,编写分割数据集 yaml 配置。
2. 人体关键点检测 Pose Estimation
- COCO 标准定义17 个人体关键点:鼻子、双眼、双耳、肩、肘、腕、髋、膝、脚踝。
- 标注格式三元组
[x, y, visibility]- x,y:归一化坐标
- visibility:0 未标注;1 标注但不可见;2 标注且可见
- 推理结果:
result.keypoints.data形状[人数,17,3];keypoints.conf关键点置信度。 - 训练:
yolo11n‑pose.yaml,使用 coco8‑pose 数据集。
3. 图像分类 Classification
- 架构:去掉检测 / 分割头,只保留分类输出头
Classify; - 训练:
yolo11n‑cls.yaml,输入数据集 yaml,输出类别 logits。
四、数据集 yaml 配置
- 分割数据集 yaml:指定 train、val 图像路径,定义类别 id‑name 映射;
- COCO 标准数据集:COCO8‑seg,80 类目标,检测、分割、姿态任务通用。
五、迁移学习:参数冻结 Freeze
-
原理:
model.parameters().requires_grad = False,参数只做前向传播,不参与反向传播更新。 -
应用场景
- 冻结 Backbone 骨干网络,只训练 Head 输出头;
- 算力不足,减少参数量,节省显存;
- 渐进式解冻,做微调 finetune。
冻结全部骨干网络示例
for param in model.backbone.parameters():
param.requires_grad = False
六、核心数学算法
1. YOLO 总损失(多任务联合损失)
\(L_{total }=L_{cls }+L_{box }+L_{obj }+L_{seg }\)
- \(L_{cls}\):分类损失(交叉熵)
- \(L_{box}\):边界框回归损失(IoU Loss)
- \(L_{obj}\):目标置信度损失(二分类交叉熵)
- \(L_{seg}\):分割损失(Dice Loss + Focal Loss)
2. IoU 交并比
\(IoU=\frac{ Area _{intersection }}{ Area _{union }}=\frac{|A \cap B|}{|A \cup B|}\)
3. NMS 非极大值抑制
作用:过滤同一物体重复生成的大量重叠检测框。 算法步骤:
-
将所有框按照置信度从高到低排序;
-
保留置信度最高的框;
-
计算其余框和当前保留框 IoU,IoU 超过阈值直接丢弃;
-
对剩下的框循环执行,输出最终保留框。
def nms(boxes, scores, iou_threshold):
indices = scores.argsort()[::-1]
keep = []
while len(indices) > 0:
current = indices[0]
keep.append(current)
if len(indices) ==1:
break
ious = compute_iou(boxes[current], boxes[indices[1:]])
indices = indices[1:][ious <= iou_threshold]
return keep
七、训练监控文件
训练自动生成runs/输出目录:
results.csv:每轮全部指标- 各类曲线图:损失曲线、PR 曲线、MaskF1 曲线
confusion_matrix.png混淆矩阵- weights 文件夹:
best.pt最优权重、last.pt最新权重
八、训练优化策略
- 数据增强:Mosaic 四图拼接、MixUp 图像混合、Copy‑Paste 实例复制粘贴、Albumentations 高级变换。
- 超参数 :
lr0初始学习率、momentum动量、weight_decay权重衰减、warmup_epochs预热轮数。 - 模型选型:移动端选 n;实时业务选 s/m;高精度选 l/x。
九、模型部署优化
导出多种格式实现跨平台部署
model.export(format="onnx", optimize=True) # ONNX通用中间格式
model.export(format="engine", device=0) # TensorRT GPU硬件加速
十、整体总结
- YOLO11 统一一套架构,支持检测、实例分割、人体关键点、图像分类四大计算机视觉任务;
- 网络结构 = Backbone(C3k2 + SPPF + C2PSA 注意力) + FPN 多尺度融合 Head;
- 模型 n/s/m/l/x 缩放方案,适配边缘设备到高性能 GPU;
- 迁移学习可以冻结骨干网络,只训练头部,降低算力消耗;
- 底层关键算法:IoU 计算、NMS 非极大值抑制;多任务联合损失函数同时优化分类、框回归、分割;
- 工程流程:准备对应任务数据集 yaml → 选择对应 yaml/pt 模型 → 训练监控指标 → 导出 ONNX/TensorRT 部署。
YOLO11 实例分割+人体关键点检测
依赖安装
python
pip install ultralytics matplotlib opencv-python numpy
1. 实例分割(YOLO11‑seg)推理代码
python
from ultralytics import YOLO
import os
import cv2
from matplotlib import pyplot as plt
os.environ["KMP_DUPLICATE_LIB"] = "TRUE"
# 加载预训练分割模型
model = YOLO("yolo11n-seg.pt")
# 推理图片
img_list = ["000000000025.jpg", "000000000034.jpg"]
results = model(source=img_list)
# 取第一张结果
res = results[0]
# 绘制带掩码的可视化图
plot_img = res.plot()
# 获取掩码mask张量
mask = res.masks.data.cpu()[0, :, :]
# 获取物体轮廓点
polygon_pts = res.masks.xy[0].astype(int)
# 在原图绘制轮廓线
orig_img = res.orig_img
draw_poly = cv2.polylines(orig_img.copy(), [polygon_pts], isClosed=True, color=(255,0,0), thickness=2)
# 绘图展示
plt.figure(figsize=(14,6))
plt.subplot(1,3,1)
plt.imshow(plot_img[:, :, ::-1])
plt.title("分割效果图")
plt.axis("off")
plt.subplot(1,3,2)
plt.imshow(mask, cmap="gray")
plt.title("掩码mask")
plt.axis("off")
plt.subplot(1,3,3)
plt.imshow(draw_poly[:, :, ::-1])
plt.title("轮廓多边形")
plt.axis("off")
plt.show()
# ---------------- 实例分割训练示例 ----------------
if __name__ == "__main__":
seg_model = YOLO("yolo11n-seg.yaml")
train_result = seg_model.train(
data="cat_dog_seg.yaml",
epochs=10,
imgsz=640,
batch=8,
workers=1
)
关键属性说明表格
| 属性 | 说明 |
|---|---|
res.masks.data |
所有实例掩码张量 |
res.masks.xy |
每个实例轮廓多边形坐标 |
res.plot() |
绘制掩码、框、类别,返回 BGR 图像 |
2. 人体关键点检测(YOLO11‑pose)推理代码
COCO 定义 17 个人体关键点,输出格式
[x, y, visibility]visibility:0 未标注,1 标注不可见,2 标注可见
python
from ultralytics import YOLO
import os
from matplotlib import pyplot as plt
os.environ["KMP_DUPLICATE_LIB"] = "TRUE"
# 加载关键点姿态模型
model = YOLO("yolo11n-pose.pt")
results = model(source=["img1.jpg", "img2.jpg"])
res0 = results[0]
# 绘制带关键点的图像
vis_img = res0.plot()
# 获取关键点数据
keypoints_data = res0.keypoints.data.cpu().numpy() # shape:[num_person,17,3]
keypoints_conf = res0.keypoints.conf.cpu().numpy() # shape:[num_person,17]
print(f"关键点坐标shape:{keypoints_data.shape}")
print(f"关键点置信度shape:{keypoints_conf.shape}")
# 可视化
plt.figure(figsize=(10,7))
plt.imshow(vis_img[:, :, ::-1])
plt.axis("off")
plt.title("人体关键点检测")
plt.show()
# ---------------- 关键点姿态训练示例 ----------------
if __name__ == "__main__":
pose_model = YOLO("yolo11n-pose.yaml")
train_res = pose_model.train(
data="coco8-pose.yaml",
epochs=10,
imgsz=640,
batch=16,
workers=1
)
3. 参数冻结(迁移学习)片段
冻结骨干网络 backbone,只训练输出头 head,节省显存,适合小数据集微调
python
model = YOLO("yolo11n-seg.yaml")
# 冻结骨干网络backbone
for name, param in model.model.backbone.named_parameters():
param.requires_grad = False
# 开始训练,只有head部分参数会更新
if __name__ == "__main__":
res = model.train(data="cat_dog_seg.yaml", epochs=10, imgsz=640)
4. NMS 非极大值抑制 完整函数
python
import numpy as np
def calculate_iou(box1, box2):
"""box格式xyxy [x1,y1,x2,y2]"""
x1_1, y1_1, x2_1, y2_1 = box1
x1_2, y1_2, x2_2, y2_2 = box2
x1_inter = max(x1_1, x1_2)
y1_inter = max(y1_1, y1_2)
x2_inter = min(x2_1, x2_2)
y2_inter = min(y2_1, y2_2)
if x2_inter <= x1_inter or y2_inter <= y1_inter:
return 0.0
inter_area = (x2_inter - x1_inter) * (y2_inter - y1_inter)
area1 = (x2_1 - x1_1) * (y2_1 - y1_1)
area2 = (x2_2 - x1_2) * (y2_2 - y1_2)
union_area = area1 + area2 - inter_area
return inter_area / union_area if union_area>0 else 0.0
def nms(boxes, scores, iou_threshold):
"""
:param boxes: np.ndarray[N,4] xyxy
:param scores: np.ndarray[N]
:param iou_threshold: IoU阈值
:return: 保留框索引
"""
indices = np.argsort(scores)[::-1]
keep = []
while len(indices) > 0:
cur_idx = indices[0]
keep.append(cur_idx)
if len(indices) == 1:
break
cur_box = boxes[cur_idx]
rest_boxes = boxes[indices[1:]]
ious = np.array([calculate_iou(cur_box, b) for b in rest_boxes])
indices = indices[1:][ious <= iou_threshold]
return keep
5. 模型导出部署代码
python
model = YOLO("yolo11n-seg.pt")
# 导出ONNX通用格式
model.export(format="onnx", optimize=True)
# 导出TensorRT引擎(GPU加速)
model.export(format="engine", device=0)
复习重点速记
- 实例分割:比检测多输出
mask掩码,masks.data、masks.xy获取掩码与轮廓。 - 关键点:输出
[x,y,visibility],一共 17 个 COCO 人体关键点。 - 参数冻结:
requires_grad=False,冻结 backbone 只训练 head,迁移学习。 - NMS:按置信度排序,IoU 过滤重复重叠框。
- 部署优先导出 ONNX,NVIDIA GPU 使用 TensorRT 加速。