深度学习Loss总结–目标检测:

1-5为基础的loss总结
6-:都是目标检测中,比较实用,比较新的loss

1. nn.L1Loss

目标检测 loss 目标检测loss均值_MSE

loss_fn = torch.nn.L1Loss(reduce=False, size_average=False)

目标检测 loss 目标检测loss均值_损失函数_02


文章的最下方会解释什么是鲁棒,稳定解等

2 nn.smoothL1Loss

目标检测 loss 目标检测loss均值_MSE_03

criterion = nn.SmoothL1Loss()
loss = criterion(sample, target)
print(loss)

3 nn.MSELoss

meanSquareError:就是平方差的loss; 在逻辑回归问题中,常常使用MSE(Mean Squared Error)作为loss函数

目标检测 loss 目标检测loss均值_MSE_04


这里的y_i就表示期望输出,y_i’表示原始的实际输出(就是还没有加softmax)。这里的m表示有m个样本,loss为m个样本的loss均值。MSE在逻辑回归问题中比较好用,那么在分类问题中还是如此么?我们来看看Loss曲线。

目标检测 loss 目标检测loss均值_损失函数_05


这是一个非凸函数,只有当损失函数为凸函数时,梯度下降算法才能保证达到全局最优解。所以MSE在分类问题中,并不是一个好的loss函数。

3 nn.BCELoss

详细理解
二分类与多分类的关系

二分类用的交叉熵,其计算公式较复杂,这里主要是有个概念即可,一般情况下不会用到。

目标检测 loss 目标检测loss均值_目标检测_06


y’是经过激活函数的输出,所以在0-1之间。可见普通的交叉熵对于正样本而言,输出概率越大损失越小。对于负样本而言,输出概率越小则损失越小。此时的损失函数在大量简单样本的迭代过程中比较缓慢且可能无法优化至最优。 离散版本:

目标检测 loss 目标检测loss均值_MSE_07


p是真实值;q为预测值;

这个以后在别的目标检测中,如focs就对其进行了修改;还是很有用的;

import torch.nn.functional as F
import torch
from torch.autograd import Variable
loss_fn = torch.nn.BCELoos(reduce = False, size_average= False)
input = Variable(torch.randn(3,4))
target = Variable(torch.FloatTensor(3,4).random_(2))
loss = loss_fn(F.sigmoid(input),target)
print(loss)

参数:

**

  1. weight (Tensor,可选)– a manual rescaling weight given to the loss of each batch element. If given, has to be a Tensor of size “nbatch”.每批元素损失的手工重标权重。如果给定,则必须是一个大小为“nbatch”的张量。
  2. size_average (bool, 可选)
    弃用(见reduction参数)。默认情况下,设置为True,即对批处理中的每个损失元素进行平均。注意,对于某些损失,每个样本有多个元素。如果字段size_average设置为False,则对每个小批的损失求和。当reduce为False时,该参数被忽略。默认值:True
  3. reduce (bool,可选)
    弃用(见reduction参数)。默认情况下,设置为True,即根据size_average参数的值决定对每个小批的观察值是进行平均或求和。如果reduce为False,则返回每个批处理元素的损失,不进行平均和求和操作,即忽略size_average参数。默认值:True
  4. reduction (string,可选) – 指定要应用于输出的reduction操作:’ none ’ | ‘mean’ | ’
    sum
    '。“none”:表示不进行任何reduction,“mean”:输出的和除以输出中的元素数,即求平均值,“sum”:输出求和。注意:size_average和reduce正在被弃用,与此同时,指定这两个arg中的任何一个都将覆盖reduction参数。默认值:“mean”

4 nn.CrossEntropyLoss

交叉熵损失函数,这个可以支持多分类

目标检测 loss 目标检测loss均值_损失函数_08


目标检测 loss 目标检测loss均值_目标检测 loss_09


CrossEntropyLoss相对MSE而言,曲线整体呈单调性,loss越大,梯度越大。便于梯度下降反向传播,利于优化。所以一般针对分类问题采用交叉熵作为loss函数。

import torch
import torch.nn as nn
import math

criterion = nn.CrossEntropyLoss()
output = torch.randn(1, 5, requires_grad=True)
label = torch.empty(1, dtype=torch.long).random_(5)
loss = criterion(output, label)
print(loss)

5 nn.NLLLoss

用于多分类的负对数似然损失函数(Negative Log Likelihood)

目标检测 loss 目标检测loss均值_目标检测 loss_10


在前面接上一个 LogSoftMax 层就等价于交叉熵损失了。注意这里的 xlabel 和上个交叉熵损失里的不一样,这里是经过 log 运算后的数值。这个损失函数一般也是用在图像识别模型上。

import torch
import torch.nn as nn
import torch.nn.functional as F
torch.manual_seed(2019)
output = torch.randn(1, 3)  # 网络输出
target = torch.ones(1, dtype=torch.long).random_(3)  # 真实标签
criterion = nn.NLLLoss()
loss = criterion(output, target)
print(loss)
print(loss)

目标检测loss

