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
有任何问题,欢迎交流!🚀