pytorch loss函数整理

2024-03-04 1698阅读

温馨提示:这篇文章已超过384天没有更新,请注意相关的内容是否还可用!

变量名解释

logits:未经过normalize(未经过激活函数处理)的原始预测值,例如一个mlp将特征映射到num_target_class维的输出tensor就是logits。

pytorch loss函数整理
(图片来源网络,侵删)

probs:probabilities的简写,例如logits经过sigmoid函数,就变成了分布在0-1之间的概率值probs。

Binary Cross-Entropy Loss

Binary Cross-Entropy Loss,简称为BCE loss,即二元交叉熵损失。

二元交叉熵损失是一种用于二分类问题的损失函数。它衡量的是模型预测的概率分布与真实标签的概率分布之间的差异。在二分类问题中,每个样本的标签只有两种可能的状态,通常表示为 0(负类)和 1(正类)。

其公式为:

L B C E = − 1 N ∑ i = 1 N [ y i log ⁡ ( p i ) + ( 1 − y i ) log ⁡ ( 1 − p i ) ] L_{BCE}=-\frac{1}{N} \sum_{i=1}^N\left[y_i \log \left(p_i\right)+\left(1-y_i\right) \log \left(1-p_i\right)\right] LBCE​=−N1​i=1∑N​[yi​log(pi​)+(1−yi​)log(1−pi​)]

