目标检测优化实战:CA+WIOU损失函数的原理与实现

1次阅读
没有评论

共计 2692 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

目录

背景痛点

目标检测中的边界框回归质量直接影响模型性能。传统 IOU 及其变种存在两大核心问题:

  1. 梯度消失 :当预测框与真实框无重叠时,IOU= 0 导致梯度无法回传。下图展示不同位置预测框的梯度分布(假设真实框居中):

目标检测优化实战:CA+WIOU 损失函数的原理与实现

  1. 方向不敏感 :常规 IOU 对边界框的长宽比变化不敏感,导致倾斜物体(如旋转的车辆)回归精度低。下表对比各损失函数在 DOTA 数据集上的表现:
损失函数 AP50(水平框) AP50(旋转框)
IOU 72.1 58.3
GIOU 73.5 61.2
CIOU 74.8 63.7

技术方案

CA 模块设计原理

Coordinate Attention 通过两步捕获空间坐标信息:

  1. 坐标信息嵌入 :对输入特征图分别进行 X / Y 方向的全局池化,得到两个方向的特征向量:

$$ z_h(h) = \frac{1}{W} \sum_{0≤i<W} x(h,i), \quad z_w(w) = \frac{1}{H} \sum_{0≤j<H} x(j,w) $$

  1. 坐标注意力生成 :将两个方向的特征拼接后通过卷积 + 非线性激活生成注意力图:

$$ f = \delta(F_1([z_h, z_w])) $$

$$ g_h = \sigma(F_h(f)), \quad g_w = \sigma(F_w(f)) $$

WIOU 动态权重机制

定义权重系数为预测框与真实框宽高比的函数:

$$ w = \frac{\min(w_p,w_g)}{\max(w_p,w_g)} \cdot \frac{\min(h_p,h_g)}{\max(h_p,h_g)} $$

最终损失函数为:

$$ \mathcal{L}_{wiou} = 1 – \frac{|B_p \cap B_g|}{|B_p \cup B_g|} \cdot w^\gamma $$

其中 γ 为可调超参数,实验表明 γ =0.5 时效果最佳。下图展示不同 γ 值对 P - R 曲线的影响:

代码实现

CA 模块 PyTorch 实现

import torch
import torch.nn as nn

class CoordAtt(nn.Module):
    def __init__(self, in_channels, reduction=32):
        super().__init__()
        self.pool_h = nn.AdaptiveAvgPool2d((None, 1))
        self.pool_w = nn.AdaptiveAvgPool2d((1, None))

        mid_channels = max(in_channels // reduction, 8)
        self.conv1 = nn.Conv2d(in_channels, mid_channels, 1)
        self.bn1 = nn.BatchNorm2d(mid_channels)
        self.act = nn.ReLU(inplace=True)

        self.conv_h = nn.Conv2d(mid_channels, in_channels, 1)
        self.conv_w = nn.Conv2d(mid_channels, in_channels, 1)

    def forward(self, x):
        _, _, h, w = x.size()

        # 坐标信息嵌入
        x_h = self.pool_h(x)  # [B,C,H,1]
        x_w = self.pool_w(x)  # [B,C,1,W]

        # 注意力生成
        x_cat = torch.cat([x_h, x_w], dim=2)  # [B,C,H+W,1]
        out = self.act(self.bn1(self.conv1(x_cat)))

        h_out = torch.sigmoid(self.conv_h(out[:, :, :h, :]))
        w_out = torch.sigmoid(self.conv_w(out[:, :, h:, :]))

        return x * h_out * w_out

WIOU 损失函数实现

def weighted_iou_loss(pred, target, gamma=0.5):
    """pred/target: [B,4] format (x1,y1,x2,y2)"""
    # 计算交集和并集
    inter_area = (torch.min(pred[:,2], target[:,2]) - torch.max(pred[:,0], target[:,0])).clamp(0) * \
                 (torch.min(pred[:,3], target[:,3]) - torch.max(pred[:,1], target[:,1])).clamp(0)

    pred_area = (pred[:,2] - pred[:,0]) * (pred[:,3] - pred[:,1])
    target_area = (target[:,2] - target[:,0]) * (target[:,3] - target[:,1])
    union_area = pred_area + target_area - inter_area

    # 计算动态权重
    w_ratio = torch.min(pred[:,2]-pred[:,0], target[:,2]-target[:,0]) / \
              torch.max(pred[:,2]-pred[:,0], target[:,2]-target[:,0])
    h_ratio = torch.min(pred[:,3]-pred[:,1], target[:,3]-target[:,1]) / \
              torch.max(pred[:,3]-pred[:,1], target[:,3]-target[:,1])
    weight = (w_ratio * h_ratio).pow(gamma)

    iou = inter_area / (union_area + 1e-7)
    return 1 - iou * weight

实验验证

COCO 数据集结果

Method AP50 AP75 Params(M) FPS
Faster R-CNN 58.9 37.4 41.5 26
+CA+WIOU 61.2↑2.3 39.8↑2.4 41.8 24

训练曲线对比

避坑指南

  1. 学习率设置 :当 batch size 增大 4 倍时,学习率应加倍(线性缩放规则)
  2. 示例:bs=16 时 lr=0.01 → bs=64 时 lr=0.04

  3. 极端长宽比处理

  4. 调整 γ 值:对于长宽比 >5:1 的目标,建议 γ =0.3~0.4
  5. 数据增强:添加随机旋转(-15°~15°)

  6. 多任务梯度冲突

  7. 对分类和回归分支使用不同优化器
  8. 采用 GradNorm 进行梯度归一化

延伸思考

  1. Anchor-free 结合 :可将 CA 模块插入 FCOS 的 centerness 分支,WIOU 替换原回归损失
  2. YOLOv8 集成
  3. 替换 head 中的卷积为 CA 模块
  4. 修改 utils/metrics.py 中的 bbox_iou 函数
  5. 未来方向 :探索 3D 检测中 Z 轴坐标的注意力机制设计
正文完
 0
评论(没有评论)