【YOLOv5/v7改進系列】替換損失函數為WIOU、CIOU、GIOU、SIOU、DIOU、EIOU、Focal C/G/S/D/EIOU等

一、導言

在目標檢測任務中,損失函數的主要作用是衡量模型預測的邊界框(bounding boxes)與真實邊界框之間的匹配程度,并指導模型學習如何更精確地定位和分類目標。損失函數通常由兩部分構成:分類損失(用于判斷物體屬于哪個類別)和回歸損失(用于調整預測邊界框的位置和尺寸以更好地匹配真實目標)。一個好的損失函數能夠幫助模型快速且準確地收斂,提高檢測性能。

二、YOLO訓練中常見且有效的損失函數
1.SIOU (Sum of Intersection over Union)

SIOU不是一個廣泛認可的術語,但若假設這是對某種綜合IoU概念的提及,其潛在的優點可能在于嘗試結合不同IoU變體的優勢,比如同時考慮重疊區域、最小外包矩形、中心點距離等,以提供一個更全面的評估標準,可能在某些特定場景下提升檢測精度。

2.EIOU (Enhanced Intersection over Union)

EIOU是對IOU的一個增強版本,旨在進一步提升回歸損失的效果。它可能通過額外考慮邊界框尺寸、形狀或位置關系的度量,以更精細地引導邊界框的調整。EIOU的優點在于它能更有效地處理極端情況,如極度傾斜或部分重疊的目標,從而提高檢測的魯棒性和準確性。

3.DIOU (Distance Intersection over Union)

DIOU在傳統IOU的基礎上,加入了兩個邊界框中心點之間的歐幾里得距離,這有助于直接最小化預測框與真實框之間的距離,加快了收斂速度并改善了對密集對象和極端長寬比目標的檢測效果。其優點包括減少重疊區域之外的定位誤差,尤其在處理重疊少或無重疊情況時更為有效。

4.GIOU (Generalized Intersection over Union)

GIOU解決了IOU無法懲罰預測框未能完全覆蓋真實框的問題,通過計算預測框與真實框的最小外包矩形與它們交集的比值,促使預測框不僅盡可能重疊,而且形狀和大小也要更加接近真實框。GIOU的優點在于能有效引導框的擴展,尤其是在目標被嚴重遮擋或僅部分可見時,提升檢測的完整性。

5.CIOU (Complete Intersection over Union)

CIOU在GIOU的基礎上,進一步加入了邊界框中心點距離的懲罰項以及對寬高比的約束,形成了一個更為全面的損失函數。它不僅優化了重疊區域的測量,還解決了邊界框尺寸不一致的問題,從而在各種復雜場景下都能提供穩定的性能提升。CIOU的優點在于它是目前較為全面的回歸損失函數,能夠綜合考慮重疊、中心點距離和寬高比,提高了檢測的準確性和效率。

這些改進的IoU損失函數都是為了克服傳統IOU作為損失函數時存在的局限性,如只關注重疊區域而不考慮位置偏差或形狀不匹配的問題,通過不斷地優化,這些新提出的損失函數使得目標檢測系統的性能得到了顯著提升。

三、YOLOv7-tiny改進工作

了解二后,打開YOLOv7項目文件下的utils文件夾下的general.py,搜索def bbox_iou定位到如下行,

替換如下代碼為

