美文网首页
loss函数之L1Loss,MSELoss,SmoothL1Lo

loss函数之L1Loss,MSELoss,SmoothL1Lo

作者: ltochange | 来源:发表于2021-06-15 10:22 被阅读0次

L1Loss

平均绝对误差(MAE),用于回归模型

对于包含N个样本的batch数据 D(x, y)x为神经网络的输出,y是真实的得分,xy同维度。

n个样本的损失值l_{n}计算如下:

l_{n}=\left|x_{n}-y_{n}\right|

其中,y_{n}代表第n样本的真实得分,可能对应一个值,也可能多个值,代表样本不同方面的得分,所以l_{n}可能是一个值,也可能是一个向量。

class L1Loss(_Loss):
    def __init__(self, size_average=None, reduce=None, reduction='mean'):
        super(L1Loss, self).__init__(size_average, reduce, reduction)
    def forward(self, input, target):
        return F.l1_loss(input, target, reduction=self.reduction)

pytorch中通过torch.nn.L1Loss类实现,也可以直接调用F.l1_loss 函数,代码中的size_averagereduce已经弃用。reduction有三种取值mean, sum, none,对应不同的返回\ell(x, y)。 默认为mean,对L中所有元素求平均,对应于一般情况下的loss的计算。

L=\left\{l_{1}, \ldots, l_{N}\right\}

