YOLOv11 改进 – 损失函数 SDloss尺度动态损失:动态平衡尺度与位置损失权重破解多尺度目标检测难题
# 前言
文章目录: YOLOv11改进大全:卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总
专栏链接: YOLOv11改进专栏
介绍

摘要
作为检测器定位分支的重要组成,边框回归损失在目标检测任务中发挥巨大作用。现有的边框回归方法,通常考虑了GT框与预测框之间的几何关系,通过使用边框间的相对位置与相对形状等计算损失,而忽略了边框其自身的形状与尺度等固有属性对边框回归的影响。为了弥补现有研究的不足,本文提出聚焦边框自身形状与尺度的边框回归方法。首先我们对边框回归特性进行分析,得出边框自身形状因素与尺度因素会对回归结果产生影响。接着基于以上结论我们,我们提出了Shape-IoU方法,其能够通过聚焦边框自身形状与自身尺度计算损失,从而使得边框回归更为精确。最后我们通过大量的对比实验来验证本文方法,实验结果表明本文方法能够有效提升检测效果且优于现有方法,在不同的检测任务中达到了sota.
文章链接
论文地址:论文地址
代码地址:代码地址
创新点
文章围绕红外小目标检测与分割任务,针对现有损失函数的不足,提出了基于尺度的动态损失(Scale-based Dynamic Loss, SD Loss),同时也对比分析了多种现有损失函数。以下是详细介绍:
一、核心提出的损失函数:SD Loss
SD Loss的核心设计思路是根据目标尺度动态调整尺度损失(Scale Loss, SLoss)和位置损失(Location Loss, Lloss)的影响系数,以解决标注误差(如IoU波动)和不同尺度目标对损失敏感度差异的问题,适用于边界框(BBox)和掩码(Mask)两种标注格式,分为两类具体实现:
1. 边界框专用:SDB Loss(Scale-based Dynamic BBox Loss)
- 适用场景:针对BBox标注的检测任务,解决小目标IoU损失波动大、位置偏差影响显著的问题。
- 核心组件:
- 尺度损失($\mathcal{L}{BS}$):基于IoU和边界框宽高比一致性($\alpha v$),公式为 $\mathcal{L}{BS}=1-IoU+\alpha v$;
- 位置损失($\mathcal{L}{BL}$):基于预测框与真实框质心的欧氏距离($\rho$)和对角线长度($c$),公式为 $\mathcal{L}{BL}=\frac{\rho^{2}(b{p}, b{gt})}{c^{2}}$;
- 动态系数($\betaB$):根据目标真实面积($B{gt}$)、图像与特征图尺度比($R{OC}$)和可调参数$\delta$计算,公式为 $\beta{B}=min\left(\frac{B{gt}}{B{gtmax}} × R{OC} × \delta, \delta\right)$($B{gtmax}=81$ 为红外小目标最大定义尺寸);
- 最终损失:$\mathcal{L}{SDB}=\beta{\mathcal{L}{BS}} × \mathcal{L}{BS}+\beta{\mathcal{L}{BL}} × \mathcal{L}{BL}$,其中 $\beta{\mathcal{L}{BS}}=1-\delta +\beta{B}$、$\beta{\mathcal{L}{BL}}=1+\delta -\beta_{B}$,动态平衡两类损失的权重。
2. 掩码专用:SDM Loss(Scale-based Dynamic Mask Loss)
- 适用场景:针对Mask标注的分割任务,解决模糊边界导致的IoU波动、小目标位置损失收敛困难的问题。
- 核心组件:
- 尺度损失($\mathcal{L}{MS}$):基于掩码交并比(IoU)并引入权重$\omega$(描述预测与真实掩码差异),公式为 $\mathcal{L}{MS}=1-\omega \frac{|M{p} \bigcap M{gt}|}{|M{p} \bigcup M{gt}|}$;
- 位置损失($\mathcal{L}{ML}$):结合极坐标下的距离比和角度差,公式为 $\mathcal{L}{ML}=1-\frac{min(d{p}, d{gt})}{max(d{p}, d{gt})}+\frac{4}{\pi^{2}}(\theta{p}-\theta{gt})^{2}$;
- 动态系数($\beta_M$):与SDB Loss的$\betaB$计算逻辑一致,基于掩码真实面积($M{gt}$),公式为 $\beta{M}=min\left(\frac{M{gt}}{M{gtmax}} × R{OC} × \delta, \delta\right)$;
- 最终损失:$\mathcal{L}{SDM}=\beta{\mathcal{L}{MS}} × \mathcal{L}{MS}+\beta{\mathcal{L}{ML}} × \mathcal{L}{ML}$,其中 $\beta{\mathcal{L}{MS}}=1+\beta{M}$、$\beta{\mathcal{L}{ML}}=1-\beta_{M}$,增强尺度损失对小目标的关注度。
3. SD Loss的优势
- 动态适配目标尺度:小目标降低SLoss权重、提升LLoss权重(BBox场景)或增强SLoss权重(Mask场景),缓解标注误差影响;
- 计算高效:无指数运算,相比NWD、SAFit等损失函数更稳定、复杂度更低;
- 泛化性强:在IRSTD-1K和SIRST-UAVB数据集上均实现稳定性能提升。
核心代码
def bbox_iou(box1, box2, xywh=True, GIoU=False, DIoU=False, CIoU=False, SDIoU=True, eps=1e-7, delta=0.5):
"""
Calculate Intersection over Union (IoU) of box1(1, 4) to box2(n, 4).
Args:
box1 (torch.Tensor): A tensor representing a single bounding box with shape (1, 4).
box2 (torch.Tensor): A tensor representing n bounding boxes with shape (n, 4).
xywh (bool, optional): If True, input boxes are in (x, y, w, h) format. If False, input boxes are in
(x1, y1, x2, y2) format. Defaults to True.
GIoU (bool, optional): If True, calculate Generalized IoU. Defaults to False.
DIoU (bool, optional): If True, calculate Distance IoU. Defaults to False.
CIoU (bool, optional): If True, calculate Complete IoU. Defaults to False.
SDIoU (bool, optional): If True, calculate Scale-based Dynamic IoU. Defaults to False.
eps (float, optional): A small value to avoid division by zero. Defaults to 1e-7.
Returns:
(torch.Tensor): IoU, GIoU, DIoU, or CIoU values depending on the specified flags.
"""
# Get the coordinates of bounding boxes
if xywh: # transform from xywh to xyxy
(x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1)
w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2
b1_x1, b1_x2, b1_y1, b1_y2 = x1 - w1_, x1 + w1_, y1 - h1_, y1 + h1_
b2_x1, b2_x2, b2_y1, b2_y2 = x2 - w2_, x2 + w2_, y2 - h2_, y2 + h2_
else: # x1, y1, x2, y2 = box1
b1_x1, b1_y1, b1_x2, b1_y2 = box1.chunk(4, -1)
b2_x1, b2_y1, b2_x2, b2_y2 = box2.chunk(4, -1)
w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps
w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps
# Intersection area ∩
inter = (b1_x2.minimum(b2_x2) - b1_x1.maximum(b2_x1)).clamp_(0) * (
b1_y2.minimum(b2_y2) - b1_y1.maximum(b2_y1)
).clamp_(0)
# Union Area U
union = w1 * h1 + w2 * h2 - inter + eps
# IoU
iou = inter / union
# R_oc = 1 # The YOLO bounding box is normalized, so R_oc is equal to 1.
if CIoU or DIoU or GIoU or SDIoU:
cw = b1_x2.maximum(b2_x2) - b1_x1.minimum(b2_x1) # convex (smallest enclosing box) width
ch = b1_y2.maximum(b2_y2) - b1_y1.minimum(b2_y1) # convex height
if CIoU or DIoU or SDIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1
c2 = cw**2 + ch**2 + eps # convex diagonal squared
rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 # center dist ** 2
if CIoU or SDIoU: # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47
v = (4 / math.pi**2) * (torch.atan(w2 / h2) - torch.atan(w1 / h1)).pow(2)
with torch.no_grad():
alpha = v / (v - iou + (1 + eps))
if SDIoU:
beta = (w2 * h2 * delta) / 81
beta = torch.where(beta > delta, torch.tensor(delta, device=beta.device), beta)
return delta-beta + (1-delta+beta)*(iou-v*alpha) - (1+delta-beta)*(rho2/c2) # SDIoU
return iou - (rho2 / c2 + v * alpha) # CIoU
return iou - rho2 / c2 # DIoU
c_area = cw * ch + eps # convex area
return iou - (c_area - union) / c_area # GIoU https://arxiv.org/pdf/1902.09630.pdf
return iou # IoU
版权声明:
作者:魔改工程师
链接:https://www.sylblog.xin/archives/226
文章版权归作者所有,未经允许请勿转载。
THE END