上面讲了很多基础的loss,这些都会出现于各种问题中,loss这玩意还是需要针对不同问题进行解决的;我们主要来看看目标检测的loss总结;目标检测的LOSS很多都是不同的分支使用不同的loss,最后进行求和.主要是两部分:1.分类的分支,2.Iou分支:基于anchor结构(或者长宽分支和中心点分支:基于centerness结构);

6 yolo 损失函数

这个loss主要分为3部分(这里是yolo1)
原文地址: https://arxiv.org/pdf/1506.02640.pdf

① 坐标误差
对不同大小的bbox预测中,相比于大bbox预测偏一点,小box预测偏一点更不能忍受。作者用了一个比较取巧的办法,就是将box的width和height取平方根代替原本的height和width

(主要为了平衡小目标检测预测的偏移)

② IOU误差(很多人不知道C_i代表什么)

目标检测 loss 目标检测loss均值_损失函数_11

其实这里的分别表示 1 和 0

③ 分类误差

这个很容易理解(激活函数的输出)

目标检测 loss 目标检测loss均值_损失函数_12

可以发现,现在的loss已经不能只是简单一个原理组成的了;分了很多部分;

6 Facol loss

论文题目: FCOS: Fully Convolutional One-Stage Object Detection
原文地址: https://arxiv.org/abs/1904.01355
最初出自于retinanet,但也是centerness的loss形式;Focal loss主要是为了解决one-stage目标检测中正负样本比例严重失衡的问题。该损失函数降低了大量简单负样本在训练中所占的权重,也可理解为一种困难样本挖掘。

目标检测 loss 目标检测loss均值_目标检测_13

之前的交叉熵损失y’是经过激活函数的输出,就是预测值;所以在0-1之间。可见普通的交叉熵对于正样本而言,输出概率越大损失越小。对于负样本而言,输出概率越小则损失越小。此时的损失函数在大量简单样本的迭代过程中比较缓慢且可能无法优化至最优。

Focal loss是在交叉熵损失函数基础上进行的修改(注意y只有两个值:0,1):

目标检测 loss 目标检测loss均值_目标检测_14

首先在原有的基础上加了一个因子,其中gamma>0使得减少易分类样本的损失。使得更关注于困难的、错分的样本。

例如gamma为2,对于正类样本而言,预测结果为0.95肯定是简单样本,所以(1-0.95)的gamma次方就会很小,这时损失函数值就变得更小。而预测概率为0.3的样本其损失相对很大。对于负类样本而言同样,预测0.1的结果应当远比预测0.7的样本损失值要小得多。对于预测概率为0.5时,损失只减少了0.25倍,所以更加关注于这种难以区分的样本。这样减少了简单样本的影响,大量预测概率很小的样本叠加起来后的效应才可能比较有效。

目标检测 loss 目标检测loss均值_目标检测_15

此外,加入平衡因子alpha,用来平衡正负样本本身的比例不均:文中alpha取0.25,即正样本要比负样本占比小,这是因为负例易分。 只添加alpha虽然可以平衡正负样本的重要性,但是无法解决简单与困难样本的问题。

gamma调节简单样本权重降低的速率,当gamma为0时即为交叉熵损失函数,当gamma增加时,调整因子的影响也在增加。实验发现gamma为2是最优。

  • 作者认为:作者认为one-stage和two-stage的表现差异主要原因是大量前景背景类别不平衡导致。作者设计了一个简单密集型网络RetinaNet来训练在保证速度的同时达到了精度最优。在双阶段算法中,在候选框阶段,通过得分和nms筛选过滤掉了大量的负样本,然后在分类回归阶段又固定了正负样本比例,或者通过OHEM在线困难挖掘使得前景和背景相对平衡。而one-stage阶段需要产生约100k的候选位置,虽然有类似的采样,但是训练仍然被大量负样本所主导。

Generalized Focal Loss:

论文题目: Generalized Focal Loss: Learning Qualified and Distributed Bounding Boxes for Dense Object Detection
原文地址: https://arxiv.org/pdf/2006.04388.pdf

PCALab南京大学和微软2020发表的Generalized Focal Loss这篇就厉害了,它发现了,在inference和在train的时候, inference的时候乘了iou LOSS,但是train的时候分类的分支和iou或者centerness的分支是相互独立训练的;所以导致了前后不一致;统一了训练和推理过程中的不一致问题;

目标检测 loss 目标检测loss均值_MSE_16


Generalized Focal Loss主要由:Quality Focal Loss (QFL);Distribution Focal Loss (DFL)组成;

Quality Focal Loss (QFL):

之前的fl都是非0即1,这里,可以是0-1之间的概率;这里的y就是IOU LOSS的值;

目标检测 loss 目标检测loss均值_MSE_17


Distribution Focal Loss (DFL)

这玩意还挺复杂的,就是将以前的bounding box的回归损失,使用分类的技巧,将回归问题变成分类问题;因为回归的东西很难收敛;

目标检测 loss 目标检测loss均值_目标检测_18


中心点到groundtruth四条边的距离使用了分段进行求分,每一层都是几段,最后使用softmax进行输出,来获得最终得分;具体的可以看论文,也有git: https://github.com/implus/GFocal

