BEV模型常用LOSS总结


BEV模型常用LOSS总结,以Pytorch用法为例进行介绍

分类

CrossEntropyLoss 交叉熵

torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=- 100, reduce=None, reduction=’mean’, label_smoothing=0.0)

交叉熵主要用于处理分类任务。当类别不均衡的时候,可以通过给不同的类别添加不同的权重进行平衡。

# Example of target with class indices
loss = nn.CrossEntropyLoss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.empty(3, dtype=torch.long).random_(5)
output = loss(input, target)
output.backward()
# Example of target with class probabilities
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5).softmax(dim=1)
output = loss(input, target)
output.backward()

Focal loss

Focal Loss 就是一个解决分类问题中类别不平衡、分类难度差异的一个 loss,它实际上一个基于交叉熵的改进版本。以二分类为例,公式定义如下

Pytorch实现

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, Dataset
import torchvision
import torchvision.transforms as F
from IPython.display import display


class FocalLoss(nn.Module):
    def __init__(self, weight=None, reduction='mean', gamma=0, eps=1e-7):
        super(FocalLoss, self).__init__()
        self.gamma = gamma
        self.eps = eps
        self.ce = torch.nn.CrossEntropyLoss(weight=weight, reduction=reduction)

    def forward(self, input, target):
        logp = self.ce(input, target)
        p = torch.exp(-logp)
        loss = (1 - p) ** self.gamma * logp
        return loss.mean()

KLDivLoss KL散度

torch.nn.KLDivLoss(size_average=None, reduce=None, reduction=’mean’, log_target=False)

KL散度的取值范围是$[0, +\infty)$,当两个分布接近相同的时候KL散度取值为0。KL散度和交叉熵之间相差一个常数,这个常数是信息熵。
不对称性。尽管KL散度从直观上是个度量或距离函数,但它并不是一个真正的度量或者距离,因为它不具有对称性,即$D_{KL}(p||q) \ne D_{KL}(q||p)$

>>> import torch.nn.functional as F
>>> kl_loss = nn.KLDivLoss(reduction="batchmean")
>>> # input should be a distribution in the log space
>>> input = F.log_softmax(torch.randn(3, 5, requires_grad=True), dim=1)
>>> # Sample a batch of distributions. Usually this would come from the dataset
>>> target = F.softmax(torch.rand(3, 5), dim=1)
>>> output = kl_loss(input, target)

>>> kl_loss = nn.KLDivLoss(reduction="batchmean", log_target=True)
>>> log_target = F.log_softmax(torch.rand(3, 5), dim=1)
>>> output = kl_loss(input, log_target)

回归

L1 loss (MAE loss)

torch.nn.L1Loss(size_average=None, reduce=None, reduction=’mean’)

>>> loss = nn.L1Loss()
>>> input = torch.randn(3, 5, requires_grad=True)
>>> target = torch.randn(3, 5)
>>> output = loss(input, target)
>>> output.backward()

L2 loss (MSE loss)

torch.nn.MSELoss(size_average=None, reduce=None, reduction=’mean’)

>>> loss = nn.MSELoss()
>>> input = torch.randn(3, 5, requires_grad=True)
>>> target = torch.randn(3, 5)
>>> output = loss(input, target)
>>> output.backward()

Smooth L1 loss

torch.nn.SmoothL1Loss(size_average=None, reduce=None, reduction=’mean’, beta=1.0)

优点:Smooth L1 loss主要是在预测结果和ground-truth相差大时起到限制梯度的作用。在$x$较小时,对$x$的梯度也会变小,而在$x$很大时,对$x$的梯度的绝对值达到上限 1,也不会太大以至于破坏网络参数。完美地避开了$L_1$和$L_2$损失的缺陷,不会导致梯度爆炸。其函数图像如下

曼哈顿距离

曼哈顿距离实际上就是两个点在标准坐标系上的绝对轴距总和。

GIoU loss (Generalized Intersection over Union)

GIoU loss即泛化的IoU损失。当预测框与真实框之间没有任何重叠时,两个边框的交集(分子)为0,此时IoU损失为0,因此IoU无法算出两者之间的距离(重叠度)。另一方面,由于IoU损失为零,意味着梯度无法有效地反向传播和更新,即出现梯度消失的现象,致使网络无法给出一个优化的方向。

参考

https://pytorch.org/docs/
https://www.zhihu.com/question/58200555/answer/621174180
https://zhuanlan.zhihu.com/p/552132010


文章作者: Jingyi Yu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Jingyi Yu !
  目录