IoU损失函数的发展
时间: 2024-08-13 16:05:07 浏览: 72
IoU(Intersection over Union)损失函数,也称为Jaccard相似度或并交比,最初是由计算机视觉领域引入的,主要用于评估目标检测、图像分割等任务中预测区域与真实区域的重叠程度。该指标衡量的是预测框(或分割结果)与实际框之间的交集部分占它们并集的比例。
IoU损失函数最初是为了克服二元交叉熵损失在处理边界框定位问题时的不足,因为二元交叉熵倾向于过于关注边缘预测,可能会导致预测框偏大或偏小。IoU损失函数能更好地反映预测框的位置和大小准确性,特别是在物体较小或遮挡较多的情况下。
发展过程中,IoU损失函数得到了广泛应用,并在实践中发展出了几种变体,如:
1. **多类多目标IoU损失**:扩展到多个类别和目标的多任务场景,通过计算每个类别的IoU来综合评估。
2. **软IoU损失**:使用概率形式,将IoU作为连续值而不是离散的0/1,这样可以提供更多的梯度信息,有助于训练。
3. **IoU-softmax**:结合了softmax输出和IoU,用于更精确的目标定位和分类。
4. **Focal Loss**:针对类别不平衡问题,引入了IoU的思想,着重于减少正负样本的不平衡影响。
相关问题
yolov5损失函数发展
### YOLOv5 损失函数发展历程与变化
#### 初始版本中的损失函数设计
YOLOv5最初继承了YOLO系列一贯的设计理念,采用了多任务联合训练的方式。在早期版本中,损失函数主要由三部分组成:分类损失、置信度损失以及边界框回归损失。其中,分类损失采用交叉熵损失来衡量模型预测类别与真实标签之间的差异;置信度损失同样使用交叉熵损失评估对象存在与否的概率预测准确性。
#### Focal Loss 的引入
为了应对样本不平衡问题并提高小目标检测效果,在后续更新中引入了Focal Loss用于计算分类分支的损失值[^3]。该损失表达式为:
\[ L_{cls} = -\alpha_t(1-p_t)^\gamma \log(p_t) \]
这里 \( p_t \) 表示模型对正确类别的预测概率,\( \alpha \) 和 \( \gamma \) 分别作为正负样本权重调节参数和困难样例挖掘强度控制因子。通过这种方式可以有效降低简单背景区域带来的梯度过大现象,并增强网络对于难以区分的小物体的关注程度。
#### GIoU Loss 替代传统 IoU Loss
除了改进分类子项外,针对定位精度不足的问题,YOLOv5还逐步替换了原有的交并比(IoU)Loss形式的位置回归损失机制。具体来说是从普通的IoU发展到了GIoU (Generalized Intersection over Union),后者不仅考虑了两个矩形框重叠面积的比例关系,同时也加入了最小闭包包围盒的概念,从而更好地引导锚点向真值逼近。
```python
def giou_loss(pred, target):
"""
计算GIoU损失
参数:
pred: 预测边框坐标
target: 真实边框坐标
返回:
平均GIoU损失值
"""
# 获取预测框和真实框中心点及宽高
b1_x1, b1_y1, b1_x2, b1_y2 = pred[:, 0], pred[:, 1], pred[:, 2], pred[:, 3]
b2_x1, b2_y1, b2_x2, b2_y2 = target[:, 0], target[:, 1], target[:, 2], target[:, 3]
# 计算两者的交集宽度高度
inter_rect_x1 = torch.max(b1_x1, b2_x1)
inter_rect_y1 = torch.max(b1_y1, b2_y1)
inter_rect_x2 = torch.min(b1_x2, b2_x2)
inter_rect_y2 = torch.min(b1_y2, b2_y2)
# Clip the coordinates to avoid negative values
inter_area = torch.clamp(inter_rect_x2 - inter_rect_x1 + 1e-16, min=0.) * \
torch.clamp(inter_rect_y2 - inter_rect_y1 + 1e-16, min=0.)
# Calculate union area
w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1
w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1
union_area = (w1*h1+1e-16)+(w2*h2)-inter_area
iou = inter_area / union_area
enclose_left_up = torch.min(torch.stack([b1_x1,b2_x1]),dim=-1)[0],\
torch.min(torch.stack([b1_y1,b2_y1]),dim=-1)[0]
enclose_right_down = torch.max(torch.stack([b1_x2,b2_x2]),dim=-1)[0],\
torch.max(torch.stack([b1_y2,b2_y2]),dim=-1)[0]
c_w = enclose_right_down[0]-enclose_left_up[0]+1e-16
c_h = enclose_right_down[1]-enclose_left_up[1]+1e-16
outer_diagonal_line_square=(c_w**2+c_h**2)+1e-16
inner_diagonal_line_square=((b2_x1+b2_x2-b1_x1-b1_x2)**2+(b2_y1+b2_y2-b1_y1-b1_y2)**2)/4
gious=iou-(inner_diagonal_line_square/outer_diagonal_line_square-iou)
loss_giou=torch.mean((1-gious))
return loss_giou
```
随着这些优化措施的应用,YOLOv5能够更精准地完成各类视觉识别任务,特别是在处理复杂场景下的多尺度目标检测时表现出色。然而需要注意的是,尽管上述改动显著提升了整体性能,但在某些极端情况下仍可能存在一定的局限性,比如面对极度拥挤或遮挡严重的环境时可能无法达到理想的效果。
iou发展历程
### IOU 的发展历程
#### 初始阶段:传统IOU
最初,交并比(Intersection over Union, IOU)被定义为两个边界框交集区域除以它们的并集区域。当预测框与真实框完全重合时,该值达到最大1;而如果二者完全没有重叠,则其最小值为0[^1]。
然而,在实际应用中遇到不少挑战:
- 当目标物体之间不存在任何交叉部分时,即两者的交集面积等于零的情况下,此时计算得到的结果也为零,这使得模型难以通过反向传播调整参数来改善这种情况;
- 对于形状差异较大或者尺度变化剧烈的目标检测任务来说,单纯依靠此指标可能不足以充分反映定位精度的好坏程度。
#### 改进一:GIoU (Generalized Intersection Over Union)
针对上述不足之处,研究人员提出了广义交并比(GIoU),它不仅考虑到了原始意义上的交集和并集关系,还额外引入了闭包的概念——即将两个矩形所包围起来形成的最小外接矩形称为“闭包”。这样一来即使在无公共覆盖区间的条件下也能给出负数形式的距离惩罚项,从而引导网络更好地收敛至最优解附近。
#### 进一步优化:DIoU 和 CIoU
尽管 GIoU 已经解决了某些特定场景下的难题,但在处理极端长宽比或是中心偏移较大的实例方面仍然表现欠佳。为此,后续又出现了距离-IoU(Distance IoU, DIoU)以及完整-IoU(Complete IoU, CIoU)两种变体方案:
- **DIoU** :除了继承自 GIoU 的特性之外,还加入了基于欧氏几何原理衡量两者质心间距远近的因素,有助于缓解因位置偏差过大而导致的学习困难现象;
- **CIoU** : 综合考量了三个方面的影响因素 —— 面积占比、纵横比率一致性还有相对位移量大小 ,力求全方位提升回归性能的同时加快训练速度.
这些不断演化的损失函数设计思路体现了计算机视觉领域对于提高目标检测效果不懈追求的精神面貌.
```python
def compute_iou(box_a, box_b):
"""Calculate the intersection-over-union for two bounding boxes."""
# Calculate coordinates of intersecting rectangle
inter_xmin = max(box_a[0], box_b[0])
inter_ymin = max(box_a[1], box_b[1])
inter_xmax = min(box_a[2], box_b[2])
inter_ymax = min(box_a[3], box_b[3])
# Compute area of overlap and union
inter_area = max(inter_xmax - inter_xmin + 1, 0) * \
max(inter_ymax - inter_ymin + 1, 0)
boxa_area = (box_a[2]-box_a[0]+1)*(box_a[3]-box_a[1]+1)
boxb_area = (box_b[2]-box_b[0]+1)*(box_b[3]-box_b[1]+1)
iou_score = float(inter_area)/(boxa_area + boxb_area - inter_area)
return iou_score
def generalized_iou(pred_box, target_box):
"""Compute Generalized IoU loss between predicted bbox and ground truth"""
# Get bboxes' areas & their smallest enclosing box's diagonal length squared.
pred_area = ...
gt_area = ...
enclose_diagonal_sqrd = ...
giou_loss = ...
return giou_loss
```
阅读全文
相关推荐
















