浙江臺(tái)州做網(wǎng)站的公司有哪些網(wǎng)絡(luò)推廣網(wǎng)絡(luò)營(yíng)銷外包
秋招面試專欄推薦?:深度學(xué)習(xí)算法工程師面試問(wèn)題總結(jié)【百面算法工程師】——點(diǎn)擊即可跳轉(zhuǎn)???
💡💡💡本專欄所有程序均經(jīng)過(guò)測(cè)試,可成功執(zhí)行💡💡💡
專欄目錄:?《YOLOv5入門 + 改進(jìn)漲點(diǎn)》專欄介紹 & 專欄目錄 |目前已有40+篇內(nèi)容,內(nèi)含各種Head檢測(cè)頭、損失函數(shù)Loss、Backbone、Neck、NMS等創(chuàng)新點(diǎn)改進(jìn)
在目標(biāo)檢測(cè)領(lǐng)域內(nèi),盡管YOLO系列的算法傲視群雄,但在某些方面仍然存在改進(jìn)的空間。在YOLOv5的損失函數(shù)中,默認(rèn)是使用的CIoU,但是CIoU仍然存在一定的問(wèn)題。例如CIOU的計(jì)算方式相對(duì)復(fù)雜,需要對(duì)邊界框的坐標(biāo)進(jìn)行更多的處理和計(jì)算。本文給大家?guī)?lái)的教程是將原來(lái)的CIoU替換為EIoU、SIoU、WIoU、DIoU、FocusIoU。文章在介紹主要的原理后,將手把手教學(xué)如何進(jìn)行模塊的代碼添加和修改,并將修改后的完整代碼放在文章的最后,方便大家一鍵運(yùn)行,小白也可輕松上手實(shí)踐。以幫助您更好地學(xué)習(xí)深度學(xué)習(xí)目標(biāo)檢測(cè)YOLO系列的挑戰(zhàn)。
?專欄地址:YOLOv5改進(jìn)+入門——持續(xù)更新各種有效漲點(diǎn)方法——點(diǎn)擊即可跳轉(zhuǎn)
目錄
1. ??CIoU
1.1 CIoU原理
1.2 CIoU計(jì)算
1.3 📌CIoU代碼實(shí)現(xiàn)
2. ??WIOU(Efficient-IoU)
2.1 WIoU原理
2.2 代碼實(shí)現(xiàn)?
3. 將EIoU、SIoU、WIoU、DIoU、FocusIoU添加到Y(jié)OLOv5中
3.1 添加代碼
3.2 回調(diào)函數(shù)
4.完整代碼分享
5. 進(jìn)階
6. 總結(jié)
1. ??CIoU
1.1 CIoU原理
論文地址:Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression——點(diǎn)擊即可跳轉(zhuǎn)
論?考慮到bbox回歸三要素中的?寬?還沒(méi)被考慮到計(jì)算中,為此,進(jìn)?步在DIoU的基礎(chǔ)上提出了CIoU,同時(shí)考慮兩個(gè)矩形的長(zhǎng)寬比,也就是形狀的相似性。所以CIOU在DIOU的基礎(chǔ)上添加了長(zhǎng)寬比的懲罰項(xiàng)。
其中, 是權(quán)重函數(shù), 而用來(lái)度量長(zhǎng)寬比的相似性。計(jì)算公式為:
??優(yōu)點(diǎn)
更準(zhǔn)確的相似性度量:CIOU考慮了邊界框的中心點(diǎn)距離和對(duì)角線距離,因此可以更準(zhǔn)確地衡量?jī)蓚€(gè)邊界框之間的相似性,尤其是在目標(biāo)形狀和大小不規(guī)則的情況下。 魯棒性更強(qiáng):相比傳統(tǒng)的IoU,CIOU對(duì)于目標(biāo)形狀和大小的變化更具有魯棒性,能夠更好地適應(yīng)各種尺寸和形狀的目標(biāo)檢測(cè)任務(wù)。
??缺點(diǎn)
計(jì)算復(fù)雜度增加:CIOU引入了額外的中心點(diǎn)距離和對(duì)角線距離的計(jì)算,因此相比傳統(tǒng)的IoU,計(jì)算復(fù)雜度有所增加,可能會(huì)增加一定的計(jì)算成本。 實(shí)現(xiàn)難度較高:CIOU的計(jì)算方式相對(duì)復(fù)雜,需要對(duì)邊界框的坐標(biāo)進(jìn)行更多的處理和計(jì)算,因此在實(shí)現(xiàn)上可能會(huì)相對(duì)困難一些,需要更多的技術(shù)和經(jīng)驗(yàn)支持。
1.2 CIoU計(jì)算
中心點(diǎn) b、中心點(diǎn) bgt的坐標(biāo)分別為:(3,4)、(6,6),由此CIoU計(jì)算公式如下:
1.3 📌CIoU代碼實(shí)現(xiàn)
import numpy as np
import IoU
import DIoU
# box : [左上角x坐標(biāo),左上角y坐標(biāo),右下角x坐標(biāo),右下角y坐標(biāo)]
box1 = [0, 0, 6, 8]
box2 = [3, 2, 9, 10]
# CIoU
def CIoU(box1, box2):x1, y1, x2, y2 = box1x3, y3, x4, y4 = box2# box1的寬:box1_w,box1的高:box1_h,box1_w = x2 - x1box1_h = y2 - y1# box2的寬:box2_w,box2的高:box2_h,box2_w = x4 - x3box2_h = y4 - y3iou = IoU(box1, box2)diou = DIoU(box1, box2)# v用來(lái)度量長(zhǎng)寬比的相似性v = (4 / (np.pi) ** 2) * (np.arctan(int(box2_w / box2_h)) - np.arctan(int(box1_w / box1_h)))# α是權(quán)重函數(shù)a = v / ((1 + iou) + v)ciou = diou - a * vreturn ciouprint(CIoU(box1, box2))
2. ??WIOU(Efficient-IoU)
2.1 WIoU原理
WIoU的主要原理
論文地址:?Wise-IoU: Bounding Box Regression Loss with Dynamic Focusing Mechanism
WIoU(Wise-IoU)是為了改進(jìn)邊界框回歸(Bounding Box Regression, BBR)損失而提出的一種新的損失函數(shù)。WIoU引入了一種動(dòng)態(tài)的非單調(diào)聚焦機(jī)制(Focusing Mechanism, FM),用于解決高質(zhì)量和低質(zhì)量樣本對(duì)模型訓(xùn)練的不利影響。其主要原理如下:
-
動(dòng)態(tài)非單調(diào)聚焦機(jī)制:
-
WIoU使用非單調(diào)聚焦機(jī)制,通過(guò)評(píng)估anchor box(錨框)的離群度(outlier degree)來(lái)衡量其質(zhì)量。
-
離群度的計(jì)算公式是β = LIoU / LIoU,即將IoU損失標(biāo)準(zhǔn)化。
-
聚焦機(jī)制會(huì)根據(jù)離群度分配梯度增益。對(duì)高質(zhì)量的anchor box分配較小的梯度增益,對(duì)低質(zhì)量的anchor box分配較小的梯度增益,從而減少低質(zhì)量樣本對(duì)模型訓(xùn)練的負(fù)面影響。
-
-
梯度增益分配策略:
-
WIoU引入了一個(gè)“明智的”梯度增益分配策略,使得模型能夠關(guān)注普通質(zhì)量的anchor box。
-
這種策略減少了高質(zhì)量anchor box的競(jìng)爭(zhēng)性,同時(shí)也減少了低質(zhì)量樣本產(chǎn)生的有害梯度,從而提高了模型的整體性能。
-
-
應(yīng)用場(chǎng)景:
-
WIoU被應(yīng)用于最先進(jìn)的實(shí)時(shí)檢測(cè)器YOLOv7上,在MS-COCO數(shù)據(jù)集上的AP75從53.03%提高到54.50%。
-
具體實(shí)現(xiàn)
在具體實(shí)現(xiàn)上,WIoU通過(guò)以下步驟來(lái)優(yōu)化BBR損失:
-
生成離群度:計(jì)算每個(gè)anchor box的離群度,作為衡量其質(zhì)量的指標(biāo)。
-
分配梯度增益:根據(jù)離群度動(dòng)態(tài)調(diào)整梯度增益。對(duì)高質(zhì)量和低質(zhì)量的anchor box賦予較小的梯度增益,而對(duì)普通質(zhì)量的anchor box賦予較大的梯度增益。
-
損失計(jì)算:結(jié)合IoU損失和聚焦機(jī)制計(jì)算最終的WIoU損失。
論文中的具體實(shí)現(xiàn)細(xì)節(jié)
根據(jù)論文內(nèi)容,WIoU的公式和實(shí)現(xiàn)細(xì)節(jié)如下:
-
IoU損失公式:
其中,Wi 和 Hi 分別是重疊區(qū)域的寬度和高度, Su 是聯(lián)合區(qū)域的面積。
-
離群度計(jì)算:
-
梯度增益分配: 動(dòng)態(tài)非單調(diào)聚焦機(jī)制根據(jù)離群度分配梯度增益,減少高質(zhì)量和低質(zhì)量樣本對(duì)模型的不利影響。
WIoU的主要貢獻(xiàn)在于引入了動(dòng)態(tài)的非單調(diào)聚焦機(jī)制,使得模型能夠更加有效地處理普通質(zhì)量的anchor box,從而提高了邊界框回歸的性能。?
2.2 代碼實(shí)現(xiàn)?
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_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 1
3. 將EIoU、SIoU、WIoU、DIoU、FocusIoU添加到Y(jié)OLOv5中
3.1 添加代碼
關(guān)鍵步驟一:?在
utils/metrics.py
中,找到bbox_iou
函數(shù),可以把原有的注釋掉,換成下面的代碼:
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_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, xywh=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 Intersection over Union (IoU) of box1(1,4) to box2(n,4)# Get the coordinates of bounding boxesif 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 / 2b1_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 = box1b1_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 areainter = (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 Areaunion = 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
3.2 回調(diào)函數(shù)
關(guān)鍵步驟二:在
utils/loss.py
中,找到ComputeLoss
類中的__call__()
函數(shù),把Regression loss中計(jì)算iou的代碼,換成下面這句:
iou = bbox_iou(pbox, tbox[i], WIoU=True)if type(iou) is tuple:if len(iou) == 2:lbox += (iou[1].detach().squeeze() * (1 - iou[0].squeeze())).mean()iou = iou[0].squeeze()else:lbox += (iou[0] * iou[1]).mean()iou = iou[2].squeeze()else:lbox += (1.0 - iou.squeeze()).mean() # iou lossiou = iou.squeeze()
4.完整代碼分享
https://pan.baidu.com/s/16E9eva_mm6rHPaTOAyZ5uA?pwd=i3ba
提取碼:i3ba??
5. 進(jìn)階
可以融合其他的注意力機(jī)制,修改backbone以及neck,多個(gè)模塊進(jìn)行改進(jìn)。
6. 總結(jié)
WIoU(Wise-IoU)通過(guò)引入動(dòng)態(tài)非單調(diào)聚焦機(jī)制來(lái)優(yōu)化邊界框回歸損失。具體而言,它根據(jù)錨框的離群度(outlier degree)來(lái)分配梯度增益,離群度越高的錨框被認(rèn)為質(zhì)量越差,因此分配較小的梯度增益,而離群度較低的高質(zhì)量錨框也分配較小的梯度增益。這種機(jī)制使得模型能夠?qū)W⒂谄胀ㄙ|(zhì)量的錨框,減少高質(zhì)量和低質(zhì)量樣本對(duì)模型訓(xùn)練的負(fù)面影響,從而提高目標(biāo)檢測(cè)中的邊界框定位精度和整體性能。