目标检测——yolov4损失函数

 

人工智能学习离不开实践的验证,推荐大家可以多在FlyAI-AI竞赛服务平台多参加训练和竞赛,以此来提升自己的能力。FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台。每周免费提供项目开源算法样例,支持算法能力变现以及快速的迭代算法模型。

损失函数

yolo损失分为3个部分类别损失、置信度损失、位置损失

1. 类别损失

只有有目标的地方才会有类别判断,从而才会有类别损失,所以需要解决两个问题:1.有目标的地方;2.类别损失

1.1有目标的地方:object_mask

object_mask根据 y_true(真实值)确定,如何通过前处理编码y_true,通过计算实际框(ground_truth)与anchor框的iou来确定

achor的9个框分为3组,分别负责下小目标(8倍下采样)、中目标(16倍下采样)、大目标(32倍下采样) ,计算每个框与anchor框的iou,iou最大的anchor负责回归这个真实框,

以13*13 (32倍下采样)为例,整幅图被分为13*13个gird,真实框的信息应该放在哪个grid里面呢?答案是真实框的中心落在哪个grid里面,这个grid就负责存储这个框的所有信息,

包括(x, y, h, w),(confidence=1),(class)。object_mask,顾名思义,目标掩码,即有目标的地方为true,所以 object_mask = y_true[l][..., 4:5]

2.1类别损失

类型损失,一般采用交叉熵损失,在目标检测中,采用二元交叉熵损失,对每一个类别计算交叉熵损失,进行求和;

class_loss = object_mask * K.binary_crossentropy(true_class_prob, raw_pred[..., 5:], from_logits=True)
class_loss = K.sum(class_loss) / mf

此处为什么不采用softmax交叉熵损失呢?此处笔者也不清楚,欢迎有答案的同学留言交流。我猜测是因为各个类别之间相互独立,不是非A即B的关系

所以没有采用softmax,将所有类别的概率之和调整为1。

2.位置损失

目标检测的一项重要任务就是确定目标的位置,即(x, y, h, w),所以损失值的计算中包含位置损失

通常计算位置损失有

1. L1 Loss 平均绝对误差(Mean Absolute Error, MAE

梯度值为1或-1,在接近准确值时,会以learning_rate在准确值附近波动,比较难获得准确效果

2. L2 Loss  均方误差损失(Mean Square Error, MSE

在距离准确值较远的地方梯度值较大,训练初期收敛难度大,容易受到噪声的干扰

3. Smooth L1 Loss

克服了以上两种损失函数的缺点,但将x,y,h,w作为独立的变量的看待,割裂了他们之间的相对关系

4. IoU Loss

考虑重合面积,可以较好的反应预测框和真实框的接近程度,但是但二者不相交时,损失值恒为1

5. GIoU Loss

考虑了不重合部分的面积对于损失的影响

6. DIoU Loss

考虑了中心点的偏移,即两个框中心的距离与两个框最远距离的比值

7. CIoU Loss

考虑了长和宽的比值

在yoloV4中,采用了CIou Loss

 

def box_ciou(b1, b2):

    b1_xy = b1[..., :2]
    b1_wh = b1[..., 2:4]
    b1_wh_half = b1_wh / 2.

    b1_mins = b1_xy - b1_wh_half
    b1_maxes = b1_xy + b1_wh_half

    b2_xy = b2[..., :2]
    b2_wh = b2[..., 2:4]
    b2_wh_half = b2_wh / 2.

    b2_mins = b2_xy - b2_wh_half
    b2_maxes = b2_xy + b2_wh_half

    intersect_mins = K.maximum(b1_mins, b2_mins)
    intersect_maxes = K.minimum(b1_maxes, b2_maxes)

    intersect_wh = K.maximum(intersect_maxes-intersect_mins, 0.)
    # 两个框相交部分面积
    intersect_area = intersect_wh[..., 0] * intersect_wh[..., 1]

    b1_area = b1_wh[..., 0] * b1_wh[..., 1]

    b2_area = b2_wh[..., 0] * b2_wh[..., 1]

    union_area = b1_area + b2_area - intersect_area
    # 两个框的iou
    iou = intersect_area / K.maximum(union_area, K.epsilon())

    # 两个框中心点的距离
    center_distance = K.sum(K.square((b1_xy - b2_xy)), axis=-1)

    enclose_mins = K.minimum(b1_mins, b2_mins)
    enclose_maxes = K.maximum(b1_maxes, b2_maxes)
    enclose_wh = K.maximum(enclose_maxes - enclose_mins, 0.0)
     
    # 两个框的最远距离
    enclose_diagonal = K.sum(K.square(enclose_wh), axis=-1)
   
    # 计算DIOU(CIOU的前半部分)
    ciou = iou - 1.0 * (center_distance) / K.maximum(enclose_diagonal, K.epsilon())
   
   # 计算两个框的长宽比的差值的平方
    v = 4*K.square(tf.math.atan2(b1_wh[..., 0], K.maximum(b1_wh[..., 1],K.epsilon())) - tf.math.atan2(b2_wh[..., 0], K.maximum(b2_wh[..., 1],K.epsilon()))) / (math.pi * math.pi)

    alpha = v / K.maximum((1.0 - iou + v), K.epsilon())
    ciou = ciou - alpha * v

    ciou = K.expand_dims(ciou, -1)
    return ciou     
ciou_loss = object_mask * box_loss_scale * (1 - ciou)
ciou_loss = K.sum(ciou_loss) / mf

其中 box_loss_scale 为 (2 - 对应真实框的面积),范围为(1-2),当真实框的面积越大,box_loss_scale越小,意味着对大框的偏差容忍度越大。

解决了以上问题以后,我们还有一个重要问题没有解决,预测框的(x, y, h, w)如何得到?

在yolo中,我们的(x,y)是通过对应grid左上角偏移得到;(h,w)是通过对对应anchor的长宽缩放得到,

box_xy = (K.sigmoid(feats[..., :2]) + grid) / K.cast(grid_shape[..., ::-1], K.dtype(feats))
box_wh = K.exp(feats[..., 2:4]) * anchors_tensor / K.cast(input_shape[..., ::-1], K.dtype(feats))

前半部分(斜体加粗),公式转化如图所示

 

后半部分,box_xy 除以grid_shape 将中心点坐标转化为(0-1),与y_true中中心点的坐标的编码对应,同样转化为(0-1),即中心点相对于输入图像的位置;同样也是作归一化处理;box_hw 除以input_shape 将长宽转化为(0-1),与y_true中长宽的编码对应。

3.置信度损失

置信度损失分为两个部分,有目标的置信度损失,无目标的置信度损失

3.1 有目标的置信度损失

有目标的地方,即object_mask,

置信度损失:采用二元交叉熵损失

K.binary_crossentropy(object_mask, raw_pred[..., 4:5]

总的损失为

object_mask * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True)

3.2 无目标的置信度损失

无目标的地方,即(1-object_mask)

(1 - object_mask) * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True)

存在一个问题,因为一张图中大部分是背景,即大部分是负样本,如果所有的负样本都参与计算,会极大的放大负样本的损失,导致训练结果偏向于负样本,

所以在计算无目标的置信度损失时只会选择部分负样本,如何选择负样本?原则是计算预测值框和真实值框的iou,每个预测值的每个grid中都有三个框(以13*13)为例,每个真实值(一幅图)中有那个框

依次计算iou,会得到(13*13*3*n)个iou,选取最大的iou作为预测值和真实值的iou,得到的维度为(13,13,3,1),设置一个iou阈值,小于此阈值的视为负样本,其实质笔者认为是一种随机取样的方法。

def loop_body(b, ignore_mask):
    true_box = tf.boolean_mask(y_true[l][b, ..., 0:4], object_mask_bool[b, ..., 0])

    iou = box_iou(pred_box[b], true_box)

    best_iou = K.max(iou, axis=-1)

    # 13, 13, 3
    ignore_mask = ignore_mask.write(b, K.cast(best_iou<ignore_thresh, K.dtype(true_box)))

    return b+1, ignore_mask

得到ignore_mask ,所以无目标的置信度损失为:

confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) + \
                  (1 - object_mask) * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) * ignore_mask
