深度理解yolov3损失函数

深度理解yolov3损失函数

在yolov3中,loss分为三个部分:

  • 一个是xywh部分带来的误差,也就是bbox带来的loss
  • 一个是置信度带来的误差,也就是obj带来的loss
  • 最后一个是类别带来的误差,也就是class带来的loss

在代码中分别对应lbox,lobj,lcls,yolov3中使用的loss公式如下:

\begin{aligned} lbox &= \lambda_{coord}\sum_{i=0}^{S^2}\sum_{j=0}^{B}1_{i,j}^{obj}(2-w_i\times h_i)[(x_i-\hat{x_i})^2+(y_i-\hat{y_i})^2+(w_i-\hat{w_i})^2+(h_i-\hat{h_i})^2] \\ lcls &= \lambda_{class}\sum_{i=0}^{S^2}\sum_{j=0}^{B}1_{i,j}^{obj}\sum_{c\in classes}p_i(c)log(\hat{p_i}(c)) \\ lobj &= \lambda_{noobj}\sum_{i=0}^{S^2}\sum_{j=0}^{B}1_{i,j}^{noobj}(c_i-\hat{c_i})^2+\lambda_{obj}\sum_{i=0}^{S^2}\sum_{j=0}^{B}1_{i,j}^{obj}(c_i-\hat{c_i})^2 \\ loss &= lbox + lobj + lcls \end{aligned}

           

其中:

S:代表grid size,S^2代表 13×13,26×26,52×52

B:box

    1_{i,j}^{obj}:如果在i,j处的box有目标,其值为1,否则为0

     1_{i,j}^{noobj}:如果在i,j处的box没有目标,其值为1,否则为0 

     BCE(binary cross entropy)具体计算公式如下:

                                             BCE(\hat{c_i},c_i)=-\hat{c_i}\times log(c_i)-(1-\hat{c_i})\times log(1-c_i)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

以上是论文中yolov3对应的损失函数分析,对应框架为darknet。而pytorch版本的yolov3改动比较大,分成三个部分进行具体分析:

1.lbox部分                                                                                                                                                                                                                                                                                                                                                                                                                   

  在U版yolov3中,使用的是GIOU,具体讲解见GIOU讲解链接                                                                                                                                                                                                                                                                                                                               

  简单来说其IoU公式如下:

                                                      IoU=\frac{|A\cap B|}{|A\cup B|}                                                                                                                                                                                                                                                                                                                                                   

而GIoU公式如下:

                                                      GIoU=IoU-\frac{|A_c-U|}{|A_c|}                                                                                                                                                                                                                                                                                                                                     

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

    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

 

  • 11
    点赞
  • 93
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值