YOLO v8目标检测
损失函数理论
在YOLO v5模型中,cls
, reg
, obj
代表的是三个不同的预测组成部分,对应的损失函数如下:
-
cls: 这代表类别预测(classification)。对应的损失是类别预测损失(loss_cls)。这个损失计算的是模型预测的类别与真实类别之间的差异。它使用的是二元交叉熵损失(BCE Loss)。
-
reg: 这代表边界框回归(bounding box regression)。对应的损失是IoU损失(loss_iou)。这个损失计算的是模型预测的边界框与真实边界框之间的交并比(IoU)差异。这里的交并比是通过IoU损失函数计算得出的。
-
obj: 这代表目标存在概率(objectness)。对应的损失是对象存在概率损失(loss_obj)。这个损失计算的是模型预测的目标存在概率与真实存在概率之间的差异。这也是用二元交叉熵损失(BCE Loss)计算的。
在引出v8的损失函数之前,首先对分类损失的相关概念进行总结。
信息量
定义:事件包含的信息量大小(事件发生的难度有多大)。
-
小概率事件,它发生的难度比较大,所以有较大的信息量
-
大概率事件,它发生的难度比较小,所以有较小的信息量
概率和信息量是负相关的
性质:两个事件同时发生的信息量等于两个事件的信息量相加I(AB)=I(A) + I(B)
满足对数函数的性质
I ( x ) : = log 2 ( 1 p ( x ) ) = − log 2 ( p ( x ) ) I(x):=\log _{2}\left(\frac{1}{p_{(x)}}\right)=-\log _{2}\left(p_{(x)}\right) I(x):=log2(p(x)1)=−log2(p(x))
I ( A B ) = log 2 ( 1 p ( A B ) ) = log 2 ( 1 p ( A ) p ( B ) ) = log 2 ( 1 p ( A ) ) + log 2 ( 1 p ( B ) ) = I ( A ) + I ( B ) I(A B)=\log _{2}\left(\frac{1}{p(A B)}\right)=\log _{2}\left(\frac{1}{p(A) p(B)}\right)=\log _{2}\left(\frac{1}{p(A)}\right)+\log _{2}\left(\frac{1}{p(B)}\right)=I(A)+I(B) I(AB)=log2(p(AB)1)=log2(p(A)p(B)1)=log2(p(A)1)+log2(p(B)1)=I(A)+I(B)
举例:抛硬币, 正面概率 P(A) = 0.2, 反面概率 P(B) = 0.8
I ( A ) = − log 2 ( 0.2 ) = 2.32 , I ( B ) = − log 2 ( 0.8 ) = 0.32 I(A)=-\log _{2}(0.2)=2.32, \quad I(B)=-\log _{2}(0.8)=0.32 I(A)=−log2(0.2)=2.32,I(B)=−log2(0.8)=0.32
小概率事件有较大的信息量,大概率事件有较小的信息量
信息熵
定义:概率分布 的信息量期望: H(p) := E(I(x)),期望使用的就是概率论中离散型随机变量的计算公式
H ( p ) = ∑ p i I i p = − ∑ p i log 2 ( p i ) H(p)=\sum p_{i} I_{i}^{p}=-\sum p_{i} \log _{2}\left(p_{i}\right) H(p)=∑piIip=−∑pilog2(pi)
作用:用来评估概率模型的不确定性程度
-
不确定性越大,信息熵越大
-
不确定性越小,信息熵越小
例1 : 抛硬币, 正面概率 P(A) = 0.5, 反面概率 P(B) = 0.5
H ( p ) = ∑ p i I i p = p ( A ) ⋅ log 2 ( 1 / p ( A ) ) + p ( B ) ⋅ log 2 ( 1 / p ( B ) ) = 0.5 ⋅ log 2 ( 1 / 0.5 ) + 0.5 ⋅ log 2 ( 1 / 0.5 ) = 0.5 ⋅ 1 + 0.5 ⋅ 1 = 1 \begin{aligned} H(p) & =\sum p_{i} I_{i}^{p} \\ & =p_{(A)} \cdot \log _{2}\left(1 / p_{(A)}\right)+p_{(B)} \cdot \log _{2}\left(1 / p_{(B)}\right) \\ & =0.5 \cdot \log _{2}(1 / 0.5)+0.5 \cdot \log _{2}(1 / 0.5) \\ & =0.5 \cdot 1+0.5 \cdot 1 \\ & =1 \end{aligned} H(p)=∑piIip=p(A)⋅log2(1/p(A))+p(B)⋅log2(1/p(B))=0.5⋅log2(1/0.5)+0.5⋅log2(1/0.5)=0.5⋅1+0.5⋅1=1
例二:抛硬币, 正面概率 P(A) = 0.2, 反面概率 P(B) = 0.8
H ( p ) = ∑ p i I i p = p ( A ) ⋅ log 2 ( 1 / p ( A ) ) + p ( B ) ⋅ log 2 ( 1 / p ( B ) ) = 0.2 ⋅ log 2 ( 1 / 0.2 ) + 0.8 ⋅ log 2 ( 1 / 0.8 ) = 0.2 ⋅ 2.32 + 0.8 ⋅ 0.32 = 0.72 \begin{aligned} H(p) & =\sum p_{i} I_{i}^{p} \\ & =p_{(A)} \cdot \log _{2}\left(1 / p_{(A)}\right)+p_{(B)} \cdot \log _{2}\left(1 / p_{(B)}\right) \\ & =0.2 \cdot \log _{2}(1 / 0.2)+0.8 \cdot \log _{2}(1 / 0.8) \\ & =0.2 \cdot 2.32+0.8 \cdot 0.32 \\ & =0.72 \end{aligned} H(p)=∑piIip=p(A)⋅log2(1/p(A))+p(B)⋅log2(1/p(B))=0.2⋅log2(1/0.2)+0.8⋅log2(1/0.8)=0.2⋅2.32+0.8⋅0.32=0.72
结论:
-
若概率密度均匀,产生的随机变量的不确定性就更高,则熵的值就更大
-
若概率密度聚拢,产生的随机变量的不确定性就更低,则熵的值较小
交叉熵 Cross Entropy
假设 真实概率分布为 p、预测概率分布 (估计概率分布)为 q
定义:预测概率分布q 对真实的概率分布 p 的平均信息量的估计,叫做交叉熵
H ( p , q ) = ∑ p i I i q = − ∑ p i log 2 ( q i ) H(p, q)=\sum p_{i} I_{i}^{q}=-\sum p_{i} \log _{2}\left(q_{i}\right) H(p,q)=∑piIiq=−∑pilog2(qi)
例1 : 抛硬币, 正面真实概率 p(A) = 0.5, 反面真实概率 p(B) = 0.5 ; 正面估计概率 q(A) = 0.2, 反面估计概率 q(B) = 0.8
H ( p , q ) = − ∑ p i log 2 ( q i ) = p ( A ) ⋅ log 2 ( 1 / q ( A ) ) + p ( B ) ⋅ log 2 ( 1 / q ( B ) ) = 0.5 ⋅ log 2 ( 1 / 0.2 ) + 0.5 ⋅ log 2 ( 1 / 0.8 ) = 0.5 ⋅ 2.32 + 0.5 ⋅ 0.32 = 1.32 \begin{aligned} H(p, q) & =-\sum p_{i} \log _{2}\left(q_{i}\right) \\ & =p_{(A)} \cdot \log _{2}\left(1 / q_{(A)}\right)+p_{(B)} \cdot \log _{2}\left(1 / q_{(B)}\right) \\ & =0.5 \cdot \log _{2}(1 / 0.2)+0.5 \cdot \log _{2}(1 / 0.8) \\ & =0.5 \cdot 2.32+0.5 \cdot 0.32 \\ & =1.32 \end{aligned} H(p,q)=−∑pilog2(qi)=p(A)⋅log2(1/q(A))+p(B)⋅log2(1/q(B))=0.5⋅log2(1/0.2)+0.5⋅log2(1/0.8)=0.5⋅2.32+0.5⋅0.32=1.32
例2:抛硬币,正面真实概率p(A)=0.5,反面真实概率p(B)=0.5;正面估计概率p(A)=0.4、反面估计概率p(B)=0.6
H ( p , q ) = − ∑ p i log 2 ( q i ) = p ( A ) ⋅ log 2 ( 1 / q ( A ) ) + p ( B ) ⋅ log 2 ( 1 / q ( B ) ) = 0.5 ⋅ log 2 ( 1 / 0.4 ) + 0.5 ⋅ log 2 ( 1 / 0.6 ) = 0.5 ⋅ 1.32 + 0.5 ⋅ 0.74 = 1.03 \begin{aligned} H(p, q) & =-\sum p_{i} \log _{2}\left(q_{i}\right) \\ & =p_{(A)} \cdot \log _{2}\left(1 / q_{(A)}\right)+p_{(B)} \cdot \log _{2}\left(1 / q_{(B)}\right) \\ & =0.5 \cdot \log _{2}(1 / 0.4)+0.5 \cdot \log _{2}(1 / 0.6) \\ & =0.5 \cdot 1.32+0.5 \cdot 0.74 \\ & =1.03 \end{aligned} H(p,q)=−∑pilog2(qi)=p(A)⋅log2(1/q(A))+p(B)⋅log2(1/q(B))=0.5⋅log2(1/0.4)+0.5⋅log2(1/0.6)=0.5⋅1.32+0.5⋅0.74=1.03
结论:
-
预估概率分布与真实概率分布越接近,交叉熵越小
-
交叉熵的值总是大于熵的值(根据吉布斯不等式)
若 ∑ i = 1 n p i = ∑ i = 1 n q i = 1 , 且 p i , q i ∈ ( 0 , 1 ] , 则有 : − ∑ i = 1 n p i log p i ≤ − ∑ i = 1 n p i log q i , 等号成立当且仅当 p i = q i ∀ i 若 \sum_{i=1}^{n} p_{i}=\sum_{i=1}^{n} q_{i}=1 , 且 p_{i}, q_{i} \in(0,1] , 则有: -\sum_{i=1}^{n} p_{i} \log p_{i} \leq-\sum_{i=1}^{n} p_{i} \log q_{i} \text {, } 等号成立当且仅当 p_{i}=q_{i} \forall i 若i=1∑npi=i=1∑nqi=1,且pi,qi∈(0,1],则有:−i=1∑npilogpi≤−i=1∑npilogqi, 等号成立当且仅当pi=qi∀i
相对熵
KL散度
以Kullback和Leibler的名字命名,也被称为相对熵
作用:用于衡量2个概率分布之间的差异
D K L ( p ∥ q ) = ∑ p i [ I q − I p ] # I q − I p 为信息量之差 = ∑ p i [ log 2 ( 1 / q i ) − log 2 ( 1 / p i ) ] = ∑ p i log 2 ( 1 / q i ) − ∑ p i log 2 ( 1 / p i ) = H ( p , q ) − H ( p ) = ∑ p i l o g 2 ( p i / q i ) \begin{aligned} D_{K L}(p \| q) & =\sum p_{i}\left[I_{q}-I_{p}\right] \quad \# I_{q}-I_{p} \text { 为信息量之差 } \\ & =\sum p_{i}\left[\log _{2}\left(1 / q_{i}\right)-\log _{2}\left(1 / p_{i}\right)\right] \\ & =\sum p_{i} \log _{2}\left(1 / q_{i}\right)-\sum p_{i} \log _{2}\left(1 / p_{i}\right) \\ & =H(p, q)-H(p) \\ & =\sum p_{i} log _{2}\left(p_{i} / q_{i}\right) \end{aligned} DKL(p∥q)=∑pi[Iq−Ip]#Iq−Ip 为信息量之差 =∑pi[log2(1/qi)−log2(1/pi)]=∑pilog2(1/qi)−∑pilog2(1/pi)=H(p,q)−H(p)=∑pilog2(pi/qi)
当p和q的分布完全相同时值为0
Cross Entropy loss
预测分布q与真实分布p之间的差距,所以我们可直接将损失函数定义为KL散度:
损失函数: L o s s = D ( p ∥ q ) = H ( p , q ) − H ( p ) = ∑ p i log 2 ( 1 / q i ) − ∑ p i log 2 ( 1 / p i ) \text { 损失函数: } L o s s=D(p \| q)=H(p, q)-H(p)=\sum p_{i} \log _{2}\left(1 / q_{i}\right)-\sum p_{i} \log _{2}\left(1 / p_{i}\right) 损失函数: Loss=D(p∥q)=H(p,q)−H(p)=∑pilog2(1/qi)−∑pilog2(1/pi)
对于分类问题,真实分布是一个单点分布,真实类别的概率为1,其他类别的概率都为0,类似如下:
类别 | class1 | class2 | class3 | class4 |
---|---|---|---|---|
概率 | 0 | 0 | 1 | 0 |
p class 1 = p class 2 = p class 4 = 0 , log 2 ( 1 / p class 3 ) = 0 所以 , H ( p ) = ∑ p i log 2 ( 1 / p i ) = 0 p_{\text {class } 1}=p_{\text {class } 2}=p_{\text {class } 4}=0, \quad \log _{2}\left(1 / p_{\text {class } 3}\right)=0 所以, H(p)=\sum p_{i} \log _{2}\left(1 / p_{i}\right)=0 pclass 1=pclass 2=pclass 4=0,log2(1/pclass 3)=0所以,H(p)=∑pilog2(1/pi)=0
Loss = D ( p ∥ q ) = H ( p , q ) − H ( p ) = H ( p , q ) \text { Loss }=D(p \| q)=H(p, q)-H(p)=H(p, q) Loss =D(p∥q)=H(p,q)−H(p)=H(p,q)
多分类 : E = − ∑ i = 1 n y i ∗ log ( p i ) 多分类: E=-\sum_{i=1}^{n} y_{i} * \log \left(p_{i}\right) 多分类:E=−i=1∑nyi∗log(pi)
二分类 : E = − [ y ∗ log ( p ) + ( 1 − y ) ∗ log ( 1 − p ) ] 二分类: E=-[y * \log (p)+(1-y) * \log (1-p)] 二分类:E=−[y∗log(p)+(1−y)∗log(1−p)]
Focal loss
Focal loss是何恺明提出的一种新的loss计算方案。其具有两个重要的特点。
-
控制正负样本的权重
-
控制容易分类和难分类样本的权重
正负样本的概念如下:
一张图像可能生成成千上万的候选框,但是其中只有很少一部分是包含目标的的,有目标的就是正样本,没有目标的就是负样本。(负样本的占比过多导致损失值大多数是负样本的损失值)
容易分类和难分类样本的概念如下:
假设存在一个二分类,样本1属于类别1的pt=0.9,样本2属于类别1的pt=0.6,显然前者更可能是类别1,其就是容易分类的样本;后者有可能是类别1,所以其为难分类样本。
首先我们对提到的二分类交叉熵损失进行简化
二分类 : E = − [ y ∗ log ( p ) + ( 1 − y ) ∗ log ( 1 − p ) ] 二分类: E=-[y * \log (p)+(1-y) * \log (1-p)] 二分类:E=−[y∗log(p)+(1−y)∗log(1−p)]
CE ( p , y ) = { − log ( p ) if y = 1 − log ( 1 − p ) otherwise \operatorname{CE}(p, y)=\left\{\begin{array}{ll} -\log (p) & \text { if } y=1 \\ -\log (1-p) & \text { otherwise } \end{array}\right. CE(p,y)={−log(p)−log(1−p) if y=1 otherwise
p t = { p if y = 1 1 − p otherwise p_{\mathrm{t}}=\left\{\begin{array}{ll} p & \text { if } y=1 \\ 1-p & \text { otherwise } \end{array}\right. pt={p1−p if y=1 otherwise
CE ( p , y ) = CE ( p t ) = − log ( p t ) \operatorname{CE}(p, y)=\operatorname{CE}\left(p_{\mathrm{t}}\right)=-\log \left(p_{\mathrm{t}}\right) CE(p,y)=CE(pt)=−log(pt)
想要降低负样本的影响,可以在常规的损失函数前增加一个系数αt。与Pt类似,当label=1的时候,αt=α;当label=otherwise的时候,αt=1 - α,a的范围也是0到1。此时我们便可以通过设置α实现控制正负样本对loss的贡献
α t = { α if y = 1 1 − α otherwise \alpha_{t}=\left\{\begin{array}{cc} \alpha & \text { if } y=1 \\ 1-\alpha & \text { otherwise } \end{array}\right. αt={α1−α if y=1 otherwise
C E ( p , y , α ) = { − log ( p ) ∗ α if y = 1 − log ( 1 − p ) ∗ ( 1 − α ) if y = 0 C E(p, y, \alpha)=\left\{\begin{array}{cc} -\log (p) * \alpha & \text { if } y=1 \\ -\log (1-p) *(1-\alpha) & \text { if } y=0 \end{array}\right. CE(p,y,α)={−log(p)∗α−log(1−p)∗(1−α) if y=1 if y=0
在控制容易分类和难分类样本的权重的时候引入了一个调制系数的概念。
( 1 − p t ) γ \left(1-\mathrm{p}_{\mathrm{t}}\right)^{\gamma} (1−pt)γ
-
当pt趋于0的时候,调制系数趋于1,对于总的loss的贡献很大。当pt趋于1的时候,调制系数趋于0,也就是对于总的loss的贡献很小。
-
当γ=0的时候,focal loss就是传统的交叉熵损失,可以通过调整γ实现调制系数的改变。
FL ( p t ) = − α t ( 1 − p t ) γ log ( p t ) \operatorname{FL}\left(p_{\mathrm{t}}\right)=-\alpha_{\mathrm{t}}\left(1-p_{\mathrm{t}}\right)^{\gamma} \log \left(p_{\mathrm{t}}\right) FL(pt)=−αt(1−pt)γlog(pt)
DFL loss
Loss 计算包括 2个分支:分类和回归分支,没有了以前的objectness 分支。
- 分类分支依然采用
BCE LOSS
- 回归分支需要和 Distribution Focal Loss (DFL)中提出的积分形式表示法绑定, 因此使用了
DFL
,同时还使用了CIoULoss
最终的loSS是对3个LoSS采用一定权重比例加权。
针对边界框模糊设计的损失函数
D F L ( S i , S i + 1 ) = − ( ( y i + 1 − y ) log ( S i ) + ( y − y i ) log ( S i + 1 ) ) \mathbf{D F L}\left(\mathcal{S}_{i}, \mathcal{S}_{i+1}\right)=-\left(\left(y_{i+1}-y\right) \log \left(\mathcal{S}_{i}\right)+\left(y-y_{i}\right) \log \left(\mathcal{S}_{i+1}\right)\right) DFL(Si,Si+1)=−((yi+1−y)log(Si)+(y−yi)log(Si+1))
模型训练执行步骤
from ultralytics import YOLOdef train_model():# Load a model#model = YOLO('yolov8n.yaml') # build a new model from YAMLmodel = YOLO('yolov8s.pt') # load a pretrained model (recommended for training)#model = YOLO('yolov8n.yaml').load('yolov8n.pt') # build from YAML and transfer weights# Train the modelresults = model.train(data='coco128.yaml', epochs=50, imgsz=640, batch=8, workers= 4, device=[0])return resultsif __name__ == '__main__':results = train_model()
正负样本匹配的执行步骤
Task-Aligned Assigner,又名对齐分配器,在YOLOv8中是一种动态的分配策略。
针对所有像素点预测的 Cls score 和 Reg Score(Box与每个GT box的IOU) 通过加权的方式得到最终的加权分数,通过对加权分数进行排序后选择Topk个正样本。
t = s α + u β t=s^{\alpha}+u^{\beta} t=sα+uβ
s 是标注类别对应的预测分值,u 是预测框和 gt 框的 iou,两者相乘就可以衡量对齐程度。
正样本匹配处理流程
-
解析预测框坐标(l,t,r,b)→→(cmin,ymin,max,ymax)
-
粗筛正样本:筛选出落在gt_box范围内的anchor,作为正样本
-
在上一步粗筛出来的正样本基础上精筛正样本:
- 提取bboc_score、计算CIoU
- 计算出的align_metric:
- (TAL)align_matric = bbox_score0.5 * CIoU0.6
- 根据align_metric的值,筛选出top-10作为正样本。
-
处理一个anchorpoint可能匹配到多个gt_box的情况,仅保留最大CloU的那个匹配。
断点调试的代码注释需要的可以联系。