class WIoU_Scale:''' monotonous: {None: origin v1True: monotonic FM v2False: non-monotonic FM v3}momentum: The momentum of running mean'''iou_mean = 1.monotonous = False  # (false為v3,true為v2,none為v1)_momentum = 1 - 0.5 ** (1 / 7000)_is_train = Truedef __init__(self, iou):self.iou = iouself._update(self)@classmethoddef _update(cls, self):if cls._is_train: cls.iou_mean = (1 - cls._momentum) * cls.iou_mean + \cls._momentum * self.iou.detach().mean().item()@classmethoddef _scaled_loss(cls, self, gamma=1.9, delta=3):if isinstance(self.monotonous, bool):if self.monotonous:return (self.iou.detach() / self.iou_mean).sqrt()else:beta = self.iou.detach() / self.iou_meanalpha = delta * torch.pow(gamma, beta - delta)return beta / alphareturn 1def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, SIoU=False, EIoU=False, WIoU=False,Focal=False, alpha=1, gamma=0.5, scale=False, eps=1e-7):# Returns the IoU of box1 to box2. box1 is 4, box2 is nx4box2 = box2.T# Get the coordinates of bounding boxesif x1y1x2y2:  # x1, y1, x2, y2 = box1b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]else:  # transform from xywh to xyxyb1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2# Intersection areainter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \(torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)# Union Areaw1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + epsw2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + epsunion = w1 * h1 + w2 * h2 - inter + epsif scale:self = WIoU_Scale(1 - (inter / union))# IoU# iou = inter / union # ori iouiou = torch.pow(inter / (union + eps), alpha)  # alpha iouif CIoU or DIoU or GIoU or EIoU or SIoU or WIoU:cw = b1_x2.maximum(b2_x2) - b1_x1.minimum(b2_x1)  # convex (smallest enclosing box) widthch = b1_y2.maximum(b2_y2) - b1_y1.minimum(b2_y1)  # convex heightif CIoU or DIoU or EIoU or SIoU or WIoU:  # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1c2 = (cw ** 2 + ch ** 2) ** alpha + eps  # convex diagonal squaredrho2 = (((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4) ** alpha  # center dist ** 2if CIoU:  # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47v = (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))if Focal:return iou - (rho2 / c2 + torch.pow(v * alpha_ciou + eps, alpha)), torch.pow(inter / (union + eps),gamma)  # Focal_CIoUelse:return iou - (rho2 / c2 + torch.pow(v * alpha_ciou + eps, alpha))  # CIoUelif EIoU:rho_w2 = ((b2_x2 - b2_x1) - (b1_x2 - b1_x1)) ** 2rho_h2 = ((b2_y2 - b2_y1) - (b1_y2 - b1_y1)) ** 2cw2 = 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_EIouelse:return iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2)  # EIouelif SIoU:# SIoU Loss https://arxiv.org/pdf/2205.12740.pdfs_cw = (b2_x1 + b2_x2 - b1_x1 - b1_x2) * 0.5 + epss_ch = (b2_y1 + b2_y2 - b1_y1 - b1_y2) * 0.5 + epssigma = torch.pow(s_cw ** 2 + s_ch ** 2, 0.5)sin_alpha_1 = torch.abs(s_cw) / sigmasin_alpha_2 = torch.abs(s_ch) / sigmathreshold = pow(2, 0.5) / 2sin_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) ** 2rho_y = (s_ch / ch) ** 2gamma = angle_cost - 2distance_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)if Focal:return iou - torch.pow(0.5 * (distance_cost + shape_cost) + eps, alpha), torch.pow(inter / (union + eps), gamma)  # Focal_SIouelse:return iou - torch.pow(0.5 * (distance_cost + shape_cost) + eps, alpha)  # SIouelif WIoU:if Focal:raise RuntimeError("WIoU do not support Focal.")elif scale:return getattr(WIoU_Scale, '_scaled_loss')(self), (1 - iou) * torch.exp((rho2 / c2)), iou  # WIoU https://arxiv.org/abs/2301.10051else:return iou, torch.exp((rho2 / c2))  # WIoU v1if Focal:return iou - rho2 / c2, torch.pow(inter / (union + eps), gamma)  # Focal_DIoUelse:return iou - rho2 / c2  # DIoUc_area = cw * ch + eps  # convex areaif Focal:return iou - torch.pow((c_area - union) / c_area + eps, alpha), torch.pow(inter / (union + eps),gamma)  # Focal_GIoU https://arxiv.org/pdf/1902.09630.pdfelse:return iou - torch.pow((c_area - union) / c_area + eps, alpha)  # GIoU https://arxiv.org/pdf/1902.09630.pdfif Focal:return iou, torch.pow(inter / (union + eps), gamma)  # Focal_IoUelse:return iou  # IoU

