【Loss总结】适用与弱监督语义分割中的各类loss

【Loss总结】适用与弱监督语义分割中的各类loss

交叉熵损失

交叉熵损失函数(CrossEntropy Loss),它是分类问题中经常使用的一种损失函数

在模型的输出层总会接一个softmax函数

交叉熵是信息论中的一个重要概念,主要用于度量两个概率分布间的差异性

构建理论:

  • 信息是用来消除随机不确定性的东西
  • 信息量的大小与信息发生的概率成反比。概率越大,信息量越小。概率越小,信息量越大


在这里插入图片描述

I(x)表示信息量,P(x)表示概率

I(x)为正值,因为log(P(x))为负值

信息熵

信息熵也被称为熵,用来表示所有信息量的期望

期望是试验中每次可能结果的概率乘以其结果的总和。

信息量的熵可表示为:


在这里插入图片描述

在这里插入图片描述

0-1分布问题

一件事情发生的概率为P(x) ,则另一件事情发生的概率为1-P(x)

在这里插入图片描述

相对熵(KL散度)

有两个单独的概率分布P ( x ) 和Q ( x ) ,则我们可以使用KL散度来衡量这两个概率分布之间的差异。

在这里插入图片描述

P ( x ) 来表示样本的真实分布,Q ( x ) 来表示模型所预测的分布

真实分布P ( X ) = [ 1 , 0 , 0 ] , 预测分布Q ( X ) = [ 0.7 , 0.2 , 0.1 ]


在这里插入图片描述

将对应的P,Q值进行代入

KL散度越小,表示P ( x ) 与Q ( x ) 的分布更加接近,可以通过反复训练Q ( x ) 来使Q ( x ) 的分布逼近P ( x ) 。

交叉熵

KL散度公式拆开:

在这里插入图片描述

前者H ( p ( x ) ) )表示信息熵,后者即为交叉熵,KL散度 = 交叉熵 - 信息熵
当KL散度完全一致(loss=1)DKL=1 · log1

交叉熵公式表示为:

在这里插入图片描述

输入数据与标签常常已经确定,那么真实概率分布P ( x ) 也就确定下来了,所以信息熵在这里就是一个常量

在线性回归问题中,常常使用MSE(Mean Squared Error)作为loss函数,而在分类问题中常常使用交叉熵作为loss函数。

在这里插入图片描述

其中一个batch的loss为


在这里插入图片描述

n表示预测的类别数(猫,狗 ,马)n=3,m表示样本数量(batch_size=16)m=16


L1 Loss

也就是L1 Loss了,它有几个别称:

  • L1 范数损失
  • 最小绝对值偏差(LAD)
  • 最小绝对值误差(LAE)

MAE也是指L1 Loss损失函数

目标值 yi与模型输出f(xi)(估计值)做绝对值得到的误差。

在这里插入图片描述

应用场景:

  1. 回归任务
  2. 简单的模型
  3. 由于神经网络通常是解决复杂问题,所以很少使用。

公式: torch.nn.L1Loss(size_average=None, reduce=None, reduction='mean')

创建一个绝对值误差损失函数

在这里插入图片描述

用法:reduction='mean','None','sum'

mean 对应(x, y)的均值,None 对应(x, y)的单独值,sum对应(x, y)的总值

L2Loss

也就是L2 Loss了,它有几个别称:

  • L2 范数损失
  • 最小均方值偏差(LSD)
  • 最小均方值误差(LSE)

最常看到的MSE也是指L2 Loss损失函数,PyTorch中也将其命名为torch.nn.MSELoss

目标值 yi与模型输出f(xi)(估计值)做差然后平方得到的误差

在这里插入图片描述

应用场景:

  1. 回归任务

  2. 数值特征不大

  3. 问题维度不高

对离群点比较敏感,如果feature是unbounded的话,需要好好调整学习率,防止出现梯度爆炸的情况。l2正则会让特征的权重不过大,使得特征的权重比较平均。

SmoothL1Loss

简单来说就是平滑版的L1 Loss

SoothL1Loss的函数如下:

在这里插入图片描述

仔细观察可以看到,当预测值和ground truth差别较小的时候(绝对值差小于1),其实使用的是L2 Loss;而当差别大的时候,是L1 Loss的平移

SooothL1Loss其实是L2Loss和L1Loss的结合,它同时拥有L2 Loss和L1 Loss的部分优点。

优点:

  1. 当预测值和ground truth差别较小的时候(绝对值差小于1),梯度不至于太大。(损失函数相较L1 Loss比较圆滑)
  2. 当差别大的时候,梯度值足够小(较稳定,不容易梯度爆炸)。

