yolov7 GIoU
时间: 2025-02-19 07:30:04 浏览: 43
### YOLOv7 中 GIoU 实现与应用
在对象检测领域,GIoU (Generalized Intersection over Union) 是一种改进的损失函数,用于提高边界框回归的质量。对于YOLOv7而言,GIoU不仅有助于提升模型性能,还简化了训练过程中的收敛。
#### GIoU 定义及其优势
传统IoU仅考虑预测框和真实框之间的交集部分除以并集面积来衡量重叠程度;而GIoU在此基础上引入了一个额外项——最小外接矩形(C),该矩形能够完全覆盖住两个框[^1]。具体计算公式如下:
\[ \text{GIoU} = \frac{|A ∩ B|}{|A ∪ B|} - \frac{|C-(A∪B)|}{|C|}\]
其中 \( A \) 和 \( B \) 分别代表预测框和实际标注框,\( C \) 表示能包围这两个框的最小闭合区域。
这种设计使得即使当预测框与目标框完全没有重叠时也能给出合理的梯度方向指导优化器调整参数,从而加速网络学习速度并改善最终效果。
#### YOLOv7 中的具体实现方式
为了更好地理解如何在YOLOv7中运用GIoU,在PyTorch框架下可以按照以下方式进行编码实现:
```python
import torch
def giou_loss(pred_boxes, target_boxes):
"""
计算GIoU Loss
参数:
pred_boxes: 预测边框张量形状为[N, 4], xywh格式.
target_boxes: 真实边框张量同样为[N, 4].
返回值:
平均GIoU损失值作为标量tensor.
"""
# 将xywh转换成xmin ymin xmax ymax形式以便后续操作更直观方便
def box_convert(boxes):
converted_box = boxes.clone()
converted_box[:, :2] -= boxes[:, 2:] / 2 # 左上角坐标(xmin,ymin)=中心点-宽高的一半
converted_box[:, 2:] += converted_box[:, :2] # 右下角坐标(xmax,ymax)=左上角+宽度高度
return converted_box
pred_boxes = box_convert(pred_boxes)
target_boxes = box_convert(target_boxes)
tl = torch.max(pred_boxes[:, None, :2], target_boxes[:, :2]) # [N,M,2]
br = torch.min(pred_boxes[:, None, 2:], target_boxes[:, 2:]) # [N,M,2]
area_pred = (pred_boxes[:, 2]-pred_boxes[:, 0]) * \
(pred_boxes[:, 3]-pred_boxes[:, 1])
area_target = (target_boxes[:, 2]-target_boxes[:, 0]) * \
(target_boxes[:, 3]-target_boxes[:, 1])
inter_wh = (br-tl).clamp(min=0) # [N,M,2]
inter_area = inter_wh[:, :, 0]*inter_wh[:, :, 1] # [N,M]
union_area = area_pred[:, None]+area_target-inter_area
iou = inter_area/union_area
enclose_tl = torch.min(pred_boxes[:, None, :2], target_boxes[:, :2])
enclose_br = torch.max(pred_boxes[:, None, 2:], target_boxes[:, 2:])
enclose_w = (enclose_br[:, :, 0]-enclose_tl[:, :, 0]).clamp(min=0)
enclose_h = (enclose_br[:, :, 1]-enclose_tl[:, :, 1]).clamp(min=0)
outer_diag_sq = enclose_w ** 2 + enclose_h ** 2
inner_diag_sq = ((pred_boxes[:, None, 0] -
target_boxes[:, 0])**2 +
(pred_boxes[:, None, 1] -
target_boxes[:, 1])**2)
giou_term = -(inner_diag_sq / outer_diag_sq).mean(dim=-1)
giou = iou.mean() + giou_term.mean()
return 1-giou
# 示例用法
if __name__ == '__main__':
import numpy as np
preds = torch.tensor([[1., 1., 3., 5.],
[2., 2., 4., 4.]])
targets = torch.tensor([[1., 1., 4., 4.]])
print(f'GIoU Loss: {giou_loss(preds, targets)}')
```
此代码片段展示了如何定义一个简单的 `giou_loss` 函数来计算给定预测框集合相对于真值框集合之间平均GIoU得分,并将其转化为可用于反向传播更新权重的学习信号。
阅读全文
相关推荐


