打開utils文件夾下的loss.py,搜索class ComputeLossOTA定位到如下行:

替換ComputeLossOTA下的該兩行為如下代碼

                iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, CIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, WIoU=True, scale=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, GIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, SIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, DIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, EIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, CIoU=True, Focal=True)#iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, SIoU=True, Focal=True)#iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, DIoU=True, Focal=True)#iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, EIoU=True, Focal=True)#iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, GIoU=True, Focal=True)if type(iou) is tuple:if len(iou) == 2:lbox += (iou[1].detach() * (1 - iou[0])).mean()iou = iou[0]else:lbox += (iou[0] * iou[1]).mean()iou = iou[-1]else:lbox += (1.0 - iou).mean()  # iou loss

使用時,取消掉不要的注釋即可(如base是CIOU,你想使用SIOU,注釋掉CIOU這行,SIOU那行取消注釋即可)。

四、YOLOv7改進工作

?了解二后,打開YOLOv7項目文件下的utils文件夾下的general.py,搜索def bbox_iou定位到如下行,

替換如下代碼為

class WIoU_Scale:''' monotonous: {None: origin v1True: monotonic FM v2False: non-monotonic FM v3}momentum: The momentum of running mean'''iou_mean = 1.monotonous = False  # (false為v3,true為v2,none為v1)_momentum = 1 - 0.5 ** (1 / 7000)_is_train = Truedef __init__(self, iou):self.iou = iouself._update(self)@classmethoddef _update(cls, self):if cls._is_train: cls.iou_mean = (1 - cls._momentum) * cls.iou_mean + \cls._momentum * self.iou.detach().mean().item()@classmethoddef _scaled_loss(cls, self, gamma=1.9, delta=3):if isinstance(self.monotonous, bool):if self.monotonous:return (self.iou.detach() / self.iou_mean).sqrt()else:beta = self.iou.detach() / self.iou_meanalpha = delta * torch.pow(gamma, beta - delta)return beta / alphareturn 1def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, SIoU=False, EIoU=False, WIoU=False,Focal=False, alpha=1, gamma=0.5, scale=False, eps=1e-7):# Returns the IoU of box1 to box2. box1 is 4, box2 is nx4box2 = box2.T# Get the coordinates of bounding boxesif x1y1x2y2:  # x1, y1, x2, y2 = box1b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]else:  # transform from xywh to xyxyb1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2# Intersection areainter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \(torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)# Union Areaw1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + epsw2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + epsunion = w1 * h1 + w2 * h2 - inter + epsif scale:self = WIoU_Scale(1 - (inter / union))# IoU# iou = inter / union # ori iouiou = torch.pow(inter / (union + eps), alpha)  # alpha iouif CIoU or DIoU or GIoU or EIoU or SIoU or WIoU:cw = b1_x2.maximum(b2_x2) - b1_x1.minimum(b2_x1)  # convex (smallest enclosing box) widthch = b1_y2.maximum(b2_y2) - b1_y1.minimum(b2_y1)  # convex heightif CIoU or DIoU or EIoU or SIoU or WIoU:  # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1c2 = (cw ** 2 + ch ** 2) ** alpha + eps  # convex diagonal squaredrho2 = (((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4) ** alpha  # center dist ** 2if CIoU:  # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47v = (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))if Focal:return iou - (rho2 / c2 + torch.pow(v * alpha_ciou + eps, alpha)), torch.pow(inter / (union + eps),gamma)  # Focal_CIoUelse:return iou - (rho2 / c2 + torch.pow(v * alpha_ciou + eps, alpha))  # CIoUelif EIoU:rho_w2 = ((b2_x2 - b2_x1) - (b1_x2 - b1_x1)) ** 2rho_h2 = ((b2_y2 - b2_y1) - (b1_y2 - b1_y1)) ** 2cw2 = 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_EIouelse:return iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2)  # EIouelif SIoU:# SIoU Loss https://arxiv.org/pdf/2205.12740.pdfs_cw = (b2_x1 + b2_x2 - b1_x1 - b1_x2) * 0.5 + epss_ch = (b2_y1 + b2_y2 - b1_y1 - b1_y2) * 0.5 + epssigma = torch.pow(s_cw ** 2 + s_ch ** 2, 0.5)sin_alpha_1 = torch.abs(s_cw) / sigmasin_alpha_2 = torch.abs(s_ch) / sigmathreshold = pow(2, 0.5) / 2sin_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) ** 2rho_y = (s_ch / ch) ** 2gamma = angle_cost - 2distance_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)if Focal:return iou - torch.pow(0.5 * (distance_cost + shape_cost) + eps, alpha), torch.pow(inter / (union + eps), gamma)  # Focal_SIouelse:return iou - torch.pow(0.5 * (distance_cost + shape_cost) + eps, alpha)  # SIouelif WIoU:if Focal:raise RuntimeError("WIoU do not support Focal.")elif scale:return getattr(WIoU_Scale, '_scaled_loss')(self), (1 - iou) * torch.exp((rho2 / c2)), iou  # WIoU https://arxiv.org/abs/2301.10051else:return iou, torch.exp((rho2 / c2))  # WIoU v1if Focal:return iou - rho2 / c2, torch.pow(inter / (union + eps), gamma)  # Focal_DIoUelse:return iou - rho2 / c2  # DIoUc_area = cw * ch + eps  # convex areaif Focal:return iou - torch.pow((c_area - union) / c_area + eps, alpha), torch.pow(inter / (union + eps),gamma)  # Focal_GIoU https://arxiv.org/pdf/1902.09630.pdfelse:return iou - torch.pow((c_area - union) / c_area + eps, alpha)  # GIoU https://arxiv.org/pdf/1902.09630.pdfif Focal:return iou, torch.pow(inter / (union + eps), gamma)  # Focal_IoUelse:return iou  # IoU