应用:

  1. 回归
  2. 当特征中有较大的数值
  3. 适合大多数问题

Dice loss

dice loss 来自 dice coefficient,是一种用于评估两个样本的相似性的度量函数,取值范围在0到1之间,取值越大表示越相似

在这里插入图片描述

dice loss可以写为:

在这里插入图片描述

梯度分析

从dice loss的定义可以看出,dice loss 是一种区域相关的loss。意味着某像素点的loss以及梯度值不仅和该点的label以及预测值相关,和其他点的label以及预测值也相关,这点和ce (交叉熵cross entropy) loss 不同

从loss曲线和求导曲线对单点输出方式分析。然后对于多点输出的情况,利用模拟预测输出来分析其梯度

Dice Loss可以缓解样本中前景背景(面积)不平衡带来的消极影响,前景背景不平衡也就是说图像中大部分区域是不包含目标的,只有一小部分区域包含目标

语义分割代码

class DiceLoss(nn.Module):
    def __init__(self, n_classes):
        super(DiceLoss, self).__init__()
        self.n_classes = n_classes  # 物体的输入数量

    # 没有问题,但是需要的是进行一个one_hot_的解码,来满足6个特征图
    def _one_hot_encoder(self, input_tensor):
        tensor_list = []
        for i in range(self.n_classes):
            temp_prob = input_tensor == i  # * torch.ones_like(input_tensor)
            tensor_list.append(temp_prob.unsqueeze(1))
        output_tensor = torch.cat(tensor_list, dim=1)
        return output_tensor.float()

    def _dice_loss(self, score, target):
        target = target.float()
        smooth = 1e-5
        intersect = torch.sum(score * target)
        y_sum = torch.sum(target * target)
        z_sum = torch.sum(score * score)
        loss = (2 * intersect + smooth) / (z_sum + y_sum + smooth)
        loss = 1 - loss
        return loss

    def forward(self, inputs, target, weight=None, softmax=False):
        if softmax:
            inputs = torch.softmax(inputs, dim=1)  # 12, 6, 256, 256
        target = self._one_hot_encoder(target)  # [12, 6, 256, 256]
        if weight is None:
            weight = [1] * self.n_classes
        assert inputs.size() == target.size(), 'predict {} & target {} shape do not match'.format(inputs.size(),
                                                                                                  target.size())
        class_wise_dice = []
        loss = 0.0
        for i in range(0, self.n_classes):
            dice = self._dice_loss(inputs[:, i], target[:, i])
            class_wise_dice.append(1.0 - dice.item())
            loss += dice * weight[i]
        return loss / self.n_classes
  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像级Transformer监督语义分割是一种利用Transformer模型进行图像分割的方法,它可以在没有像素级标注的情况下进行语义分割。下面是一个简单的步骤: 1.首先,使用一个预训练的卷积神经网络(CNN)提取图像特征。 2.然后,将这些特征输入到Transformer模型,以学习像素之间的关系。 3.在训练过程,使用图像级别的标签来指导模型进行学习,而不是使用像素级别的标注。 4.最后,使用训练好的模型对新的图像进行分割。 下面是一个示例代码: ```python import torch import torch.nn as nn import torch.nn.functional as F from transformers import TransformerEncoder, TransformerEncoderLayer class ImageTransformer(nn.Module): def __init__(self, input_dim, hidden_dim, num_layers, num_heads): super(ImageTransformer, self).__init__() self.input_dim = input_dim self.hidden_dim = hidden_dim self.num_layers = num_layers self.num_heads = num_heads self.encoder_layer = TransformerEncoderLayer(d_model=input_dim, nhead=num_heads) self.transformer_encoder = TransformerEncoder(encoder_layer=self.encoder_layer, num_layers=num_layers) self.fc = nn.Linear(input_dim, 1) def forward(self, x): x = x.permute(0, 2, 3, 1) # 将通道维度放到最后 b, h, w, c = x.shape x = x.reshape(b*h*w, c) # 将空间维度展平 x = self.transformer_encoder(x) x = self.fc(x) x = x.reshape(b, h, w) return x # 定义模型 model = ImageTransformer(input_dim=512, hidden_dim=256, num_layers=4, num_heads=8) # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 训练模型 for epoch in range(num_epochs): for images, labels in train_loader: optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() # 对新图像进行分割 with torch.no_grad(): outputs = model(new_image) predicted_labels = torch.argmax(outputs, dim=1) ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值