目标检测 loss 目标检测loss均值_MSE_19


在我们的实验结果下,不同数据集的目标检测问题都提高了不错( ^_^ )的点数,可以试一下哟.

7 IOU loss

论文题目: UnitBox: An Advanced Object Detection Network
原文地址: https://arxiv.org/pdf/1608.01471.pdf

IOU Loss是旷视在2016年提出的《UnitBox: An Advanced Object Detection Network》。该论文的主要观点之一是:

使用基于欧式距离的L-n损失函数,其前提是假设4个坐标变量都是独立的,但实际上,这些坐标变量是具有一定的关联性。

评价指标使用了IOU,而回归坐标框又使用4个坐标变量,这两者是不等价的。

具有相同的欧式距离的框,其IOU值却不是唯一的。

所以,提出了IOU loss,直接使用IOU作为损失函数:

目标检测 loss 目标检测loss均值_目标检测 loss_20


目标检测 loss 目标检测loss均值_损失函数_21

GIOU

论文题目: Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression
原文地址: https://arxiv.org/pdf/1911.08287.pdf

该GIOU Loss损失函数是斯坦福于2019年提出的《Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression》。在上面的IOU Loss中,无法对两个不重叠的框进行优化,而且IOU Loss无法反映出两个框到底距离有多远。为了解决这个问题,作者提了GIOU来作为损失函数:

目标检测 loss 目标检测loss均值_目标检测_22


GIOU具有以下的性质:

  • GIOU可以作为一种衡量距离的方式,𝐿𝑜𝑠𝑠𝐺𝐼𝑂𝑈=1−𝐺𝐼𝑂𝑈
  • GIOU具有尺度不变性
  • GIOU是IOU的下限,𝐺𝐼𝑂𝑈(𝐴,𝐵)≤𝐼𝑂𝑈(𝐴,𝐵)。当矩形框A、B类似时,lim𝐴→𝐵𝐺𝐼𝑂𝑈(𝐴,𝐵)=𝐼𝑂𝑈(𝐴,𝐵)
  • 当矩形框A、B重叠时,𝐺𝐼𝑂𝑈(𝐴,𝐵)=𝐼𝑂𝑈(𝐴,𝐵)
  • 当矩形框A、B不相交时,𝐺𝐼𝑂𝑈(𝐴,𝐵)=−1

总的来说,GIOU包含了IOU所有的优点,同时克服了IOU的不足。

DIOU和CIOU

论文题目: Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression
原文地址:https://arxiv.org/pdf/2005.03572.pdf

DIOU和CIOU是天津大学于2019年提出的《Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression》。为了解决GIOU收敛慢和提高回归精度,提出DIOU来加速收敛。同时考虑到框回归的3个几何因素(重叠区域,中心点距离,宽高比),基于DIOU,再次提出CIOU,进一步提高收敛速度和回归精度。另外,可以将DIOU结合NMS组成DIOU-NMS,来对预测框进行后处理。

当出现下图的情况(GT框完全包含预测框)时,IOU与GIOU的值相同,此时GIOU会退化成IOU,无法区分其相对位置关系。同时由于严重依赖于IOU项,GIOU会致使收敛慢。

目标检测 loss 目标检测loss均值_目标检测_23


直接最小化预测框与目标框之间的归一化距离是否可行,以达到更快的收敛速度。

如何使回归在与目标框有重叠甚至包含时更准确、更快

好的目标框回归损失应该考虑三个重要的几何因素:重叠面积,中心点距离,长宽比。基于问题一,作者提出了DIoU Loss,相对于GIoU Loss收敛速度更快,该Loss考虑了重叠面积和中心点距离,但没有考虑到长宽比;针对问题二,作者提出了CIoU Loss,其收敛的精度更高,以上三个因素都考虑到了。

目标检测 loss 目标检测loss均值_目标检测 loss_24


所以,𝐿𝑜𝑠𝑠𝐷𝐼𝑂𝑈具有如下性质:

  1. DIOU依然具有尺度不变性;
  2. DIOU直接最小化两个框的距离,因此收敛会更快;
  3. 对于目标框包裹预测框的这种情况,DIoU
    Loss可以收敛的很快,而GIoU Loss此时退化为IoU Loss收敛速度较慢

CIOU(Complete-IoU)

论文考虑到bbox回归三要素中的长宽比还没被考虑到计算中,因此,进一步在DIoU的基础上提出了CIoU。其惩罚项如下面公式:

目标检测 loss 目标检测loss均值_目标检测 loss_25


目标检测 loss 目标检测loss均值_MSE_26

Oriented bounding box 旋转bouding框的loss

旋转矩形的loss;有很多:<Arbitrary-Oriented Object Detection with Circular Smooth Label> 很多,以后有空整理整理;

PIoU Loss

论文题目: PIoU Loss: Towards Accurate Oriented Object Detection in Complex Environments
原文地址:https://arxiv.org/pdf/2007.09584.pdf

目标检测 loss 目标检测loss均值_目标检测_27


以像素为单位,进行交并集的计算;