打開utils文件夾下的loss.py,搜索class ComputeLoss:定位到如下行:

?

替換該兩行為如下代碼

                iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, WIoU=True, scale=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, GIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, SIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, DIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, EIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True, Focal=True)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, SIoU=True, Focal=True)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, DIoU=True, Focal=True)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, EIoU=True, Focal=True)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, GIoU=True, Focal=True)if type(iou) is tuple:if len(iou) == 2:lbox += (iou[1].detach() * (1 - iou[0])).mean()iou = iou[0]else:lbox += (iou[0] * iou[1]).mean()iou = iou[-1]else:lbox += (1.0 - iou).mean()  # iou loss

使用時,取消掉不要的注釋即可(如base是CIOU,你想使用SIOU,注釋掉CIOU這行,SIOU那行取消注釋即可)。

五、YOLOv5改進工作

了解二后,打開YOLOv5項目文件下的utils文件夾下的metrics.py,搜索def bbox_iou定位到如下行,

將該函數替換為如下代碼

class WIoU_Scale:''' monotonous: {None: origin v1True: monotonic FM v2False: non-monotonic FM v3}momentum: The momentum of running mean'''iou_mean = 1.monotonous = False  # (false為v3,true為v2,none為v1)_momentum = 1 - 0.5 ** (1 / 7000)_is_train = Truedef __init__(self, iou):self.iou = iouself._update(self)@classmethoddef _update(cls, self):if cls._is_train: cls.iou_mean = (1 - cls._momentum) * cls.iou_mean + \cls._momentum * self.iou.detach().mean().item()@classmethoddef _scaled_loss(cls, self, gamma=1.9, delta=3):if isinstance(self.monotonous, bool):if self.monotonous:return (self.iou.detach() / self.iou_mean).sqrt()else:beta = self.iou.detach() / self.iou_meanalpha = delta * torch.pow(gamma, beta - delta)return beta / alphareturn 1def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, SIoU=False, EIoU=False, WIoU=False,Focal=False, alpha=1, gamma=0.5, scale=False, eps=1e-7):# Returns the IoU of box1 to box2. box1 is 4, box2 is nx4box2 = box2.T# Get the coordinates of bounding boxesif x1y1x2y2:  # x1, y1, x2, y2 = box1b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]else:  # transform from xywh to xyxyb1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2# Intersection areainter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \(torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)# Union Areaw1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + epsw2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + epsunion = w1 * h1 + w2 * h2 - inter + epsif scale:self = WIoU_Scale(1 - (inter / union))# IoU# iou = inter / union # ori iouiou = torch.pow(inter / (union + eps), alpha)  # alpha iouif CIoU or DIoU or GIoU or EIoU or SIoU or WIoU:cw = b1_x2.maximum(b2_x2) - b1_x1.minimum(b2_x1)  # convex (smallest enclosing box) widthch = b1_y2.maximum(b2_y2) - b1_y1.minimum(b2_y1)  # convex heightif CIoU or DIoU or EIoU or SIoU or WIoU:  # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1c2 = (cw ** 2 + ch ** 2) ** alpha + eps  # convex diagonal squaredrho2 = (((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4) ** alpha  # center dist ** 2if CIoU:  # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47v = (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))if Focal:return iou - (rho2 / c2 + torch.pow(v * alpha_ciou + eps, alpha)), torch.pow(inter / (union + eps),gamma)  # Focal_CIoUelse:return iou - (rho2 / c2 + torch.pow(v * alpha_ciou + eps, alpha))  # CIoUelif EIoU:rho_w2 = ((b2_x2 - b2_x1) - (b1_x2 - b1_x1)) ** 2rho_h2 = ((b2_y2 - b2_y1) - (b1_y2 - b1_y1)) ** 2cw2 = 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_EIouelse:return iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2)  # EIouelif SIoU:# SIoU Loss https://arxiv.org/pdf/2205.12740.pdfs_cw = (b2_x1 + b2_x2 - b1_x1 - b1_x2) * 0.5 + epss_ch = (b2_y1 + b2_y2 - b1_y1 - b1_y2) * 0.5 + epssigma = torch.pow(s_cw ** 2 + s_ch ** 2, 0.5)sin_alpha_1 = torch.abs(s_cw) / sigmasin_alpha_2 = torch.abs(s_ch) / sigmathreshold = pow(2, 0.5) / 2sin_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) ** 2rho_y = (s_ch / ch) ** 2gamma = angle_cost - 2distance_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)if Focal:return iou - torch.pow(0.5 * (distance_cost + shape_cost) + eps, alpha), torch.pow(inter / (union + eps), gamma)  # Focal_SIouelse:return iou - torch.pow(0.5 * (distance_cost + shape_cost) + eps, alpha)  # SIouelif WIoU:if Focal:raise RuntimeError("WIoU do not support Focal.")elif scale:return getattr(WIoU_Scale, '_scaled_loss')(self), (1 - iou) * torch.exp((rho2 / c2)), iou  # WIoU https://arxiv.org/abs/2301.10051else:return iou, torch.exp((rho2 / c2))  # WIoU v1if Focal:return iou - rho2 / c2, torch.pow(inter / (union + eps), gamma)  # Focal_DIoUelse:return iou - rho2 / c2  # DIoUc_area = cw * ch + eps  # convex areaif Focal:return iou - torch.pow((c_area - union) / c_area + eps, alpha), torch.pow(inter / (union + eps),gamma)  # Focal_GIoU https://arxiv.org/pdf/1902.09630.pdfelse:return iou - torch.pow((c_area - union) / c_area + eps, alpha)  # GIoU https://arxiv.org/pdf/1902.09630.pdfif Focal:return iou, torch.pow(inter / (union + eps), gamma)  # Focal_IoUelse:return iou  # IoU

