giou和ciou区别
时间: 2025-01-11 14:51:53 浏览: 32
GIoU 和 CIoU 在目标检测损失函数中的差异
定义与背景
GIoU (Generalized Intersection over Union) 是对传统 IoU 的一种改进,能够处理预测框和真实框完全不重叠的情况。通过引入最小外接矩形的概念,使得即使两个边界框不相交也能计算出合理的相似度得分[^5]。
CIoU (Complete Intersection over Union),则是在 GIoU 基础上进一步优化得到的新指标。除了考虑位置误差之外,还加入了尺度比例以及宽高比的影响因素,从而更全面地衡量了两者的匹配程度[^6]。
数学表达式对比
对于给定的真实框 ( \text{bbox}_\text{gt}=(x_\text{gt}, y_\text{gt}, w_\text{gt}, h_\text{gt}) ) 及其对应的预测框 ( \text{bbox}_p=(x_p,y_p,w_p,h_p)):
- GIoU Loss [ L_{giou}=1-\frac{\text{IOU}-C}{|C|}]
其中 IOU 表示交并比;( C=\min(\max(x_1,x'_1),...)-\max(\min(x_1,x'_1),...) \times ... )表示包含两个边界的最小闭合区域面积。
- CIoU Loss [L_{ciou}=1-\left[\frac{\text{IOU}}{(1+\alpha d^2)} + v - \alpha v(1-e^{-d^2/v})\right]]
这里增加了三个额外项来描述中心点距离平方 (d)、纵横比率一致性惩罚因子 (v) 以及综合调节系数 (\alpha) ,这些都旨在让模型更好地学习到对象形状特征[^7]。
Python 实现示例
下面给出一段简单的 TensorFlow 代码片段展示如何实现这两种损失:
import tensorflow as tf
from tensorflow.keras import backend as K
def giou_loss(y_true, y_pred):
"""Compute Generalized IoU loss."""
xi1 = tf.maximum(y_pred[..., 0], y_true[..., 0])
yi1 = tf.maximum(y_pred[..., 1], y_true[..., 1])
xi2 = tf.minimum(y_pred[..., 2], y_true[..., 2])
yi2 = tf.minimum(y_pred[..., 3], y_true[..., 3])
inter_area = tf.maximum(xi2 - xi1, 0.) * tf.maximum(yi2 - yi1, 0.)
box1_area = (y_pred[..., 2]-y_pred[..., 0])*(y_pred[..., 3]-y_pred[..., 1])
box2_area = (y_true[..., 2]-y_true[..., 0])*(y_true[..., 3]-y_true[..., 1])
union_area = box1_area + box2_area - inter_area
enclose_xi1 = tf.minimum(y_pred[..., 0], y_true[..., 0])
enclose_yi1 = tf.minimum(y_pred[..., 1], y_true[..., 1])
enclose_xi2 = tf.maximum(y_pred[..., 2], y_true[..., 2])
enclose_yi2 = tf.maximum(y_pred[..., 3], y_true[..., 3])
enclose_area = (enclose_xi2 - enclose_xi1)*(enclose_yi2 - enclose_yi1)
iou = inter_area / union_area
giou = iou - ((enclose_area - union_area)/enclose_area)
return 1-giou
def ciou_loss(y_true, y_pred):
"""Compute Complete IoU loss."""
# Calculate intersection area & union area.
intersect_mins = tf.maximum(y_pred[:, :2], y_true[:, :2])
intersect_maxes = tf.minimum(y_pred[:, 2:], y_true[:, 2:])
intersect_wh = tf.maximum(intersect_maxes - intersect_mins, 0.0)
intersection = intersect_wh[..., 0]*intersect_wh[..., 1]
pred_areas = (y_pred[:, 2] - y_pred[:, 0]) * \
(y_pred[:, 3] - y_pred[:, 1])
true_areas = (y_true[:, 2] - y_true[:, 0]) * \
(y_true[:, 3] - y_true[:, 1])
union = pred_areas + true_areas - intersection
ious = intersection/union
center_distance_squared = (
(tf.square((y_pred[:, 0]+y_pred[:, 2])/2-(y_true[:, 0]+y_true[:, 2])/2))+
(tf.square((y_pred[:, 1]+y_pred[:, 3])/2-(y_true[:, 1]+y_true[:, 3])/2))
)
diag_enclosing_box_squared = (
tf.square(tf.maximum(y_pred[:, 2], y_true[:, 2])-tf.minimum(y_pred[:, 0], y_true[:, 0])) +
tf.square(tf.maximum(y_pred[:, 3], y_true[:, 3])-tf.minimum(y_pred[:, 1], y_true[:, 1]))
)
u = center_distance_squared/diag_enclosing_box_squared
ar_gt = (y_true[:, 2]-y_true[:, 0])/(y_true[:, 3]-y_true[:, 1])
ar_pred = (y_pred[:, 2]-y_pred[:, 0])/(y_pred[:, 3]-y_pred[:, 1])
v = 4*K.square(K.atan(ar_gt)-K.atan(ar_pred))/(math.pi*math.pi)
alpha = v/(1-ious+v)
cious = ious-u-v*alpha
return 1-cious
相关推荐



















