在深入理解yolov3损失函数的yolov3中,loss分为三个部分。

一个是xywh部分引起的误差,也就是bbox引起的loss一个是可靠度引起的误差,也就是obj引起的loss最后是类引起的误差,也就是class引起的loss在代码中分别与lbox、lobj、lcls、yolov3对应使用

其中:

S:表示网格大小,表示1313、2626、5252

b :箱子

: I,j中的box有目标时,其值为1,没有时为0

: I,j的box如果没有目标,则值为1,否则为0

BCE(binarycrossentropy )的具体计算公式如下。

以上是论文中与yolov3对应的损失函数的分析,对应框架是darknet。 另一方面,pytorch版本的yolov3变更比较大,分为三个部分进行具体分析:

1.lbox部分

u版yolov3使用了GIOU。 具体说明请参照GIOU的说明链接

简而言之,其IoU的公式如下。

                                                                                                                                           

而GIoU公式如下:

                                                                                                                                                                                                                                                                                                                                                                                           

其中代表两个框最小闭包区域面积,也就是同时包含了预测框和真实框的最小框的面积。

    yolov3中提供了IoU,GIoU,DIoU和CIoU等计算方式,以GIoU为例:

if GIoU: # Generalized IoU https://arxiv.org/pdf/1902.09630.pdf c_area = cw * ch + 1e-16 # convex area return iou – (c_area – union) / c_area # GIoU

  可以看到代码和GIoU公式是一致的,再来看一下lbox计算部分:

giou = bbox_iou(pbox.t(), tbox[i],x1y1x2y2=False, GIoU=True) lbox += (1.0 – giou).sum() if red == ‘sum’ else (1.0 – giou).mean()

    可以看到box的loss是1-giou的值。

2.lobj部分

      lobj代表置信度,即该bounding box中是否含有物体的概率。在yolov3代码中obj loss可以通过arc来指定,有两种模式:

     如果采用default模式,使用BCEWithLogitsLoss,将obj loss和cls loss分开计算:

BCEobj = nn.BCEWithLogitsLoss(pos_weight=ft([h[‘obj_pw’]]), reduction=red)if ‘default’ in arc: # separate obj and cls lobj += BCEobj(pi[…, 4], tobj) # obj loss # pi[…,4]对应的是该框中含有目标的置信度,和giou计算BCE # 相当于将obj loss和cls loss分开计算

    如果采用BCE模式,使用的也是BCEWithLogitsLoss,计算对象是所有的cls loss:

BCE = nn.BCEWithLogitsLoss(reduction=red)elif ‘BCE’ in arc: # unified BCE (80 classes) t = torch.zeros_like(pi[…, 5:]) # targets if nb: t[b, a, gj, gi, tcls[i]] = 1.0 # 对应正样本class置信度设置为1 lobj += BCE(pi[…, 5:], t)#pi[…,5:]对应的是所有的class

3.lcls部分

      如果是单类的情况,cls loss=0

      如果是多类的情况,也分两个模式:

      如果采用default模式,使用的是BCEWithLogitsLoss计算class loss。

BCEcls = nn.BCEWithLogitsLoss(pos_weight=ft([h[‘cls_pw’]]), reduction=red)# cls loss 只计算多类之间的loss,单类不进行计算if ‘default’ in arc and model.nc > 1: t = torch.zeros_like(ps[:, 5:]) # targets t[range(nb), tcls[i]] = 1.0 # 设置对应class为1 lcls += BCEcls(ps[:, 5:], t) # 使用BCE计算分类loss

     如果采用CE模式,使用的是CrossEntropy同时计算obj loss和cls loss。

CE = nn.CrossEntropyLoss(reduction=red)elif ‘CE’ in arc: # unified CE (1 background + 80 classes) t = torch.zeros_like(pi[…, 0], dtype=torch.long) # targets if nb: t[b, a, gj, gi] = tcls[i] + 1 # 由于cls是从零开始计数的,所以+1 lcls += CE(pi[…, 4:].view(-1, model.nc + 1), t.view(-1)) # 这里将obj loss和cls loss一起计算,使用CrossEntropy Loss

 以上三个部分总结下来就是下图:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

 

 

参考链接:https://www.cnblogs.com/pprp/p/12590801.html