打開utils文件夾下的loss.py,搜索ciou

替換該兩行為

                iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, WIoU=True, scale=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, GIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, SIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, DIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, EIoU=True)  # iou(prediction, target)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True, Focal=True)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, SIoU=True, Focal=True)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, DIoU=True, Focal=True)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, EIoU=True, Focal=True)#iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, GIoU=True, Focal=True)if type(iou) is tuple:if len(iou) == 2:lbox += (iou[1].detach() * (1 - iou[0])).mean()iou = iou[0]else:lbox += (iou[0] * iou[1]).mean()iou = iou[-1]else:lbox += (1.0 - iou).mean()  # iou loss

使用時,取消掉不要的注釋即可(如base是CIOU,你想使用SIOU,注釋掉CIOU這行,SIOU那行取消注釋即可)。

六、一些注意的點

采用WIOU進行訓練時,默認采用的是WIOUv3

想要訓練WIOUv1、v2時將該行改為none、true即可。

更多文章產出中,主打簡潔和準確,歡迎關注我,共同探討!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/web/39605.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/39605.shtml
英文地址,請注明出處:http://en.pswp.cn/web/39605.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RabbitMQ入門教程(精細版二帶圖)

目錄 六 RabbitMQ工作模式 6.1Hello World簡單模式 6.1.1 什么是簡單模式 6.1.2 RabbitMQ管理界面操作 6.1.3 生產者代碼 6.1.4 消費者代碼 6.2 Work queues工作隊列模式 6.2.1 什么是工作隊列模式 6.2.2 RabbitMQ管理界面操作 6.2.3 生產者代碼 6.2.4 消費者代碼 …