其中:

  • N N N是数据集的样本数量。
  • y i y_i yi​是第 i {i} i个样本的真实标签,取值为 0 或 1,即第 i {i} i个样本要么属于类别 0(负类),要么属于类别 1(正类)。
  • p i p_i pi​是第 i {i} i个样本属于类别 1(正类)的预测概率
  • log ⁡ \log log是是自然对数。

    当真实标签 y i = 1 y_i=1 yi​=1 时,损失函数的第一部分 y i log ⁡ ( p i ) y_i \log \left(p_i\right) yi​log(pi​) 起作用,第二部分为 0 。此时, 如果预测概率 p i p_i pi​ 接近 1 (接近真实标签 y i = 1 y_i=1 yi​=1), 那么 log ⁡ ( p i ) \log \left(p_i\right) log(pi​) 接近 0 , 损失较小;如果 p i p_i pi​ 接近 0 (即模型预测错误),那么 log ⁡ ( p i ) \log \left(p_i\right) log(pi​) 会变得成绝对值很大的负数,导致取反后loss很大。

    当真实标签 y i = 0 y_i=0 yi​=0 时,损失函数的第二部分 ( 1 − y i ) log ⁡ ( 1 − p i ) \left(1-y_i\right) \log \left(1-p_i\right) (1−yi​)log(1−pi​)起作用,第一部分为 0。此时,预测概率 p i p_i pi​越接近于 0,整体loss越小。

    Pytorch手动实现

    import torch
    import torch.nn.functional as F
    def manual_binary_cross_entropy_with_logits(logits, targets):
        # 使用 Sigmoid 函数将 logits 转换为概率
        probs = torch.sigmoid(logits)
        # 计算二元交叉熵损失
        loss = - torch.mean(targets * torch.log(probs) + (1 - targets) * torch.log(1 - probs))
        return loss
    # logits和targets可以是任意shape的tensor,只要两者shape相同即可
    logits = torch.tensor([0.2, -0.4, 1.2, 0.8])
    targets = torch.tensor([0., 1., 1., 0.])
    assert logits.shape == targets.shape
    # 使用 PyTorch 的 F.binary_cross_entropy_with_logits 函数计算损失
    loss_pytorch = F.binary_cross_entropy_with_logits(logits, targets)
    # 使用手动实现的函数计算损失
    loss_manual = manual_binary_cross_entropy_with_logits(logits, targets)
    print(f'Loss (PyTorch): {loss_pytorch.item()}')
    print(f'Loss (Manual): {loss_manual.item()}')
    

    F.binary_cross_entropy 与 F.binary_cross_entropy_with_logits的区别

    F.binary_cross_entropy的输入是probs

    F.binary_cross_entropy_with_logits的输入是logits

     

     

    Dice Loss

    Dice Loss 来自文章《V-Net: Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation》,它能够有效地处理图像分割任务中正负样本不平衡问题。例如,当一张图片中真实分割区域占比很小,即gt_label里的正样本像素很少。这时候如果用BCE Loss,图片里的每个像素都要去进行二分类,而绝大部分的像素都是负样本,所以会存在正负样本不平衡的问题。

    介绍Dice Loss前,需要先了解Dice系数。

    Dice系数是一种用于评估两个集合的相似性的度量函数,取值范围在0到1之间,取值越大表示越相似。定义如下:

     dice coefficient  = 2 × ∣ X ∩ Y ∣ ∣ X ∣ + ∣ Y ∣ \text { dice coefficient }=\frac{2 \times|X \cap Y|}{|X|+|Y|}  dice coefficient =∣X∣+∣Y∣2×∣X∩Y∣​

    其中 X X X 和 Y Y Y 分别是两个样本集合, X ∩ Y X \cap Y X∩Y 表示它们交集的大小, ∣ X ∣ |X| ∣X∣ 和 ∣ Y ∣ |Y| ∣Y∣分别表示 X X X 和 Y Y Y中的样本个数。由于分子乘上了 2,Dice 系数的值在 0 到 1 之间,值越大表示相似度越高。

    而对于Dice Loss,我们的训练目的是让两个样本越来越相似,所以当 X X X 和 Y Y Y越相似,loss值应该越小,而Dice系数的值在 0 到 1 之间,我们可以直接用1减去Dice系数来作为Dice Loss,这样就能达成两个样本越相似loss值越小的目的:

    L d i c e = 1 −  dice coefficient  L_{dice}= 1 - \text { dice coefficient } Ldice​=1− dice coefficient 

    在图像分割任务中,Dice 系数计算预测分割区域和真实分割区域之间的重叠度。上述公式中的 X X X 和 Y Y Y则分别代表预测分割区域和真实分割区域。

    I = ∑ 1 N p i y i U = ∑ 1 N ( p i + y i ) = ∑ 1 N p i + ∑ 1 N y i \begin{gathered} I=\sum_1^N p_i y_i \\ U=\sum_1^N\left(p_i+y_i\right)=\sum_1^N p_i+\sum_1^N y_i \end{gathered} I=1∑N​pi​yi​U=1∑N​(pi​+yi​)=1∑N​pi​+1∑N​yi​​

    其中:

    • N N N是一张图片里的像素数量。
    • y i y_i yi​是第 i {i} i个像素的真实标签,取值为 0 或 1,即第 i {i} i个像素要么属于类别 0(非分割区域),要么属于类别 1(分割区域)。
    • p i p_i pi​是第 i {i} i个像素属于类别 1(分割区域)的预测概率。
    • I I I是图像的分割区域中,每个像素的预测概率之和。 I I I代表上述公式中的 ∣ X ∩ Y ∣ |X \cap Y| ∣X∩Y∣。
    • U U U是图像每个像素的真实分割概率之和(即真实分割区域的像素总数) + 每个像素的预测分割概率之和。 U U U代表上述公式中的 ∣ X ∣ + ∣ Y ∣ |X|+|Y| ∣X∣+∣Y∣。

      Dice Loss 为 Dice 系数的补数,即 1 减去 Dice 系数。在实际应用中,为了避免除以零的情况,通常会在分子和分母中添加一个小的平滑项 ϵ \epsilon ϵ。

      L dice  = 1 − 2 I + ε U + ε L_{\text {dice }}=1-\frac{2 I+\varepsilon}{U+\varepsilon} Ldice ​=1−U+ε2I+ε​

      在许多实现中,将预测值 logits 和目标 targets 在计算Dice Loss的过程中除以一个缩放因子(如 1000 或 10000),通常是为了数值稳定性。当处理大型图像或大量数据时,像素点的总数可能非常大,这意味着求和操作可能产生非常大的值。这可能导致计算过程中出现数值不稳定性,尤其是在梯度下降和反向传播过程中。通过引入一个缩放因子,可以将这些值缩小到一个更合理的范围内,从而减少数值不稳定性的风险。

      Pytorch手动实现

      import torch
      import torch.nn.functional as F
      def dice_loss(
          logits: torch.Tensor,  # shape为[bs, h, w]
          targets: torch.Tensor, # shape为[bs, h, w]
          scale=1000,
          eps=1e-6,
      ):
          probs = logits.sigmoid()
          # 只对h,w这两维求和,保留bs这一维,这样每个sample都可以得到一个dice loss
          numerator = 2 * (probs / scale * targets).sum(dim=(-2, -1))
          denominator = (probs / scale).sum(dim=(-2, -1)) + (targets / scale).sum(dim=(-2, -1))
          loss = 1 - (numerator + eps) / (denominator + eps)
          return loss
      # 随机生成shape为(4, 480, 640)的预测值 logits 和目标 targets
      # targets要么是 0(非分割区域),要么是 1(分割区域)
      logits = torch.randn(4, 480, 640)
      targets = torch.randint(0, 2, (4, 480, 640))
      loss = dice_loss(logits, targets) # shape为[bs, ]
      print(f"Dics Loss: {loss}")
      

      GIOU Loss

      Focal Loss

      Cross-Entropy Loss

      KLDivLoss

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]