Faster-rcnn中的损失函数

L2   loss

RPN网络中对于边框的预测是一个回归问题,通常可以选择平方损失函数,即L2损失。但是当预测值与目标值相差很大时,容易产生梯度爆炸。

                                                                                                 L2  loss = f\left ( x \right )=x^{2}

L1  loss

我们可以采用稍微缓和一点的绝对损失函数,即L1损失。它随着误差线性增长,而不是平方增长。但这个函数在0点处导数不存在,因此可能会影响收敛。

                                                                                                L1  loss  = f\left ( x \right )=\left | x \right |

Smoooh L1 Loss

针对上述两个损失的优缺点,我们使用一个分段函数来作为RPN网络的损失函数。此函数在0点附近使用平方损失函数,这样使得它更加平滑,因此被称为平滑L1损失函数,即:Smoooh L1 Loss,表达式如下:

                                                                                  smooth_{L1}\left ( x \right )=\left\{\begin{matrix} 0.5x^{2} &if\left | x \right | < 1\\ \left | x \right |-0.5& otherwise \end{matrix}\right.

通常情况下,我们还会增加一个\sigma参数来控制平滑的区域,则表达式变为如下形式:

                                                                                  smooth_{L1}\left ( x \right )=\left\{\begin{matrix} 0.5x^{2}\sigma ^{2} &if\left | x \right | <1/\sigma ^{2}\\ \left | x \right |-0.5/\sigma^{2} & otherwise \end{matrix}\right

Faster-rcnn中的损失函数

Faster-rcnn中RPN网络的损失函数为分类损失与回归损失的总和,其表达式如下:

                                                             L\left ( \left \{ p_{i} \right \},\left \{ t_{i} \right \} \right )=\frac{1}{N_{cls}}\sum_{i}L_{cls}\left ( p_{i} ,p_{i}^{*}\right )+\lambda \frac{1}{N_{reg}}\sum_{i}p_{i}^{*}L_{reg}\left ( t_{i},t_{i}^{*} \right )

分类损失使用交叉熵损失函数计算,需要注意的是分类损失计算的是所有样本的平均损失,N_{cls}参数就是样本总数量,隐含在输入参数中,通常为256。

回归损失则使用上述的Smoooh L1 Loss计算,这里我们以此源码中的Smooth L1 loss实现为例进行说明:

def _smooth_l1_loss(bbox_pred, bbox_targets, bbox_inside_weights, bbox_outside_weights, sigma=1.0, dim=[1]):

    #RPN训练时,σ = 3(Faster-rCNN训练时,σ = 1)
    sigma_2 = sigma ** 2  

    #ti - ti*
    box_diff = bbox_pred - bbox_targets  

    #只有前景才计算损失,背景不计算损失
    in_box_diff = bbox_inside_weights * box_diff

    abs_in_box_diff = torch.abs(in_box_diff)
    smoothL1_sign = (abs_in_box_diff < 1. / sigma_2).detach().float()
    in_loss_box = torch.pow(in_box_diff, 2) * (sigma_2 / 2.) * smoothL1_sign \
                  + (abs_in_box_diff - (0.5 / sigma_2)) * (1. - smoothL1_sign)

    #乘以回归损失的权重,没有前景(fg)也没有后景(bg)的为0,其他为1/(bg+fg)=1/256
    out_loss_box = bbox_outside_weights * in_loss_box
    loss_box = out_loss_box
    for i in sorted(dim, reverse=True):
      loss_box = loss_box.sum(i)
    loss_box = loss_box.mean()
    return loss_box
  • t_{i}是一个向量,表示在RPN训练阶段,anchor相对于gt(Ground Truth,即目标所在的真实框)预测的偏移量。对应文章中的:dx(A),dy(A),dw(A),dh(A)
  • t_{i}^{*}是与t_{i}维度相同的向量,表示在RPN训练阶段,anchor相对于gt实际的偏移量。对应文章中的:tx,ty,tw,th

                                                                                     L_{reg}\left ( t_{i} ,t_{i}^{*}\right )=smooth_{L1}\left ( t_{i} -t_{i}^{*} \right )

  • 对于每一个anchor 计算完L_{reg}\left ( t_{i} ,t_{i}^{*}\right )部分后还要乘以p_{i}^{*},有物体时(positive)为1,没有物体(negative)时为0,意味着只有前景才计算损失,背景不计算损失。p_{i}^{*}即为代码中的bbox_inside_weights。
  • 论文中N_{reg}是feature  map的尺寸(600*1000的图片,s16,则约为2400),然后将\lambda取为10。此时分类损失和回归损失的权重基本相同(N_{cls} 为 256,N_{reg}/\lambda约为240)。但是在实际的代码中直接将N_{reg}取为正负样本的总数(256,batch size),然后将\lambda取为1,这样相当于直接使分类损失和回归损失的权重相同。因此不需要额外设置\lambda\lambda \frac{1}{N_{reg}}即为代码中的bbox_outside_weights。没有前景(fg)也没有后景(bg)的为0,其他为1/(bg+fg)=1/256。

 

参考文章:https://blog.csdn.net/Mr_health/article/details/84970776

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的路飞桑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值