清理測試數據用truncate還是delete

truncate和delete的區別,我相信大家都清楚。 truncate會清空表的全部數據,且自增主鍵會重置;而delete可以按條件刪除,且自增主鍵不會重置。 我們日常測試過程中經常要刪除掉測試數據,那么應該用truncate刪&#xff0c…

Java中繼承接口和實現接口的區別、接口和抽象類的區別、并理解關鍵字interface、implements

初學者容易把繼承接口和實現接口搞混,專門整理一下,順便簡單介紹一下interface、implements關鍵字。 繼承接口和實現接口的區別、接口的特點 繼承接口是說的只有接口才可以繼承接口,是接口與接口間的。實現接口是說的接口與類之間&#xff…

Eclipse導入工程提示“No projects are found to import”

如果發現導入工程的時候出現"No projects are found to import" 的提示,首先查看項目目錄中是否有隱藏文件.project,還有目錄結構也還要有一個隱藏文件.classpath, 如果沒有的解決辦法。 方法1:可以把其它項目的.proje…

面試題--SpirngCloud

SpringCloud 有哪些核心組件?(必會) ? Eureka: 注冊中心, 服務注冊和發現 ? Ribbon: 負載均衡, 實現服務調用的負載均衡 ? Hystrix: 熔斷器 ? Feign: 遠程調用 ? Zuul: 網關 ? Spring Cloud Config: 配置中心 (1)Eureka 提供服務注冊和發現, 是注冊中心. 有兩個組…

【最新】App Inventor 2 學習平臺和AI2伴侶使用

1、AppInventor2服務器: 官方服務器:http://ai2.appinventor.edu/ 官方備用服務器:http://code.appinventor.mit.edu/ 國內同步更新服務器:https://www.fun123.cn 國內訪問速度很快,很穩定,文檔是中文的…

Android11 系統/framework層禁止三方應用開機自啟動。

背景介紹:客戶給了定制的launcher,要求在設備上啟動他們的launcher,實現過程中出現的問題是 開機引導還沒走完,launcher就會自己彈出來打斷開機引導,按道理來說launcher是在開機引導結束后,由開機引導通過i…

偏微分方程筆記(駐定與非駐定問題)

橢圓方程可以看成拋物方程 t → ∞ t\rightarrow\infty t→∞的情況。 拋物: 雙曲:

什么是deep supervision?

Deep supervision 是深度學習中的一種技術,通常用于改進模型訓練的效果,尤其是在訓練深度神經網絡時。它通過在模型的多個中間層添加輔助監督信號(即額外的損失函數)來實現。這種方法有助于緩解梯度消失問題,加速收斂&…

DolphinDB 蟬聯 Gartner 中國實時數據管理代表廠商

