學習視頻:
yolov8 | 損失函數 之 5、類別損失_嗶哩嗶哩_bilibili
yolov8 | 損失函數 之 6、定位損失 CIoU + DFL_嗶哩嗶哩_bilibili
2.13、yolov8損失函數_嗶哩嗶哩_bilibili
YOLOv8 的損失函數由類別損失和定位損失構成
類別損失:BCE Loss
定位損失:CIoU Loss + DFL(Distribution Focal Loss)
損失函數計算公式如下:
YOLOv8 損失函數?
注意:YOLOv8 只需要計算正樣本的損失值,負樣本不參數損失計算?
目錄
1.類別損失
1.1 YOLOv5
1.2 YOLOv8:
2.定位損失
2.1 CIoU Loss
2.2?Distribution Focal Loss
2.2.1 前言
2.2.2 為什么使用Distribution Focal Loss?
2.2.3 原理
2.2.4 關于reg_max取值的補充
1.類別損失
?YOLOv8 的類別損失使用的依舊是 BCE Loss ,與? YOLOv5 一致,但類別的 one-hot 標簽值的設置有區別,下面會作兩者的對比
BCE Loss 的計算公式如下:
BCE Loss
1.1 YOLOv5
: c 類別在 one-hot 向量中的標簽值,如果未使用標簽平滑技術就是非0即1
:正樣本預測框的對于 c 類別的預測概率值應用 Sigmoid 函數后的值
對于的理解可以看下圖:
YOLOv5類別損失
1.2 YOLOv8:
下面同樣舉的例子是未使用標簽平滑技術
?YOLOv8類別損失
??:看該正樣本預測框匹配到的 gt_box 的真實類別是什么,將其他類別的
置為 0 ,而正確類別的
的計算方法:先計算出該正樣本預測框與匹配到的 gt_box 的 align_metric,然后再對得到的 align_metric 作歸一化,?align_metric 值的計算公式如下:
align_metric計算公式
上式中的?bbox_score 是正樣本預測框對于正確類別的預測概率, CIoU 值即該正樣本預測框與匹配到的 gt_box 計算得到
align_metric 的歸一化方法: YOLOv8 源碼中是取出當前 batch 中所有正樣本預測框中的最大CIoU?值 max_CIoU 和最大 align_metric 值 max_align_metric ,對上面得到的原始 align_metric 值先乘以 max_CIoU 再除以 max_align_metric 完成歸一化處理
?:正樣本預測框的對于 c 類別的預測概率值應用 Sigmoid 函數后的值
2.定位損失
2.1 CIoU Loss
CIoU Loss的計算公式如下:
2.2?Distribution Focal Loss
論文名稱:《Generalized Focal Loss: Learning Qualified and Distributed Bounding Boxes for Dense Object Detection》, DFL 只是該論文中的其中一個
論文地址:https://arxiv.org/pdf/2006.04388
2.2.1 前言
在以往的目標檢測任務中, bounding box 坐標的網絡預測結果服從狄拉克分布,簡單理解就是網絡針對預測框的坐標值只會輸出一個確定的值,預測出的那個值概率為 1 ,其他值的概率為 0 ,因為只輸出了這一個結果。而在 YOLOv8 中,首次使用 Distribution Focal Loss 參與其損失函數計算,網絡模型針對(l、t、r、b)輸出多個值,這多個值服從一般分布和任意分布,每個值都有它們自己對應的概率,不像狄拉克分布只預測出一個值,概率為 1
2.2.2 為什么使用Distribution Focal Loss?
先看下面兩張圖片。左圖中,滑板被海水給模糊掉了,所以導致滑板邊界模糊不確定;右圖中,第一只大象的身體被嚴重遮擋了,所以導致大象的邊界也不是很清晰
在復雜的場景中,通常會存在邊界模糊和不確定的情況。在這種前提情況下,如果目標檢測模型使用狄拉克分布,即針對預測框的坐標值只輸出一個確定值是非常不靈活和不準確的,沒有考慮真實框邊界的模糊性和不確定性,因此可以使用 Distribution Focal Loss ,這也是 Distribution Focal Loss 提出的原因
2.2.3 原理
作者提出直接回歸一個任意分布,對邊界框的坐標進行建模。后面我們按照 YOLOv8 的源碼實現展開講解
在 YOLOv8 中,針對每一個預測框的的 4 個值,網絡輸出 4 個值對應的長度為reg_max(YOLOv8中默認為16)的向量,下面已?
?舉例:
需要注意的是, 4 個值各自的長度為 16 的向量是做了Softmax處理的, 16 個值的和為 1?
損失函數設計
思路:作者發現對于那些非常清晰明確的邊界,它們的分布會像上圖中的 top、right、bottom 比較尖銳和集中。而對于那些比較模糊不確定的邊界,它們的分布會像上圖中的 left 比較平,而且有時候會出現雙峰的情況。所以作者想要模型來學習像上圖中的 top、right、bottom 比較集中的、尖銳的分布
實現:設計損失函數時,盡可能增加真實值左邊和右邊兩個值的概率,使得網絡快速的聚焦于這個真實值附近的值,這樣就可以把分布給學習成集中的、尖銳的樣子,所以設計 DFL 損失函數時只有標簽值左右兩個值的概率參與計算,其他值的概率不參與計算
DFL損失函數設計
注意:
(1)
:標簽值左邊值應用Softmax后的值,
:標簽值右邊值應用Softmax后的值
(2)計算DFL Loss損失函數時?left、top、right、bottom?標簽值需要將其轉換為在 feature map 尺度下的值,并且需要作長度限制,0<?
?< reg_max (YOLOv8中為 reg_max = 16)
YOLOv8 中 DFL 損失函數的代碼實現在 ultralytics/utils/loss.py 的 Class DFLoss :
DFL源碼實現?
#DFL Loss計算
class DFLoss(nn.Module):"""Criterion class for computing DFL losses during training."""def __init__(self, reg_max=16) -> None:"""Initialize the DFL module."""super().__init__()self.reg_max = reg_maxdef __call__(self, pred_dist, target):'''Args:pred_dist: {Tensor:(6448,16)},存放1612個正樣本的 ltrb 4個值對應的16個概率分布值6448 = 1612 x 416 :概率分布target: {Tensor:(1612,4)},存放1612個正樣本對應的真實框的ltrb,其值已縮放到各自的feature map尺度下Returns:out:{Tensor:(1612,1)},存放每個正樣本的DFL損失值'''#對正樣本對應的真實框的ltrb作長度限制處理,限制在0-15target = target.clamp_(0, self.reg_max - 1 - 0.01)tl = target.long()#tl:{Tensor:(1612,4)},標簽值左邊的值tr = tl + 1#tr:{Tensor:(1612,4)},標簽值右邊邊的值wl = tr - target#wl:{Tensor:(1612,4)},左邊值的權重wr = 1 - wl#wr:{Tensor:(1612,4)},右邊值的權重#損失值計算,{Tensor:(1612,4)} -> mean(-1) ->{Tensor:(1612,1)}return (F.cross_entropy(pred_dist, tl.view(-1), reduction="none").view(tl.shape) * wl+ F.cross_entropy(pred_dist, tr.view(-1), reduction="none").view(tl.shape) * wr).mean(-1, keepdim=True)
2.2.4 關于reg_max取值的補充
參考筆記:https://zhuanlan.zhihu.com/p/702085780
由于 Softmax 的取值范圍為 [0,1] ,所以根據上面提到的計算公式可以發現??∈[0,reg_max?1] ,如果 reg_max = 16 ,在特征圖上所能預測的最大預測框是?
?都取?15?時,此時預測框的高度和寬度是 w_max = 30,h_max = 30 ,由于特征圖相對于原始 image 的下采樣倍數?stride ∈ [8,16,32],如果取最大下采樣倍數 stride = 32 ,則在原圖上所能預測的最大 bbox 高度和寬度為?w_max,h_max = 30 * 32 = 960 ,那么如果圖像中的原始目標的寬度或者高度過大,則會出現預測框小于原始目標的情況。下面舉個例子理解
目標過大時的YOLOv8的GT框與預測框
圖片中有一個目標其 gt_box 的寬度為 1000 ,但我們實際能預測的最大寬度是 w_max = 960 ,這就會導致預測不精準,此時則需要根據具體情況對 reg_max 作調整