\ell(x, y)=\left\{\begin{array}{ll}\operatorname L, & \text { if reduction }=\text { 'none' } \\ \operatorname{mean}(L), & \text { if reduction }=\text { 'mean' } \\ \operatorname{sum}(L), & \text { if reduction }=\text { 'sum' }\end{array} \right.

MSELoss

均方误差(MSE),用于回归模型

对于包含N个样本的batch数据 D(x, y)x为神经网络的输出,y是真实的得分。

n个样本的损失值l_{n}计算如下:

l_{n}=\left(x_{n}-y_{n}\right)^{2}

其中,y_{n}代表第n样本的真实得分,可能对应一个值,也可能多个值,代表样本不同方面的得分,所以l_{n}可能是一个值,也可能是一个向量。

class MSELoss(_Loss):
    def __init__(self, size_average=None, reduce=None, reduction='mean'):
        super(MSELoss, self).__init__(size_average, reduce, reduction)
    def forward(self, input, target):
        return F.mse_loss(input, target, reduction=self.reduction)

pytorch中通过torch.nn.MSELoss类实现,也可以直接调用F.mse_loss 函数。代码中的size_averagereduce已经弃用。reduction有三种取值mean, sum, none,对应不同的返回\ell(x, y)。默认为mean,对L中所有元素求平均,对应于一般情况下的loss的计算。

L=\left\{l_{1}, \ldots, l_{N}\right\}

\ell(x, y)=\left\{\begin{array}{ll}\operatorname L, & \text { if reduction }=\text { 'none' } \\ \operatorname{mean}(L), & \text { if reduction }=\text { 'mean' } \\ \operatorname{sum}(L), & \text { if reduction }=\text { 'sum' }\end{array} \right.

SmoothL1Loss

分段使用均方误差和平均绝对误差,用于回归模型

对于包含N个样本的batch数据 D(x, y)x为神经网络的输出,y是真实的得分。

n个样本的损失值l_{n}计算如下:

l_{n}=\left\{\begin{array}{ll}0.5\left(x_{n}-y_{n}\right)^{2} / \text { beta }, & \text { if }\left|x_{n}-y_{n}\right|<\text { beta } \\ \left|x_{n}-y_{n}\right|-0.5 * \text { beta }, & \text { otherwise}\end{array}\right.

其中,y_{n}代表第n样本的真实得分,可能对应一个值,也可能多个值,代表样本不同方面的得分,所以l_{n}可能是一个值,也可能是一个向量。

相比平均绝对误差,SmoothL1Loss平滑了\left|x_{n}-y_{n}\right|趋近于0时的误差。相比均方误差函数,SmoothL1Loss对离群点更不敏感。在一定程度上可以防止梯度爆炸问题。Fast R-CNN论文有详细论述。

class SmoothL1Loss(_Loss):
    def __init__(self, size_average=None, reduce=None, reduction: str = 'mean', beta: float = 1.0) -> None:
        super(SmoothL1Loss, self).__init__(size_average, reduce, reduction)
        self.beta = beta
    def forward(self, input: Tensor, target: Tensor) -> Tensor:
        return F.smooth_l1_loss(input, target, reduction=self.reduction, beta=self.beta)

pytorch中通过torch.nn.SmoothL1Loss类实现,也可以直接调用F.smooth_l1_loss 函数。代码中的size_averagereduce已经弃用。reduction有三种取值mean, sum, none,对应不同的返回\ell(x, y)。默认为mean,对L中所有元素求平均,对应于一般情况下的loss的计算。

L=\left\{l_{1}, \ldots, l_{N}\right\}

\ell(x, y)=\left\{\begin{array}{ll}\operatorname L, & \text { if reduction }=\text { 'none' } \\ \operatorname{mean}(L), & \text { if reduction }=\text { 'mean' } \\ \operatorname{sum}(L), & \text { if reduction }=\text { 'sum' }\end{array} \right.

参数beta>=0,默认为1

HuberLoss

分段使用均方误差和平均绝对误差,用于回归模型

对于包含N个样本的batch数据 D(x, y)x为神经网络的输出,y是真实的得分。

n个样本的损失值l_{n}计算如下:

l_{n}=\left\{\begin{array}{ll}0.5\left(x_{n}-y_{n}\right)^{2}, & \text { if }\left|x_{n}-y_{n}\right|<\text { beta } \\ \text { beta }*(\left|x_{n}-y_{n}\right|-0.5 * \text { beta }), & \text { otherwise}\end{array}\right.

对比SmoothL1LossHuberLoss公式可知,\text {HuberLoss}= \text {beta}* \text {SmoothL1Loss},两者有如下区别:

  • beta趋于0时,SmoothL1Loss收敛于L1Loss, HuberLoss收敛于常数0
  • beta趋于无穷时,SmoothL1Loss收敛于常数0,HuberLoss收敛于MSELoss
  • 随着beta的变化,SmoothL1Loss中平均绝对误差段的斜率恒定为1;而HuberLos中平均绝对误差段的斜率是beta

SmoothL1Loss 例子:

import torch
import torch.nn as nn
import math


def validate_loss(output, target, beta):
    val = 0
    for li_x, li_y in zip(output, target):
        for i, xy in enumerate(zip(li_x, li_y)):
            x, y = xy
            if math.fabs(x - y) < beta:
                loss_val = 0.5 * math.pow(x - y, 2) / beta
            else:
                loss_val = math.fabs(x - y) - 0.5 * beta
            val += loss_val
    return val / output.nelement()


beta = 1
loss_fct = nn.SmoothL1Loss(reduction="mean", beta=beta)
input_src = torch.Tensor([[0.8, 0.8], [0.9, 0.9], [0.3, 0.3]])
target = torch.Tensor([[0.6, 0.6], [0.7, 0.8], [0.4, 0.5]])
print(input_src.size())
print(target.size())
loss = loss_fct(input_src, target)
print(loss.item())

validate = validate_loss(input_src, target, beta)
print(validate)

loss_fct = nn.SmoothL1Loss(reduction="none", beta=beta)
loss = loss_fct(input_src, target)
print(loss)

输出结果:

torch.Size([3, 2])
torch.Size([3, 2])
0.01499999687075615
0.014999997715155441
tensor([[0.0200, 0.0200],
        [0.0200, 0.0050],
        [0.0050, 0.0200]])

相关文章

  • loss函数之L1Loss,MSELoss,SmoothL1Lo

    L1Loss 平均绝对误差(MAE),用于回归模型 对于包含个样本的batch数据 ,为神经网络的输出,是真实的得...

  • pytorch【损失函数模块】二、损失函数之二

    (代码见lesson-16) 5、nn.L1Loss和6、nn.MSELoss 7、SmoothL1Loss 8、...

  • Center Loss

    损失函数改进之Center Loss

  • loss函数之triplet loss

    不同于交叉熵损失仅仅考虑样本与类别标签之间误差,triplet loss关注样本与其他样本之间距离。来自论文Lea...

  • loss函数之BCELoss

    BCELoss 二分类交叉熵损失 单标签二分类 一个输入样本对应于一个分类输出,例如,情感分类中的正向和负向 对于...

  • loss函数之KLDivLoss

    KL散度 KL散度,又叫相对熵,用于衡量两个分布(离散分布和连续分布)之间的距离。 设 、 是离散随机变量的两个概...

  • loss函数之SoftMarginLoss

    SoftMarginLoss 用于二分类任务 对于包含个样本的batch数据 , 代表模型输出,代表真实的类别标签...

  • loss函数之SoftMarginLoss

    SoftMarginLoss 用于二分类任务 对于包含个样本的batch数据 , 代表模型输出,代表真实的类别标签...

  • loss函数之MarginRankingLoss

    MarginRankingLoss 排序损失函数 对于包含个样本的batch数据 , , 是给定的待排序的两个输入...

  • 逻辑回归

    逻辑回归: 公式 loss函数 非凸函数,容易造成局部最优 Minimizing the loss corresp...

网友评论

      本文标题:loss函数之L1Loss,MSELoss,SmoothL1Lo

      本文链接:https://www.haomeiwen.com/subject/xpxzeltx.html