YOLOv5-Seg 深度解析:与 YOLOv5 检测模型的区别
1. 概述
YOLOv5 是一个强大的目标检测框架,而 YOLOv5-Seg 是其扩展版本,增加了实例分割功能。
YOLOv5(目标检测) vs YOLOv5-Seg(实例分割)
| 版本 | 主要任务 | 输出结果 |
|---|---|---|
| YOLOv5 | 目标检测(Object Detection) | 目标类别、边界框 (Bounding Box) |
| YOLOv5-Seg | 目标检测 + 实例分割(Instance Segmentation) | 目标类别、边界框、掩码 (Mask) |
2. YOLOv5-Seg 与 YOLOv5 的结构差异
2.1 网络结构对比
- YOLOv5-Seg 在 YOLOv5 的基础上增加了 Mask 预测头,用于输出目标的掩码。
- YOLOv5 仅有
类别预测头和边界框预测头。
2.2 主要结构变化
在 YOLOv5-Seg 中,主要修改了 model.yaml 文件,增加了一个 segmentation 相关的输出:
nc: 类别数,与目标检测一致。mask: 32×32 的二值化掩码。proto: 原始掩码特征,用于恢复高分辨率掩码。
在代码结构上,YOLOv5-Seg 在 models/yolo.py 的 forward() 中增加了额外的分割分支。
Mask 预测头的具体结构
YOLOv5-Seg 在 detect.py 代码中增加了 segmentation 分支,其核心是 mask 预测头,计算方式如下:
- 在
YOLOv5目标检测头的基础上,增加了一个ProtoNet网络。 ProtoNet负责提取32×32的掩码特征。mask预测头输出 32 维的mask embedding,并与ProtoNet进行点积,生成最终掩码。
在 models/yolo.py 代码片段中,ProtoNet 计算方式如下:
python
class ProtoNet(nn.Module):
def __init__(self, c1, c2, k=3):
super().__init__()
self.conv = nn.Conv2d(c1, c2, k, stride=1, padding=k//2)
def forward(self, x):
return self.conv(x)
该 ProtoNet 结构的作用是对特征图进行降维,使 mask 预测变得更加高效。
3. YOLOv5-Seg 输出格式解析
在 YOLOv5 目标检测模型中,输出格式如下:
python
# YOLOv5 输出 (N, 6): [x1, y1, x2, y2, 置信度, 类别]
而 YOLOv5-Seg 额外输出了 mask 和 proto,格式如下:
python
# YOLOv5-Seg 输出 (N, 6+32): [x1, y1, x2, y2, 置信度, 类别, mask_1, mask_2, ..., mask_32]
其中:
mask_1~mask_32是目标的 32 维掩码向量,用于通过proto计算最终掩码。proto是一个 (32, H/4, W/4) 的张量,用于掩码解码。
4. 训练 YOLOv5-Seg
与 YOLOv5 训练类似,只需要指定 --task segment:
bash
python train.py --task segment --data coco128-seg.yaml --weights yolov5s-seg.pt --epochs 100
其中:
coco128-seg.yaml是适用于分割任务的数据集配置。yolov5s-seg.pt是YOLOv5-Seg预训练模型。
5. 推理与后处理
5.1 推理命令
bash
python detect.py --task segment --weights yolov5s-seg.pt --source image.jpg
5.2 结果后处理
对于 YOLOv5-Seg,我们需要对 mask 进行解码:
python
import torch
import cv2
import numpy as np
def process_mask(mask, proto, bbox, img_shape):
"""
解析 YOLOv5-Seg 的 32×32 掩码,将其映射到原图
"""
x1, y1, x2, y2 = map(int, bbox) # 边界框坐标
mask_decoded = (proto @ mask.T).sigmoid().cpu().numpy() # 计算掩码
mask_resized = cv2.resize(mask_decoded, (x2-x1, y2-y1))
full_mask = np.zeros(img_shape[:2], dtype=np.uint8)
full_mask[y1:y2, x1:x2] = (mask_resized > 0.5).astype(np.uint8)
return full_mask
6. 总结
YOLOv5-Seg在YOLOv5目标检测基础上,增加了掩码分支,实现了实例分割。- 输出增加了
mask,需要结合proto进行解码。 - 训练方式与
YOLOv5类似,推理时需要额外处理mask。 - 适用于需要同时进行目标检测和实例分割的任务,如医学影像、自动驾驶等。
如果你对 YOLOv5-Seg 有任何问题,欢迎交流!🚀