损失函数源码参考这里yolo_layer.c
本文参考这里这里
yolo_layer.c中的delta指的是对网络层原始输出y'的负梯度, delta=-gradient
总的来说, loss可分为loss_obj, loss_noobj, loss_cls, loss_coor4个部分, 前3个部分都用到了BCE(binary cross entropy)(网上很多复现的代码中, 损失和原文是有出入的, 比如这个的loss_coor for xy是用BCE)

关于BCE:
BCE是二分类的交叉熵损失, 在BCE中
从源码解析YOLOv3的损失函数,
y是标签(y=0或者1), p是预测的概率(p=0~1)
从源码解析YOLOv3的损失函数,
y'是网络层的原始输出

损失L对y'求导得
从源码解析YOLOv3的损失函数

关于坐标映射:
再看看网络预测的坐标t和真实坐标b的映射关系
从源码解析YOLOv3的损失函数

首先对网络的xy预测和objec score以及C位的类别预测做sigmoid变换(logistic**函数)
从源码解析YOLOv3的损失函数

下面分别看这几部分损失
1. loss_obj和loss_noobj
从源码解析YOLOv3的损失函数
首先将所有预测的box都看做是noobject, 所以l.delta[obj_index] = -gradient = y - p = 0 - l.output[obj_index] (这里的l.output[obj_index]就是BCE经过sigmoid**后的值p, 前面已经说过先对这部分施加logistic**函数, 0是标签y)
其次, 如果预测的box和truth的iou大于l.ignore_thresh, 这些box就不参与loss_obj和loss_noobj的计算(实际上有了下面的obj梯度计算, 就是如果box不是最好的,但是iou大于阈值, 就不参与obj和noobj损失的计算), 所以梯度=0
最后, 将匹配最好的box看坐是object, 所以l.delta[obj_index] = 1 - l.output[obj_index]

这里附上object的标签分配规则
        1.如果1个GTbox与某1个先验的bbox的重合度IOU最高(比其他先验的bbox都高), 那么置信度标签为1. 由此可知, 1个GTbox只分配1个先验的bbox, 有多少个objects, 就有多少个标签为1的样本. (并且只有这些样本参与loss_cls和loss_coor的计算)
        2.如果1个GTbox与其他先验的bbox的重合度不是最高,但是大于0.5,就忽略它们(表示不计算loss_obj也不计算loss_noobj)
        3.其他没有分配到GTbox的先验bboxes,不参与计算坐标和类别损失,只参与计算非目标置信度损失(loss_noobj), 标签为0

2.loss_cls
从源码解析YOLOv3的损失函数
第一部分看不懂(if (delta[index]))
后面是对每个class的预测算梯度(假设是80类, 就是有80个BCE, )
class表示真实类别的索引, 在该类别上delta = - gradient = 1 - output[](前面说过了, 这里的output是经过logistic**的),
在其他错误的类别上delta = -gradient = 0 - output[]

3.loss_coor
从源码解析YOLOv3的损失函数
xy坐标损失是在输出经过sigmoid**后计算的(上图的x[index + 0*stride]和x[index + 1*stride]分别表示预测的σ(pred_x), σ(pred_y), 前面说过, 这里是经过logistic**函数的), wh坐标损失是在网络原始输出上计算的
也就是在[tx, ty, tw, th]和[σ(pred_x), σ(pred_y), pred_w, pred_h]之间计算的
所以需要把truth的原始坐标转换一下得到tx, ty, tw, th
坐标损失使用的是MSE
从源码解析YOLOv3的损失函数
而MSE对预测值x求导为
从源码解析YOLOv3的损失函数
这里的scale是一个系数=(2-w*h), 对于越小的目标, 系数越大
从源码解析YOLOv3的损失函数

这里关于xy的损失有个疑问, mse对σ(x或y)的导数如上, 但是不应该进一步对x或y的网络的原始输出再做偏导吗?即(后面是sigmoid的导数)
从源码解析YOLOv3的损失函数

最后给一下最终的loss形式吧:
从源码解析YOLOv3的损失函数
每项分别是loss_coor, loss_obj, loss_noobj, loss_cls. 带*的是ground truth, wi*和hi*是0~1之间的
从官方的模型的cfg文件中可以看出, 没有给任何的损失权重, 那么上面的λ系数都为1?

 

相关文章:

  • 2021-11-03
  • 2021-05-02
  • 2021-06-18
  • 2021-06-11
  • 2021-06-07
  • 2021-12-10
  • 2022-01-03
  • 2021-08-05
猜你喜欢
  • 2021-08-08
  • 2021-12-11
  • 2022-12-23
  • 2021-09-10
  • 2021-07-17
  • 2022-12-23
  • 2021-08-16
相关资源
相似解决方案