報!DolphinDB 又上榜啦!!! 上月,全球知名信息技術研究公司 Gartner 發布了 Hype Cycle for Data, Analytics and AI in China, 2024 報告,以技術成熟度曲線(Hype Cycle)和優先級矩陣…

【NLP學習筆記】load_dataset加載數據

除了常見的load_dataset(<hf上的dataset名>)這種方式加載HF上的所有數據外&#xff0c;還有其他custom的選項。 加載HF上部分數據 from datasets import load_dataset c4_subset load_dataset("allenai/c4", data_files"en/c4-train.0000*-of-01024.js…

Spring Boot集成多數據源的最佳實踐

Spring Boot集成多數據源的最佳實踐 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 為什么需要多數據源&#xff1f; 在實際的應用開發中&#xff0c;有時候…

【C++ Primer Plus學習記錄】函數和C-風格字符串

將字符串作為參數時意味著傳遞的是地址&#xff0c;但可以使用const來禁止對字符串參數進行修改。 假設要將字符串作為參數傳遞給函數&#xff0c;則表示字符串的方式有三種&#xff1a; &#xff08;1&#xff09;char數組 &#xff08;2&#xff09;用引號括起來的字符串常…

航空數據管控系統-②項目分析與設計:任務1:需求分析-項目場景引入

任務描述 知識點&#xff1a;需求分析 重 點&#xff1a;原型設計工具&#xff0c;用例圖&#xff0c;流程圖繪制工具 難 點&#xff1a;功能點的梳理 內 容&#xff1a;完成本次實訓項目的需求分析 先共同討論處本項目的主要功能模塊&#xff0c;并確定每個模塊的負責…

通過卷防水上限,解鎖手機的新玩法?IP68之間亦有不同

當手機的日常防水已經成了基本功&#xff0c;防水能力的上限便成了新的賽道。 畢竟再謹慎的人&#xff0c;也可能會有手滑的時候。這個時候&#xff0c;一臺有著IP68級防水的手機&#xff0c;就能給你提供一份安心。 【IP68是標準上限&#xff0c;不是手機防水上限】 IP68是…

JAVA學習筆記2

一、加號使用 二、數據類型 bit&#xff1a;計算機中的最小存儲單位 byte(字節):計算機中基本存儲單元&#xff0c;1byte8bit 浮點數符號位指數位尾數位 浮點數默認為double類型

2024亞太杯中文賽B題全保姆教程

B題 洪水災害的數據分析與預測 問題 1. 請分析附件 train.csv 中的數據&#xff0c;分析并可視化上述 20 個指標中&#xff0c;哪 些指標與洪水的發生有著密切的關聯&#xff1f;哪些指標與洪水發生的相關性不大&#xff1f;并 分析可能的原因&#xff0c;然后針對洪水的提前預…

Teamviewer刪除可信任設備

目前基本上主流的遠程連接軟件都有限制&#xff0c;要么收費&#xff1b; Teamviewer可信任設備有限&#xff0c;超出限制就會提示錯誤&#xff0c;需要刪除多余的設備才能登陸賬號&#xff01; 需要登陸這個網站 Teamviewer Management console&#xff0c;才能修改&#xff…

基于 STM32 的智能睡眠呼吸監測系統設計

本設計的硬件構成&#xff1a; STM32F103C8T6單片機最小系統板&#xff08;包含3.3V穩壓電路時鐘晶振電路復位電路&#xff08;上電自復位&#xff0c;手動復位&#xff09;&#xff09;&#xff0c;心率傳感器、氣壓傳感器、液晶顯示、按鍵、蜂鳴器、LED燈、藍牙模塊組合而成…

【C++/STL深度剖析】priority_queue 最全解析(什么是priority_queue? priority_queue的常用接口有哪些?)

目錄 一、前言 二、如何區分【優先級隊列】與【隊列】&#xff1f; 三、priority_queue的介紹 四、priority_queue 的構造 五、priority_queue 的常用接口 &#x1f4a7;push &#x1f4a7;pop &#x1f4a7;size &#x1f4a7;top &#x1f4a7;empty &…