找回密码
 会员注册
查看: 32|回复: 0

YOLOv5改进损失函数EIoU、SIoU、WIoU、DIoU、FocuSIoU等多种损失函数

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
67444
发表于 2024-9-10 14:35:08 | 显示全部楼层 |阅读模式
秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转   💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡专栏目录: 《YOLOv5入门+改进涨点》专栏介绍&专栏目录|目前已有40+篇内容,内含各种Head检测头、损失函数Loss、Backbone、Neck、NMS等创新点改进在目标检测领域内,尽管YOLO系列的算法傲视群雄,但在某些方面仍然存在改进的空间。在YOLOv5的损失函数中,默认是使用的CIoU,但是CIoU仍然存在一定的问题。例如CIOU的计算方式相对复杂,需要对边界框的坐标进行更多的处理和计算。本文给大家带来的教程是将原来的CIoU替换为EIoU、SIoU、WIoU、DIoU、FocusIoU。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改,并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。 专栏地址:YOLOv5改进+入门——持续更新各种有效涨点方法——点击即可跳转目录1.✒️CIoU1.1CIoU原理1.2CIoU计算1.3📌CIoU代码实现2.✒️WIOU(Efficient-IoU)2.1WIoU原理2.2代码实现 3.将EIoU、SIoU、WIoU、DIoU、FocusIoU添加到YOLOv5中3.1添加代码3.2回调函数4.完整代码分享5.进阶6.总结1.✒️CIoU1.1CIoU原理论文地址:Distance-IoULoss:FasterandBetterLearningforBoundingBoxRegression——点击即可跳转论⽂考虑到bbox回归三要素中的⻓宽⽐还没被考虑到计算中,为此,进⼀步在DIoU的基础上提出了CIoU,同时考虑两个矩形的长宽比,也就是形状的相似性。所以CIOU在DIOU的基础上添加了长宽比的惩罚项。其中,是权重函数,而用来度量长宽比的相似性。计算公式为:☀️优点更准确的相似性度量:CIOU考虑了边界框的中心点距离和对角线距离,因此可以更准确地衡量两个边界框之间的相似性,尤其是在目标形状和大小不规则的情况下。鲁棒性更强:相比传统的IoU,CIOU对于目标形状和大小的变化更具有鲁棒性,能够更好地适应各种尺寸和形状的目标检测任务。⚡️缺点计算复杂度增加:CIOU引入了额外的中心点距离和对角线距离的计算,因此相比传统的IoU,计算复杂度有所增加,可能会增加一定的计算成本。实现难度较高:CIOU的计算方式相对复杂,需要对边界框的坐标进行更多的处理和计算,因此在实现上可能会相对困难一些,需要更多的技术和经验支持。1.2CIoU计算中心点b、中心点bgt的坐标分别为:(3,4)、(6,6),由此CIoU计算公式如下:1.3📌CIoU代码实现importnumpyasnpimportIoUimportDIoU#box:[左上角x坐标,左上角y坐标,右下角x坐标,右下角y坐标]box1=[0,0,6,8]box2=[3,2,9,10]#CIoUdefCIoU(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用来度量长宽比的相似性v=(4/(np.pi)**2)*(np.arctan(int(box2_w/box2_h))-np.arctan(int(box1_w/box1_h)))#α是权重函数a=v/((1+iou)+v)ciou=diou-a*vreturnciouprint(CIoU(box1,box2))2.✒️WIOU(Efficient-IoU)2.1WIoU原理WIoU的主要原理论文地址: Wise-IoU:BoundingBoxRegressionLosswithDynamicFocusingMechanismWIoU(Wise-IoU)是为了改进边界框回归(BoundingBoxRegression,BBR)损失而提出的一种新的损失函数。WIoU引入了一种动态的非单调聚焦机制(FocusingMechanism,FM),用于解决高质量和低质量样本对模型训练的不利影响。其主要原理如下:动态非单调聚焦机制:WIoU使用非单调聚焦机制,通过评估anchorbox(锚框)的离群度(outlierdegree)来衡量其质量。离群度的计算公式是β=LIoU/LIoU,即将IoU损失标准化。聚焦机制会根据离群度分配梯度增益。对高质量的anchorbox分配较小的梯度增益,对低质量的anchorbox分配较小的梯度增益,从而减少低质量样本对模型训练的负面影响。梯度增益分配策略:WIoU引入了一个“明智的”梯度增益分配策略,使得模型能够关注普通质量的anchorbox。这种策略减少了高质量anchorbox的竞争性,同时也减少了低质量样本产生的有害梯度,从而提高了模型的整体性能。应用场景:WIoU被应用于最先进的实时检测器YOLOv7上,在MS-COCO数据集上的AP75从53.03%提高到54.50%。具体实现在具体实现上,WIoU通过以下步骤来优化BBR损失:生成离群度:计算每个anchorbox的离群度,作为衡量其质量的指标。分配梯度增益:根据离群度动态调整梯度增益。对高质量和低质量的anchorbox赋予较小的梯度增益,而对普通质量的anchorbox赋予较大的梯度增益。损失计算:结合IoU损失和聚焦机制计算最终的WIoU损失。论文中的具体实现细节根据论文内容,WIoU的公式和实现细节如下:IoU损失公式:其中,Wi和Hi分别是重叠区域的宽度和高度,Su是联合区域的面积。离群度计算:梯度增益分配:动态非单调聚焦机制根据离群度分配梯度增益,减少高质量和低质量样本对模型的不利影响。WIoU的主要贡献在于引入了动态的非单调聚焦机制,使得模型能够更加有效地处理普通质量的anchorbox,从而提高了边界框回归的性能。 2.2代码实现 classWIoU_Scale:'''monotonous:{Noneriginv1True:monotonicFMv2False:non-monotonicFMv3}momentum:Themomentumofrunningmean'''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):ifcls._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):ifisinstance(self.monotonous,bool):ifself.monotonous:return(self.iou.detach()/self.iou_mean).sqrt()else:beta=self.iou.detach()/self.iou_meanalpha=delta*torch.pow(gamma,beta-delta)returnbeta/alphareturn13.将EIoU、SIoU、WIoU、DIoU、FocusIoU添加到YOLOv5中3.1添加代码关键步骤一: 在utils/metrics.py中,找到bbox_iou函数,可以把原有的注释掉,换成下面的代码:classWIoU_Scale:'''monotonous:{Noneriginv1True:monotonicFMv2False:non-monotonicFMv3}momentum:Themomentumofrunningmean'''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):ifcls._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):ifisinstance(self.monotonous,bool):ifself.monotonous:return(self.iou.detach()/self.iou_mean).sqrt()else:beta=self.iou.detach()/self.iou_meanalpha=delta*torch.pow(gamma,beta-delta)returnbeta/alphareturn1defbbox_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):#ReturnsIntersectionoverUnion(IoU)ofbox1(1,4)tobox2(n,4)#Getthecoordinatesofboundingboxesifxywh:#transformfromxywhtoxyxy(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)#Intersectionareainter=(b1_x2.minimum(b2_x2)-b1_x1.maximum(b2_x1)).clamp(0)*\(b1_y2.minimum(b2_y2)-b1_y1.maximum(b2_y1)).clamp(0)#UnionAreaunion=w1*h1+w2*h2-inter+epsifscale:self=WIoU_Scale(1-(inter/union))#IoU#iou=inter/union#oriiouiou=torch.pow(inter/(union+eps),alpha)#alphaiouifCIoUorDIoUorGIoUorEIoUorSIoUorWIoU:cw=b1_x2.maximum(b2_x2)-b1_x1.minimum(b2_x1)#convex(smallestenclosingbox)widthch=b1_y2.maximum(b2_y2)-b1_y1.minimum(b2_y1)#convexheightifCIoUorDIoUorEIoUorSIoUorWIoU:#DistanceorCompleteIoUhttps://arxiv.org/abs/1911.08287v1c2=(cw**2+ch**2)**alpha+eps#convexdiagonalsquaredrho2=(((b2_x1+b2_x2-b1_x1-b1_x2)**2+(b2_y1+b2_y2-b1_y1-b1_y2)**2)/4)**alpha#centerdist**2ifCIoU:#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)withtorch.no_grad():alpha_ciou=v/(v-iou+(1+eps))ifFocal:returniou-(rho2/c2+torch.pow(v*alpha_ciou+eps,alpha)),torch.pow(inter/(union+eps),gamma)#Focal_CIoUelse:returniou-(rho2/c2+torch.pow(v*alpha_ciou+eps,alpha))#CIoUelifEIoU: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)ifFocal:returniou-(rho2/c2+rho_w2/cw2+rho_h2/ch2),torch.pow(inter/(union+eps),gamma)#Focal_EIouelse:returniou-(rho2/c2+rho_w2/cw2+rho_h2/ch2)#EIouelifSIoU:#SIoULosshttps://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)ifFocal:returniou-torch.pow(0.5*(distance_cost+shape_cost)+eps,alpha),torch.pow(inter/(union+eps),gamma)#Focal_SIouelse:returniou-torch.pow(0.5*(distance_cost+shape_cost)+eps,alpha)#SIouelifWIoU:ifFocal:raiseRuntimeError("WIoUdonotsupportFocal.")elifscale:returngetattr(WIoU_Scale,'_scaled_loss')(self),(1-iou)*torch.exp((rho2/c2)),iou#WIoUhttps://arxiv.org/abs/2301.10051else:returniou,torch.exp((rho2/c2))#WIoUv1ifFocal:returniou-rho2/c2,torch.pow(inter/(union+eps),gamma)#Focal_DIoUelse:returniou-rho2/c2#DIoUc_area=cw*ch+eps#convexareaifFocal:returniou-torch.pow((c_area-union)/c_area+eps,alpha),torch.pow(inter/(union+eps),gamma)#Focal_GIoUhttps://arxiv.org/pdf/1902.09630.pdfelse:returniou-torch.pow((c_area-union)/c_area+eps,alpha)#GIoUhttps://arxiv.org/pdf/1902.09630.pdfifFocal:returniou,torch.pow(inter/(union+eps),gamma)#Focal_IoUelse:returniou#IoU3.2回调函数关键步骤二:在utils/loss.py中,找到ComputeLoss类中的__call__()函数,把Regressionloss中计算iou的代码,换成下面这句:iou=bbox_iou(pbox,tbox[i],WIoU=True)iftype(iou)istuple:iflen(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()#ioulossiou=iou.squeeze()4.完整代码分享https://pan.baidu.com/s/16E9eva_mm6rHPaTOAyZ5uA?pwd=i3ba提取码:i3ba  5.进阶可以融合其他的注意力机制,修改backbone以及neck,多个模块进行改进。6.总结WIoU(Wise-IoU)通过引入动态非单调聚焦机制来优化边界框回归损失。具体而言,它根据锚框的离群度(outlierdegree)来分配梯度增益,离群度越高的锚框被认为质量越差,因此分配较小的梯度增益,而离群度较低的高质量锚框也分配较小的梯度增益。这种机制使得模型能够专注于普通质量的锚框,减少高质量和低质量样本对模型训练的负面影响,从而提高目标检测中的边界框定位精度和整体性能。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-3 01:31 , Processed in 1.059129 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表