首页 > 技术文章 > 语义分割损失函数

learningcaiji 2020-12-26 19:15 原文

1. 交叉熵损失

语义分割时相当于对每个像素进行分类,所以实际是一个分类任务

对每一个像素的预测值与实际值比较,将损失求平均,是所以最常用的还是交叉熵损失

self.CE = nn.CrossEntropyLoss(weight=weight, ignore_index=ignore_index, reduction=reduction)
loss = self.CE(outputs, target)
 
2. 带权重的交叉熵损失
 交叉熵Loss 可以用在大多数语义分割场景中,但它有一个明显的缺点,那就是对于只分割前景和背景
的时候,当前景像素的数量远远小于背景像素的数量时,即出现样本不平衡的的时候,损失函数中y=背景
的成分就会占据主导,使的模型严重偏向背景,导致效果不好。
为解决样本不平衡问题,
在多样本损失加一个小的权重,在少样本损失加一个大的权重

self.CE_loss = nn.CrossEntropyLoss(reduce=False, ignore_index=ignore_index, weight=alpha)
 
3. FoaclLoss
Focal Loss 用于解决难以样本数量不平衡问题,即更关注难分对样本的损失。一个简单的想法就是将高置信度的
样本的损失降低,低置信度的样本损失提高

 当p = 0.9 的时候,取 gamma=2, 损失降低了1000倍。

self.CE_loss = nn.CrossEntropyLoss(reduce=False, ignore_index=ignore_index)
logpt = self.CE_loss(output, target)
pt = torch.exp(-logpt)
loss = (1-pt)**self.gamma * logpt
loss.mean()
 
4. Dice Loss
用来度量集合相似度的度量函数,通常用于计算两个样本之间的像素。
   

class DiceLoss(nn.Module):
  def __init__(self, smooth=1, ignore_index=255):
    super(DiceLoss, self).__init__()
    self.ignore_index = ignore_index
    self.smooth = smooth

  def forward(self, output, target):
    if self.ignore_index not in range(target.min(), target.max()):
      if (target == self.ignore_index).sum() > 0:
        target[target==self.ignore_index] = target.min()
  # 转化成one-hot形式 target
= make_one_hot(target.unsqueeze(dim=1), classes=output.size()[1])
# 转化为概率 output
= F.softmax(output, dim=1) output_flat = output.contiguous().view(-1) target_flat = target.contiguous().view(-1)
# 重合部分 intersection
= (output_flat * target_flat).sum() loss = 1 - (2 * intersection + self.smooth) / (output_flat.sum() + target_flat.sum() + self.smooth)

 

 

 

 

 

推荐阅读