共计 2692 个字符,预计需要花费 7 分钟才能阅读完成。
目录
背景痛点
目标检测中的边界框回归质量直接影响模型性能。传统 IOU 及其变种存在两大核心问题:
- 梯度消失 :当预测框与真实框无重叠时,IOU= 0 导致梯度无法回传。下图展示不同位置预测框的梯度分布(假设真实框居中):

- 方向不敏感 :常规 IOU 对边界框的长宽比变化不敏感,导致倾斜物体(如旋转的车辆)回归精度低。下表对比各损失函数在 DOTA 数据集上的表现:
| 损失函数 | AP50(水平框) | AP50(旋转框) |
|---|---|---|
| IOU | 72.1 | 58.3 |
| GIOU | 73.5 | 61.2 |
| CIOU | 74.8 | 63.7 |
技术方案
CA 模块设计原理
Coordinate Attention 通过两步捕获空间坐标信息:
- 坐标信息嵌入 :对输入特征图分别进行 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) $$
- 坐标注意力生成 :将两个方向的特征拼接后通过卷积 + 非线性激活生成注意力图:
$$ 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 |
训练曲线对比
避坑指南
- 学习率设置 :当 batch size 增大 4 倍时,学习率应加倍(线性缩放规则)
-
示例:bs=16 时 lr=0.01 → bs=64 时 lr=0.04
-
极端长宽比处理 :
- 调整 γ 值:对于长宽比 >5:1 的目标,建议 γ =0.3~0.4
-
数据增强:添加随机旋转(-15°~15°)
-
多任务梯度冲突 :
- 对分类和回归分支使用不同优化器
- 采用 GradNorm 进行梯度归一化
延伸思考
- Anchor-free 结合 :可将 CA 模块插入 FCOS 的 centerness 分支,WIOU 替换原回归损失
- YOLOv8 集成 :
- 替换 head 中的卷积为 CA 模块
- 修改 utils/metrics.py 中的 bbox_iou 函数
- 未来方向 :探索 3D 检测中 Z 轴坐标的注意力机制设计
正文完
