制作一般网站,wordpress企业宣传电商,装修案例分享的文案,长宁区网站建设设前言
针对目标检测框Box(x1,y1,x2,y2)的回归学习中#xff0c;网络损失函数从最早的IoU到GIoU#xff0c;再到DIoU、CIoU和EIoU#xff0c;现在出现了SIoU。那么他们都是什么呢#xff1f;又由哪些优点#xff1f;
正文
IOU就是交并比#xff0c;预测框和真实框相交区…前言
针对目标检测框Box(x1,y1,x2,y2)的回归学习中网络损失函数从最早的IoU到GIoU再到DIoU、CIoU和EIoU现在出现了SIoU。那么他们都是什么呢又由哪些优点
正文
IOU就是交并比预测框和真实框相交区域面积和合并区域面积的比值计算公式如下 优点1、能够很好的反映重合度2、具有尺度不变形 缺点不相交时值为0无法反映中心距离
GIoU克服了两个框不相交时IoU恒为0损失恒为1没法优化的问题。 GIoU引入了一个最小闭包区的概念即能将预测框和真实框包裹住的最小矩形框其中Ac为最小闭包区u为预测框和真实框的并集那么GIoU第二项的分子就是上图中白色区域白色区域与最小闭包区的比值越高loss越高。 GIoU具有以下特点
GIoU对scale不敏感GIoU是IoU的下界取值为[-1, 1]GIoU除了关注重叠区域不同还关注了非重叠区域能够更好的反应重合度
DIoU paperhttps://arxiv.org/pdf/1911.08287.pdf 提出DIOU和CIOU 如下图所示当出现该场景时计算各种基于IOU的损失函数值 L d i o u L_{diou} Ldiou能够描述检测框与gt框的位置信息。从图中我们可以看到当处于第三幅图时检测框和gt都位于中心IoUGIoUDIoU。但位置出现差异如第一幅图和第二幅图时明显第二幅图的效果要好一些此时GIOU降级成为IOU而DIOU的损失值较大能够较好的描述当前位置信息。 基于此场景作者提出了DIoU。并提出了2个问题第一最小化两个边界框中心点的归一化距离能否加快收敛第二如何在回归时能够更好的描述重叠信息同时使得回归更准确更快速 b b b和 b g t b^{gt} bgt分别代表预测框和gt框的中心点 ρ \rho ρ代表欧氏距离c代表最小闭包区的对角线距离。 DIoU具有以下特点
对scale不敏感与GIoU 类似与目标框不重叠时仍然可以为边界框提供移动方向。DIoU可以直接最小化两个目标框的距离而GIoU 优化的是两个目标框之间的面积。因此比GIoU loss收敛快得多。对于包含两个框在水平方向和垂直方向上这种情况DIoU损失可以使回归非常快而GIoU损失几乎退化为IoU损失
CIoU DIoU解决了上文提到的第一个问题归一化两个中心点的距离从而加速收敛的问题但是还未解决第二个问题即如何在回归时能够更好的描述重叠信息。 paper指出预测的bbox的三个重要的因素分别是重叠面积、中心点距离和纵横比长宽比。 L i o u L_{iou} Liou考虑了重叠区域而GIoU很大程度上依赖了IOU损失DIoU则同时考虑了重叠区域和中心点距离更进一步的边界框的长宽比的一致性也是一个重要的几何因素。因此基于DIoU作者通过施加长宽比的一致性来提出了 L c i o u L_{ciou} Lciou。 EIoU 作者认为CIoU loss有以下两个缺点
如果预测框和gt框的长宽比是相同的那么长宽比的惩罚项恒为0不合理观察CIoU中w, h相对于v的梯度发现这两个梯度是一对相反数也就是说w和h不能同时增大或减小这显然也不够合理的。
针对上述问题作者对于长宽比的惩罚项进行了替换形成了EIoU如下式 其中 C w C_{w} Cw和 C h C_{h} Ch是最小闭包的w和h。
SIoU
paperhttps://arxiv.org/ftp/arxiv/papers/2205/2205.12740.pdf 作者认为以前的IoU损失都没有考虑角度问题但框的角度确实可以影响回归因此提出SIoU loss其中SIoU使用4组cost组成见下
角度损失距离损失形状损失IoU损失
Angle cost Distance cost 可以看出当 α \alpha α → \rightarrow → 0时Distance cost的贡献大大降低。相反 α \alpha α越接近 π \pi π/4Distance cost贡献越大。随着角度的增大问题变得越来越难。因此 γ \gamma γ被赋予时间优先的距离值随着角度的增加。
Shape cost IoU cost 整体 L o s s Loss Loss计算如下 各类IoU损失计算代码如下
import torch
import mathdef iou_loss(pred, target, eps1e-7, reductionmean, loss_typeiou)::param pred: [[x1, y1, x2, y2], [x1, y1, x2, y2], ...]:param target: [[x1, y1, x2, y2], [x1, y1, x2, y2], ...]:param eps::param reduction: mean or sum:param loss_type: iou, giou, diou, ciou, eiou or siou:return:inter_x1 torch.max(pred[:, 0], target[:, 0])inter_y1 torch.max(pred[:, 1], target[:, 1])inter_x2 torch.min(pred[:, 2], target[:, 2])inter_y2 torch.min(pred[:, 3], target[:, 3])outer_x1 torch.min(pred[:, 0], target[:, 0])outer_y1 torch.min(pred[:, 1], target[:, 1])outer_x2 torch.max(pred[:, 2], target[:, 2])outer_y2 torch.max(pred[:, 3], target[:, 3])inter_w (inter_x2 - inter_x1 1.0).clamp(0.)inter_h (inter_y2 - inter_y1 1.0).clamp(0.)inters inter_w * inter_hpred_w pred[:, 2] - pred[:, 0] 1.0pred_h pred[:, 3] - pred[:, 1] 1.0tag_w target[:, 2] - target[:, 0] 1.0tag_h target[:, 3] - target[:, 1] 1.0uni pred_h * pred_w tag_w * tag_h - intersouter_w (outer_x2 - outer_x1).clamp(min0.)outer_h (outer_y2 - outer_y1).clamp(min0.)ious (inters / uni).clamp(mineps)if loss_type iou:loss -ious.log() # -torch.log(ious)elif loss_type giou:enclose outer_w * outer_h epsgious ious - (enclose - uni) / encloseloss 1 - giouselif loss_type diou or loss_type ciou or loss_type eiou:c2 outer_w ** 2 outer_h ** 2rho2 ((pred[:, 0] pred[:, 2] - target[:, 0] - target[:, 2]) ** 2 (pred[:, 1] pred[:, 3] - target[:, 1] - target[:, 3]) ** 2) / 4dious ious - rho2 / c2if loss_type ciou:v torch.pow((torch.atan(tag_w / tag_h) - torch.atan(pred_w / pred_h)), 2) * (4 / (math.pi ** 2))alpha v / (1 - ious v)cious dious - alpha * vcious torch.clamp(cious, min-1.0, max1.0)loss 1 - ciouselif loss_type eiou:rho_w2 (tag_w - pred_w) ** 2rho_h2 (tag_h - pred_h) ** 2cw2 outer_w ** 2 epsch2 outer_h ** 2 epseious dious - rho_w2 / cw2 - rho_h2 / ch2loss 1 - eiouselse:loss 1 - diouselif loss_type siou:s_cw (pred[:, 0] pred[:, 2] - target[:, 0] - target[:, 2]) * 0.5s_ch (pred[:, 1] pred[:, 3] - target[:, 1] - target[:, 3]) * 0.5sigma torch.pow(s_cw ** 2 s_ch ** 2, 0.5) 1.0sin_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 / outer_w) ** 2rho_y (s_ch / outer_h) ** 2gamma angle_cost - 2distance_cost 2 - torch.exp(gamma * rho_x) - torch.exp(gamma * rho_y)omiga_w torch.abs(tag_w - pred_w) / torch.max(tag_w, pred_w)omiga_h torch.abs(tag_h - pred_h) / torch.max(tag_h, pred_h)shape_cost torch.pow(1 - torch.exp(-1 * omiga_w), 4) torch.pow(1 - torch.exp(-1 * omiga_h), 4)sious ious - 0.5 * (distance_cost shape_cost)loss 1 - siouselse:raise NotImplementedErrorif reduction mean:loss torch.mean(loss)elif reduction sum:loss torch.sum(loss)else:raise NotImplementedErrorprint(f{loss_type} loss: {loss})return lossif __name__ __main__:pred_box torch.tensor([[2, 4, 6, 8], [5, 9, 13, 12]])gt_box torch.tensor([[3, 4, 7, 9]])iou_loss(predpred_box, targetgt_box, loss_typeiou)iou_loss(predpred_box, targetgt_box, loss_typegiou)iou_loss(predpred_box, targetgt_box, loss_typediou)iou_loss(predpred_box, targetgt_box, loss_typeciou)iou_loss(predpred_box, targetgt_box, loss_typeeiou)iou_loss(predpred_box, targetgt_box, loss_typesiou)