目录
🚀 前言
目标检测任务的损失函数一般由目标分类损失函数(Object Classificition Loss)和边界框回归损失函数(Bounding Box Regeression Loss)两部分构成,当然在YOLO系列中,还引入了置信度损失(Object Confidence Loss)。本文主要对边界框回归损失函数(Bounding Box Regeression Loss)进行讨论。
🔥 若想尝试改进YOLOv5-7.0中的损失函数:
- YOLOv5改进实战(1)| 更换损失函数(一)之EIoU、Alpha-IoU、SIoU篇
- YOLOv5改进实战(2)| 更换损失函数(二)之WIOU(Wise IoU)篇
- YOLOv5改进实战(3)| 更换损失函数(三)之MPDIOU(2023最新IOU)篇
一、IOU(Intersection over Union)
ACM 2016 论文链接:UnitBox: An Advanced Object Detection Network
IOU(Intersection over Union)是一种用于衡量目标检测性能的评估指标。它主要用于计算两个边界框(Bounding Box)之间的重叠度,也就是所说的交并比。通常用于测量模型预测的边界框与真实边界框之间的匹配程度。
- IOU的计算方式如下:
I o U = ∣ A ∩ B ∣ ∣ A ∪ B ∣ IoU=\frac{\left | A \cap B \right | }{\left | A \cup B \right | } IoU=∣A∪B∣∣A∩B∣
1.1 优点
- IOU能够直观地反映出目标检测结果与真实情况之间的匹配程度。
- IOU具有尺度不变性,由于IOU是基于重叠度量的,它不受目标尺度和形状变换的影响。这使得IOU适用于各种不同尺度和形状的目标检测任务。
1.2 缺点
- 当预测框和目标框不相交时,即IOU=0时,不能反映两个目标之间距离的远近,此时损失函数不可导,IOU Loss 无法优化。
- 当两个检测框大小相同,两个IOU也相同,IOU_Loss无法精确的反映两个框的重合度大小。
1.3 实现代码
def IOU(box1, box2, eps=1e-7):
b1_x1, b1_y1, b1_x2, b1_y2 = box1
b2_x1, b2_y1, b2_x2, b2_y2 = box2
# 获取矩形框交集对应的左上角和右下角的坐标(intersection)
xx1 = np.max([b1_x1, b2_x1])
yy1 = np.max([b1_y1, b2_y1])
xx2 = np.min([b1_x2, b2_x2])
yy2 = np.min([b1_y2, b2_y2])
# 计算两个矩形框面积
area1 = (b1_x2 - b1_x1) * (b1_y2 - b1_y1)
area2 = (b2_x2 - b2_x1) * (b2_y2 - b2_y1)
inter = (np.max([0, xx2 - xx1])) * (np.max([0, yy2 - yy1])) # 计算交集面积
uniou = area1 + area2 - inter + eps
iou = inter / uniou # 计算交并比
return iou
if __name__ == "__main__":
box1 = np.array([0, 0, 100, 100])
box2 = np.array([50, 0, 150, 100])
print(IOU(box1, box2))
二、GIOU(Generalized IoU)
CVPR 2019 论文链接:Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression
GIOU通过引入预测框和真实框的最小外接矩形来获取预测框、真实框在闭包区域中的比重,从而解决了两个目标没有交集时梯度为零的问题。
G
I
o
U
=
I
o
U
−
∣
C
−
(
A
∪
B
)
∣
∣
C
∣
GIoU=IoU-\frac{\left | C-\left ( A\cup B \right ) \right | }{\left | C \right | }
GIoU=IoU−∣C∣∣C−(A∪B)∣
其中
C
C
C是两个框的最小外接矩形的面积。
2.1 优点
- 与IoU只关注重叠区域不同,GIOU不仅关注重叠区域,还关注其他的非重合区域,能更好的反映两者的重合度;
- GIOU是一种IoU的下界,取值范围 [ − 1 , 1 ] [-1,1] [−1,1]。在两者重合的时候取最大值1,在两者无交集且无限远的时候取最小值-1。因此,与IoU相比,GIoU是一个比较好的距离度量指标。
2.2 缺点
- 当两个预测框完全重叠时,这时GIOU就退化为IOU,无法区分相对位置关系;
- 对每个预测框与真实框均要去计算最小外接矩形,计算及收敛速度受到限制。
2.3 实现代码
- 详细代码请移步:代码区
三、DIOU(Distance-IoU)
AAAI 2020 论文链接:Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression
考虑到GIOU的缺点,DIOU在IoU的基础上直接回归两个框中心点的欧式距离,加速了收敛速度。DIOU的惩罚项是基于中心点的距离和对角线距离的比值。这样就避免了GIOU在两框距离较远时产生较大闭包时所造成的Loss值较大而难以优化的情况。
D
I
o
U
=
I
o
U
−
ρ
2
(
b
,
b
g
t
)
c
2
DIoU=IoU-\frac{\rho^{2} \left ( b,b^{gt} \right ) }{c^{2}}
DIoU=IoU−c2ρ2(b,bgt)
其中
b
b
b,
b
g
t
b^{gt}
bgt 分别表示预测框和真实框的中心点,且
ρ
\rho
ρ 表示两个中心点间的欧式距离。
c
c
c 表示能够同时包含预测框和真实框的最小闭包区域的对角线距离。
3.1 优点
- DIOU在与目标框重叠时,仍然可以为边界框提供移动方向;
- DIOU可以直接最小化两个目标框的距离,因此比GIOU收敛快得多;
- DIOU还可以替换普通的IOU评价策略,应用于NMS中,使得NMS得到的结果更加合理和有效。
3.2 缺点
- DIOU仅考虑了重叠面积和中心点距离,并没有考虑到长宽比。
3.3 源代码
- 详细代码请移步:代码区
四、CIOU(Complete-IoU)
AAAI 2020(与DIOU同一篇文章) 论文链接:Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression
论文考虑到bbox回归三要素中的长宽比还没被考虑到计算中,因此CIOU在DIOU的基础上添加了长宽比的惩罚项,定义如下:
C
I
o
U
=
I
o
U
−
ρ
2
(
b
,
b
g
t
)
c
2
−
α
υ
CIoU=IoU-\frac{\rho^{2} \left ( b,b^{gt} \right ) }{c^{2}}-\alpha \upsilon
CIoU=IoU−c2ρ2(b,bgt)−αυ
υ
\upsilon
υ 是用来衡量长宽比一致性的参数,
υ
\upsilon
υ 定义如下:
υ
=
4
π
2
(
arctan
ω
g
t
h
g
t
−
arctan
ω
h
)
2
\upsilon =\frac{4}{\pi ^2} \left ( \arctan \frac{\omega ^{gt}}{h^{gt}} - \arctan \frac{\omega}{h} \right ) ^2
υ=π24(arctanhgtωgt−arctanhω)2
α
=
υ
(
1
−
I
o
U
)
+
υ
\alpha = \frac{\upsilon }{\left ( 1- IoU \right ) + \upsilon }
α=(1−IoU)+υυ
4.1 缺点
- 若预测框和gt框的长宽比相同但宽高的值不同,而长宽比的惩罚项却恒为0,会阻碍模型有效的优化。
4.2 实现代码
- 详细代码请移步:代码区
五、EIOU(Efficient-IoU)
arXiv 2021 论文链接:Focal and Efficient IOU Loss for Accurate Bounding Box Regression
EIOU是在 CIOU 的惩罚项基础上将预测框和真实框的纵横比的影响因子拆开,分别计算预测框和真实框的长和宽,并且加入Focal聚焦优质的锚框,来解决 CIOU 存在的问题。
EIoU损失函数公式如下:
L
E
I
O
U
=
L
I
O
U
+
L
d
i
s
+
L
a
s
p
=
1
−
I
O
U
+
ρ
2
(
b
,
b
g
t
)
c
2
+
ρ
2
(
ω
,
ω
g
t
)
C
ω
2
+
ρ
2
(
h
,
h
g
t
)
c
h
2
\begin{array}{l} L_{EIOU} = L_{IOU}+L_{dis}+L_{asp} \\ = 1-IOU+\frac{\rho^{2} \left ( b,b^{gt} \right ) }{c^{2}}+\frac{\rho^{2} \left ( \omega ,\omega^{gt} \right ) }{C^{2}_{\omega}}+\frac{\rho^{2} \left ( h,h^{gt} \right ) }{c^{2}_{h}} \end{array}
LEIOU=LIOU+Ldis+Lasp=1−IOU+c2ρ2(b,bgt)+Cω2ρ2(ω,ωgt)+ch2ρ2(h,hgt)
其中
C
ω
2
C_\omega^2
Cω2 和
C
h
2
C_h^2
Ch2分别是预测框和GT框最小外接矩形的宽和高。
5.1 Focal-EIOU
利用Focal Loss对EIOU进行加权处理:
L
F
o
c
a
l
−
E
I
O
U
=
I
O
U
γ
∗
L
E
I
O
U
L_{Focal-EIOU}=IOU^\gamma *L_{EIOU}
LFocal−EIOU=IOUγ∗LEIOU
其中
γ
\gamma
γ为控制异常值抑制程度的参数。该损失中的Focal与传统的Focal Loss有一定的区别,传统的Focal Loss针对越困难的样本损失越大,起到的是困难样本挖掘的作用;而根据上述公式:IOU越高的损失越大,相当于加权作用,给越好的回归目标一个越大的损失,有助于提高回归精度。
5.2 优点
- EIOU在CIOU的基础上分别计算宽高的差异值取代了纵横比,宽高损失直接使预测框与真实框的宽度和高度之差最小,使得收敛速度更快;
- 引入了Focal Loss优化了边界框回归任务中的样本不平衡问题,即减少与目标框重叠较少的大量锚框对BBox 回归的优化贡献,使回归过程专注于高质量锚框。
5.3 实现代码
- 详细代码请移步:代码区
六、Alpha-IOU
NeurIPS 2021 论文链接:Alpha-IoU: A Family of Power Intersection over Union Losses for Bounding Box Regression
基于IoU Loss推广到一个新的Power IoU系列 Loss,该系列具有一个Power IoU项和一个附加的Power正则项,具有单个Power参数
α
\alpha
α。称这种新的损失系列为
α
\alpha
α-IoU Loss。
⭐当
α
=
1
\alpha=1
α=1时,则回归到原始各个Loss。
6.1 优点
- 通过调节Power参数 α \alpha α,使检测器在实现不同水平的bbox回归精度方面具有更大的灵活性;
- 对小数据集和噪声的鲁棒性更强;
- ⭐通过实验发现,在大多数情况下,取 α \alpha α=3 的效果最好(具体还是根据自身的数据集去调整,选择最优的阈值)。
6.2 实现代码
- 详细代码请移步:代码区
七、🔥 SIOU(SCYLLA-IoU)
论文链接:SIoU Loss: More Powerful Learning for Bounding Box Regression
SIOU损失函数是引入了所需回归之间的向量角度,重新定义了距离损失,有效降低了回归的自由度,从而加速网络的收敛,进一步提升回归的准确性。
7.1 SIOU Loss
SIOU损失函数由4个Cost函数组成:
- Angle cost
- Distance cost
- Shape cost
- IoU cost
- Angle cost(角度损失):如果
α
≤
π
4
\alpha \le \frac{\pi}{4}
α≤4π ,则收敛过程将首先最小化
α
\alpha
α,否则最小化
β
\beta
β。当中心点在x轴或y轴上对齐时,
Λ
=
0
\Lambda=0
Λ=0;当中心点连接到x轴45°时,
Λ
=
1
\Lambda=1
Λ=1。
Λ = 1 − 2 ∗ sin 2 ( arcsin ( C h σ ) − π 4 ) = 1 − 2 ∗ sin 2 ( α − π 4 ) = cos 2 ( α − π 4 ) − sin 2 ( α − π 4 ) = cos ( 2 α − π 2 ) = sin ( 2 α ) \begin{array}{l} \Lambda =1-2*\sin^2\left ( \arcsin \left ( \frac{C_h}{\sigma} \right ) - \frac{\pi}{4} \right ) \\ = 1-2*\sin^2\left ( \alpha - \frac{\pi}{4} \right ) \\ = \cos ^2\left ( \alpha - \frac{\pi}{4} \right ) - \sin ^2 \left ( \alpha - \frac{\pi}{4} \right ) \\ = \cos \left ( 2\alpha - \frac{\pi}{2} \right ) \\ = \sin \left ( 2\alpha \right ) \end{array} Λ=1−2∗sin2(arcsin(σCh)−4π)=1−2∗sin2(α−4π)=cos2(α−4π)−sin2(α−4π)=cos(2α−2π)=sin(2α)
其中
C
h
C_h
Ch 为真实框和预测框中心点的高度差,
σ
\sigma
σ为真实框和预测框中心点的距离,
arcsin
(
C
h
σ
)
\arcsin (\frac{C_h}{\sigma})
arcsin(σCh) 等于角度
α
\alpha
α。
C
h
σ
=
sin
(
α
)
\frac{C_h}{\sigma} = \sin \left ( \alpha \right )
σCh=sin(α)
- Distance cost(距离损失):当
α
\alpha
α→0时,Distance cost的贡献大大降低。相反,
α
\alpha
α越接近
π
4
\frac{\pi}{4}
4π,Distance cost贡献越大。随着角度的增大,问题变得越来越难。
Δ = ∑ t = x , y ( 1 − e − γ ρ t ) \Delta =\sum_{t=x,y}^{} \left ( 1- e^{-\gamma\rho t } \right ) Δ=t=x,y∑(1−e−γρt)
其中, ρ x = ( b c x g t − b c x c w ) 2 \rho _x=\left ( \frac{b_{c_x}^{gt}-b_{c_x}}{c_w} \right ) ^2 ρx=(cwbcxgt−bcx)2, ρ y = ( b c y g t − b c y c h ) 2 \rho _y=\left ( \frac{b_{c_y}^{gt}-b_{c_y}}{c_h} \right ) ^2 ρy=(chbcygt−bcy)2, γ = 2 − Λ \gamma =2-\Lambda γ=2−Λ
γ \gamma γ被赋予时间优先的距离值,随着角度的增加。 - Shape cost(形状损失):与CIOU类似,CIOU考虑是两框整体形状的收敛,而SIOU是以长、宽两个边收敛来实现整体形状的收敛。
Ω = ∑ t = w , h ( 1 − e − ω t ) θ \Omega = \sum_{t=w,h}^{} \left ( 1-e^{-\omega t } \right ) ^\theta Ω=t=w,h∑(1−e−ωt)θ
ω w = ∣ w − w g t ∣ max ( w , w g t ) , ω h = ∣ h − h g t ∣ max ( h , h g t ) \omega _w = \frac{\left | w-w^{gt} \right | }{\max \left ( w,w^{gt} \right ) } ,\omega _h = \frac{\left | h-h^{gt} \right | }{\max \left ( h,h^{gt} \right ) } ωw=max(w,wgt)∣w−wgt∣,ωh=max(h,hgt)∣h−hgt∣ - IoU cost(IoU损失):
L b o x = 1 − I o U + Δ + Ω 2 L_{box}=1-IoU+\frac{\Delta +\Omega }{2} Lbox=1−IoU+2Δ+Ω
7.2 实现代码
- 详细代码请移步:代码区
八、🔥 WIoU(Wise-IoU)
2023 论文链接:Wise-IoU: Bounding Box Regression Loss with Dynamic Focusing Mechanism
⭐这是作者的论文解读:Wise-IoU 作者导读:基于动态非单调聚焦机制的边界框损失,非常详细,本文则不再进行叙述。
WIoU v1 构造了基于注意力的边界框损失,WIoU v2 和 v3 则是在此基础上通过构造梯度增益 (聚焦系数) 的计算方法来附加聚焦机制。
所涉及的聚焦机制有以下几种:
- 静态:当边界框的 IoU 为某一指定值时有最高的梯度增益,如 Focal EIoU v1
- 动态:享有最高梯度增益的边界框的条件处于动态变化中,如 WIoU v3
- 单调:梯度增益随损失值的增加而单调增加,如 Focal loss
- 非单调:梯度增益随损失值的增加呈非单调变化
⭐ 总结
IOU | GIOU | DIOU | CIOU | EIOU | α \alpha α-IOU | SIOU | WIOU | |
---|---|---|---|---|---|---|---|---|
优点 | 目标检测中最常用的指标,具有尺度不变性,满足非负性;同一性;对称性;三角不等性等特点 | GIOU在基于IOU特性的基础上引入最小外接框,能更好的反映两者的重合度 | DIOU在IoU的基础上直接回归两个框中心点的欧式距离,加速收敛 | CIOU在DIOU的基础上增加了检测框尺度的Loss,增加了长宽比的Loss,使得目标框回归更加稳定 | EIOU在CIOU的基础上分别计算宽高的差异值取代了纵横比,同时引入Focal Loss解决难易样本不平衡的问题 | 基于IoU Loss推广到一个新的Power IoU系列 Loss,通过调节 α \alpha α,使检测器在实现不同水平的bbox回归精度方面具有更大的灵活性 | SIOU是引入了所需回归之间的向量角度,重新定义了距离损失,有效降低了回归的自由度,加速网络的收敛,进一步提升回归的准确性 | WIoU v1 构造了基于注意力的边界框损失,WIoU v2 和 v3 则是在此基础上通过构造梯度增益 (聚焦系数) 的计算方法来附加聚焦机制。 |
缺点 | 1.若两个框不相交,不能反映两个框距离远近 2.无法精确的反映两个框的重合度大小 | 1.当检测框和真实框出现重叠退化成IOU 2.两个框相交时,在水平和垂直方向上收敛慢 | 回归过程中未考虑Bounding box的纵横比,精确度上尚有进一步提升的空间 | 若预测框和gt框的长宽比是相同的,那么长宽比的惩罚项恒为0,会阻碍模型有效的优化 | / | / | / | / |
🔮 Code
本代码摘抄于YOLOv5官方7.0版本,并在其基础上添加了Alpha-IOU、EIOU、SIOU和WIOU(后续添加)损失函数。
def bbox_iou(box1, box2, xywh=True, GIoU=False, DIoU=False, CIoU=False, SIoU=False, EIoU=False, Focal=False, alpha=1, gamma=0.5, eps=1e-7):
# Returns Intersection over Union (IoU) of box1(1,4) to box2(n,4)
# Get the coordinates of bounding boxes
if xywh: # transform from xywh to xyxy
(x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1)
w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2
b1_x1, b1_x2, b1_y1, b1_y2 = x1 - w1_, x1 + w1_, y1 - h1_, y1 + h1_
b2_x1, b2_x2, b2_y1, b2_y2 = x2 - w2_, x2 + w2_, y2 - h2_, y2 + h2_
else: # x1, y1, x2, y2 = box1
b1_x1, b1_y1, b1_x2, b1_y2 = box1.chunk(4, -1)
b2_x1, b2_y1, b2_x2, b2_y2 = box2.chunk(4, -1)
w1, h1 = b1_x2 - b1_x1, (b1_y2 - b1_y1).clamp(eps)
w2, h2 = b2_x2 - b2_x1, (b2_y2 - b2_y1).clamp(eps)
# Intersection area
inter = (b1_x2.minimum(b2_x2) - b1_x1.maximum(b2_x1)).clamp(0) * \
(b1_y2.minimum(b2_y2) - b1_y1.maximum(b2_y1)).clamp(0)
# Union Area
union = w1 * h1 + w2 * h2 - inter + eps
# IoU
# iou = inter / union # ori iou
iou = torch.pow(inter/(union + eps), alpha) # alpha iou
if CIoU or DIoU or GIoU or EIoU or SIoU:
cw = b1_x2.maximum(b2_x2) - b1_x1.minimum(b2_x1) # convex (smallest enclosing box) width
ch = b1_y2.maximum(b2_y2) - b1_y1.minimum(b2_y1) # convex height
if CIoU or DIoU or EIoU or SIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1
c2 = (cw ** 2 + ch ** 2) ** alpha + eps # convex diagonal squared
rho2 = (((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4) ** alpha # center dist ** 2
if CIoU: # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47
v = (4 / math.pi ** 2) * (torch.atan(w2 / h2) - torch.atan(w1 / h1)).pow(2)
with torch.no_grad():
alpha_ciou = v / (v - iou + (1 + eps))
return iou - (rho2 / c2 + torch.pow(v * alpha_ciou + eps, alpha)) # CIoU
elif EIoU:
rho_w2 = ((b2_x2 - b2_x1) - (b1_x2 - b1_x1)) ** 2
rho_h2 = ((b2_y2 - b2_y1) - (b1_y2 - b1_y1)) ** 2
cw2 = torch.pow(cw ** 2 + eps, alpha)
ch2 = torch.pow(ch ** 2 + eps, alpha)
if Focal:
return iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2), torch.pow(inter/(union + eps), gamma) # Focal_EIou
else:
return iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2) # EIou
elif SIoU:
# SIoU Loss https://arxiv.org/pdf/2205.12740.pdf
s_cw = (b2_x1 + b2_x2 - b1_x1 - b1_x2) * 0.5 + eps
s_ch = (b2_y1 + b2_y2 - b1_y1 - b1_y2) * 0.5 + eps
sigma = torch.pow(s_cw ** 2 + s_ch ** 2, 0.5)
sin_alpha_1 = torch.abs(s_cw) / sigma
sin_alpha_2 = torch.abs(s_ch) / sigma
threshold = pow(2, 0.5) / 2
sin_alpha = torch.where(sin_alpha_1 > threshold, sin_alpha_2, sin_alpha_1)
angle_cost = torch.cos(torch.arcsin(sin_alpha) * 2 - math.pi / 2)
rho_x = (s_cw / cw) ** 2
rho_y = (s_ch / ch) ** 2
gamma = angle_cost - 2
distance_cost = 2 - torch.exp(gamma * rho_x) - torch.exp(gamma * rho_y)
omiga_w = torch.abs(w1 - w2) / torch.max(w1, w2)
omiga_h = torch.abs(h1 - h2) / torch.max(h1, h2)
shape_cost = torch.pow(1 - torch.exp(-1 * omiga_w), 4) + torch.pow(1 - torch.exp(-1 * omiga_h), 4)
return iou - torch.pow(0.5 * (distance_cost + shape_cost) + eps, alpha) # SIou
return iou - rho2 / c2 # DIoU
c_area = cw * ch + eps # convex area
return iou - torch.pow((c_area - union) / c_area + eps, alpha) # GIoU https://arxiv.org/pdf/1902.09630.pdf
return iou # IoU