【目标检测算法】IOU、GIOU、DIOU、CIOU与YOLOv5损失函数
1 常见IOU汇总
classification loss | 分类损失 |
---|---|
localization loss, | 定位损失(预测边界框与GT之间的误差) |
confidence loss | 置信度损失(框的目标性 objectness of the box) |
总的损失函数: classification loss + localization loss + confidence loss
YOLOv5使用二元交叉熵损失函数计算类别 概率和目标置信度得分 的损失。
YOLOv5使用 CIOU Loss作为bounding box回归的损失。
多标签分类:
- 大多数分类器假设输出标签是互斥的。 如果输出是互斥的目标类别,则确实如此。 因此,YOLO应用softmax函数将得分转换为总和为1的概率。 而YOLOv3/v4/v5使用多标签分类。 例如,输出标签可以是“行人”和“儿童”,它们不是非排他性的。 (输出的总和可以大于1)
- YOLOv3/v4/v5用多个独立的逻辑(logistic)分类器替换softmax函数,以计算输入属于特定标签的可能性。
- 在计算分类损失进行训练时,YOLOv3/v4/v5对每个标签使用二元交叉熵损失。 这也避免使用softmax函数而降低了计算复杂度。
1.1 IOU(Intersection over Union)
这里有两个问题:
- 如果两个物体不重叠,则IoU值将为零,并且不会反映两个形状彼此之间的距离;且将IoU用作损失,则其梯度将为零并且无法进行优化。
- IoU无法区分两个对象之间不同的对齐方式。 (如下图)
1.2 GIOU(Generalized-IoU)
C是包含A和B的最小的面积。
C
GIOU作为loss函数时,Loss=1-GIOU,当A、B两框不相交时A∪B值不变,最大化GIOU就是就小化C,这样就会促使两个框不断靠近。
1.3 DIOU(Distance-IoU)
根据GIoU损失(第一行)和DIoU损失(第二行)的边界框回归步骤。绿色和黑色分别表示目标框和锚框。蓝色和红色分别表示GIoU损失和DIoU损失的预测框。GIoU损耗一般增大Bounding box的尺寸以与目标框重叠,而DIoU损耗则直接使中心点归一化距离最小化。
在这些情况 (C=A∪B) 下,GIoU损失降级为IoU损失,而我们的DIoU损失仍然是可区分的。绿色和红色分别表示目标框和预测框。
其中B_gt = (xgt, ygt, wgt, hgt) 为ground-truth,B = (x, y, w, h) 为预测框。
bounding box回归的DIoU损失,其中心点之间的归一化距离可以直接最小化。
C是覆盖两个盒子的最小围盒的对角线长度,d = ρ(b, b_GT) 是两个盒子中心点的距离。
IoU损失在非重叠情况下有很大的误差,GIoU损失在水平和垂直情况下有很大的误差,我们的DIoU损失在任何地方回归误差都非常小。
1.4 CIOU(Complete-IoU)
根据GIoU损失(第一行)和CIoU损失(第二行)优化的不同迭代后bounding box的更新。绿色和黑色分别表示目标框和锚框。蓝色和红色分别表示GIoU损失和CIoU损失的预测框。GIoU损失只考虑重叠面积,并倾向于通过增大预测框的尺寸来增加GIoU。
得益于这三种几何因素(中心点距离、重叠面积和高宽比),CIoU损失中归一化中心点距离的最小可以使算法快速收敛,重叠面积和高宽比的一致性有助于更好地匹配两个框。
可以看到,对于非重叠情况,IoU损失有很大的误差。对于水平和垂直情况,GIoU损失有很大的误差。而我们的CIoU损失在任何场景下都有很小的回归误差。
CIoU Loss定义为:
1.5 损失函数总结
IoU系列(IoU, GIoU, DIoU, CIoU)
下图为上面博客的引用! 博主总结的非常好!
2 YOLOv5损失函数
def bbox_iou(box1, box2, xywh=True, GIoU=False, DIoU=False, CIoU=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_y1w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1# 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 Areaunion = w1 * h1 + w2 * h2 - inter + eps# IoUiou = inter / unionif CIoU or DIoU or GIoU:cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1) # convex (smallest enclosing box) widthch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1) # convex heightif CIoU or DIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1c2 = cw ** 2 + ch ** 2 + eps # convex diagonal squaredrho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 # 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.pow(torch.atan(w2 / (h2 + eps)) - torch.atan(w1 / (h1 + eps)), 2)with torch.no_grad():alpha = v / (v - iou + (1 + eps))return iou - (rho2 / c2 + v * alpha) # CIoUreturn iou - rho2 / c2 # DIoUc_area = cw * ch + eps # convex areareturn iou - (c_area - union) / c_area # GIoU https://arxiv.org/pdf/1902.09630.pdfreturn iou # IoU
class ComputeLoss:sort_obj_iou = False# Compute lossesdef __init__(self, model, autobalance=False):device = next(model.parameters()).device # get model deviceh = model.hyp # hyperparameters# Define criteriaBCEcls = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([h['cls_pw']], device=device))BCEobj = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([h['obj_pw']], device=device))# Class label smoothing https://arxiv.org/pdf/1902.04103.pdf eqn 3self.cp, self.cn = smooth_BCE(eps=h.get('label_smoothing', 0.0)) # positive, negative BCE targets# Focal lossg = h['fl_gamma'] # focal loss gammaif g > 0:BCEcls, BCEobj = FocalLoss(BCEcls, g), FocalLoss(BCEobj, g)m = de_parallel(model).model[-1] # Detect() moduleself.balance = {3: [4.0, 1.0, 0.4]}.get(m.nl, [4.0, 1.0, 0.25, 0.06, 0.02]) # P3-P7self.ssi = list(m.stride).index(16) if autobalance else 0 # stride 16 indexself.BCEcls, self.BCEobj, self.gr, self.hyp, self.autobalance = BCEcls, BCEobj, 1.0, h, autobalanceself.na = m.na # number of anchorsself.nc = m.nc # number of classesself.nl = m.nl # number of layersself.anchors = m.anchorsself.device = devicedef __call__(self, p, targets): # predictions, targetslcls = torch.zeros(1, device=self.device) # class losslbox = torch.zeros(1, device=self.device) # box losslobj = torch.zeros(1, device=self.device) # object losstcls, tbox, indices, anchors = self.build_targets(p, targets) # targets# Lossesfor i, pi in enumerate(p): # layer index, layer predictionsb, a, gj, gi = indices[i] # image, anchor, gridy, gridxtobj = torch.zeros(pi.shape[:4], dtype=pi.dtype, device=self.device) # target objn = b.shape[0] # number of targetsif n:# pxy, pwh, _, pcls = pi[b, a, gj, gi].tensor_split((2, 4, 5), dim=1) # faster, requires torch 1.8.0pxy, pwh, _, pcls = pi[b, a, gj, gi].split((2, 2, 1, self.nc), 1) # target-subset of predictions# Regressionpxy = pxy.sigmoid() * 2 - 0.5pwh = (pwh.sigmoid() * 2) ** 2 * anchors[i]pbox = torch.cat((pxy, pwh), 1) # predicted boxiou = bbox_iou(pbox, tbox[i], CIoU=True).squeeze() # iou(prediction, target)lbox += (1.0 - iou).mean() # iou loss# Objectnessiou = iou.detach().clamp(0).type(tobj.dtype)if self.sort_obj_iou:j = iou.argsort()b, a, gj, gi, iou = b[j], a[j], gj[j], gi[j], iou[j]if self.gr < 1:iou = (1.0 - self.gr) + self.gr * ioutobj[b, a, gj, gi] = iou # iou ratio# Classificationif self.nc > 1: # cls loss (only if multiple classes)t = torch.full_like(pcls, self.cn, device=self.device) # targetst[range(n), tcls[i]] = self.cplcls += self.BCEcls(pcls, t) # BCE# Append targets to text file# with open('targets.txt', 'a') as file:# [file.write('%11.5g ' * 4 % tuple(x) + '\n') for x in torch.cat((txy[i], twh[i]), 1)]obji = self.BCEobj(pi[..., 4], tobj)lobj += obji * self.balance[i] # obj lossif self.autobalance:self.balance[i] = self.balance[i] * 0.9999 + 0.0001 / obji.detach().item()if self.autobalance:self.balance = [x / self.balance[self.ssi] for x in self.balance]lbox *= self.hyp['box']lobj *= self.hyp['obj']lcls *= self.hyp['cls']bs = tobj.shape[0] # batch sizereturn (lbox + lobj + lcls) * bs, torch.cat((lbox, lobj, lcls)).detach()
【目标检测算法】IOU、GIOU、DIOU、CIOU与YOLOv5损失函数相关推荐
- IoU GIoU DIoU CIoU分析比较
IoU GIoU DIoU CIoU分析比较 IoU 1. IoU的简介及原理解析 2.IOU的应用有哪些? GIoU 1.Iou的缺陷 2.GIoU的简介及原理解析 3.GIoU的性质 DIoU & ...
- IOU .GIOU.DIOU.CIOU
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 IOU .GIOU.DIOU.CIOU 一.IOU(Intersection over Union) 二.GIOU(Generaliz ...
- 目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 来源:极市平台 目标检测任务的损失函数由Classificitio ...
- 目标检测回归损失函数:SmoothL1/IoU/GIoU/DIoU/CIoU Loss
文章目录 1. Smooth L1 Loss 1.1 假设x为预测框和真实框之间的数值差异,常用的L1和L2 Loss定义为: 1.2 上述的3个损失函数对x的导数分别为: 1.3 实际目标检测框回归 ...
- 目标检测算法常用Loss——DIoU GIoU CIoU
目标检测算法常用Loss 文章目录 目标检测算法常用Loss 1. 差值平方损失 2. IoU Loss 3. GIoU Loss 4. DIoU Loss 5. CIoU Loss 6. 说明和补充 ...
- IoU系列(IoU, GIoU, DIoU, CIoU)
写在前面 一.IoU (Intersection over Union) 1.1 IoU的优点 1.2 作为损失函数会出现的问题(缺点) 二.GIoU (Generalized) 三. D ...
- 基于IOU的损失函数合集, IoU, GIoU, DIoU,CIoU, EIoU
目标检测任务的损失函数一般由 Classificition Loss(分类损失函数)和Bounding Box Regeression Loss(回归损失函数)两部分构成. Bounding ...
- IOU GIOU DIOU CIOU 及代码实现
总体发展过程: IOU IOU(交并比)顾名思义就是两个框的交集除以他们的并集. IOU Loss:IOU Loss = 1 -IOU(比较常用) IOU 的优点:1.能够很好的反应重合的程度 ...
- IOU, GIOU, DIOU, CIOU
IOU IOU是用来衡量两个边界框的重叠程度的.普通的IOU也分为两种,一种是交并比,一种是最小面积与并集的比 计算公式如下: 并集面积 = 面积A + 面积B - 交集面积 交集面积 = 框A与框B ...
- IOU GIOU DIOU CIOU
# -*- coding: utf-8 -*- # @Time : 2022/8/7 10:34 # @Author : hllyzms import mathdef euclidean_distan ...
最新文章
- 【计算理论】图灵机 ( 非确定性图灵机 | 非确定性图灵机指令分析 | 计算过程 | 非确定性指令出现多个分支 | 非确定性图灵机转为计算树 | 计算树 )
- c++ template笔记(2)模板类
- ctf -- 内存取证分析工具volatility的下载与安装+简单的使用
- 5.16GW光伏扶贫,各省费用如何筹措?
- python100以内孪生素数_python用递归筛选法求N以内的孪生质数(孪生素数)
- adapter为null_软件设计精要之——适配器(Adapter)模式
- 如何使用代码给product创建distribution chain
- python--从入门到实践--chapter 10 文件及错误
- 低秩矩阵分解 matlab,低秩分解的matlab代码看不懂,分解的两个矩阵在哪呀??...
- error: No implicit Ordering defined for Any
- 三番四次,Installer 0day 终于获得微补丁
- Linux ALSA驱动框架(一)--ALSA架构简介--声卡的创建
- 服务器系列和酷睿系列,三大系列 从英特尔主流处理器选择服务器(2)
- Boost升压电路调试
- 瀚高数据库迁移工具常见问题
- mbedtls学习--大数运算
- scala 2.13 并行集合par 的引用
- 联想计算机的功能键,联想fn键怎么用 联想fn组合按键功能介绍【图文】
- 【chm】Python提取chm数据
- 双显示器扩展显示时怎么移动鼠标到另一块屏?
热门文章
- CF-926AC USB无线网卡 Ubuntu使用
- kswapd0病毒查杀过程
- 快速做PPT的流程技巧
- 实现联系人列表字母索引
- Airplay背景知识
- [整合版本]酷派手机8022线刷、卡刷总结(win7)
- 基于1000家上市公司某年的财务指标数据,包括:下一年的净资产收益率(ROE),当年净资产收益率(ROEt),债务资本比率(LEV),主营业务增长率(GROWTH),市倍率(PB),公司资产的对数(A
- 美国与印度的职场文化有何差异?Ravi Krishnamurthy博士专访
- C语言机票销售系统[2023-01-04]
- HTML基础7--文档与网站架构