confidence_loss = K.sum(confidence_loss) / mf

所以最终的目标检测损失为三者的损失之和:

loss += location_loss + confidence_loss + class_loss

更多精彩内容请访问FlyAI-AI竞赛服务平台;为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台;每周免费提供项目开源算法样例,支持算法能力变现以及快速的迭代算法模型。

挑战者,都在FlyAI!!!

  • 2
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
需要学习Windows系统YOLOv4的同学请前往《Windows版YOLOv4目标检测实战:原理与源码解析》,课程链接 https://edu.csdn.net/course/detail/29865【为什么要学习这门课】 Linux创始人Linus Torvalds有一句名言:Talk is cheap. Show me the code. 冗谈不够,放码过来!  代码阅读是从基础到提高的必由之路。尤其对深度学习,许多框架隐藏了神经网络底层的实现,只能在上层调包使用,对其内部原理很难认识清晰,不利于进一步优化和创新。YOLOv4是最近推出的基于深度学习的端到端实时目标检测方法。YOLOv4的实现darknet是使用C语言开发的轻型开源深度学习框架,依赖少,可移植性好,可以作为很好的代码阅读案例,让我们深入探究其实现原理。【课程内容与收获】 本课程将解析YOLOv4的实现原理和源码,具体内容包括:- YOLOv4目标检测原理- 神经网络及darknet的C语言实现,尤其是反向传播的梯度求解和误差计算- 代码阅读工具及方法- 深度学习计算的利器:BLAS和GEMM- GPU的CUDA编程方法及在darknet的应用- YOLOv4的程序流程- YOLOv4各层及关键技术的源码解析本课程将提供注释后的darknet的源码程序文件。【相关课程】 除本课程《YOLOv4目标检测:原理与源码解析》外,本人推出了有关YOLOv4目标检测的系列课程,包括:《YOLOv4目标检测实战:训练自己的数据集》《YOLOv4-tiny目标检测实战:训练自己的数据集》《YOLOv4目标检测实战:人脸口罩佩戴检测》《YOLOv4目标检测实战:中国交通标志识别》建议先学习一门YOLOv4实战课程,对YOLOv4的使用方法了解以后再学习本课程。【YOLOv4网络模型架构图】 下图由白勇老师绘制  

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值