课程笔记:损失函数

损失函数:
损失函数针对一个样本
代价函数:全部样本的均值
目标函数:更广泛的概念(最终的目标),会包含cost与regularization
在这里插入图片描述
并不是cost越小越好,因为会过拟合(模型太过复杂)。
在追求模型输出与真实标签差异小的同时,会对模型做些约束(约束项即为正则项regularization)

loss的代码:可见继承自module,有8个有序字典,有init与forward。
reduction有三个值:none, mean和sum

class _Loss(Module):
    reduction: str

    def __init__(self, size_average=None, reduce=None, reduction: str = 'mean') -> None:
        super(_Loss, self).__init__()
        if size_average is not None or reduce is not None:
            self.reduction = _Reduction.legacy_get_string(size_average, reduce)
        else:
            self.reduction = reduction
#构建交叉熵损失函数
loss_function = nn.CrossEntropyLoss()
#交叉熵损失进行forward
loss = loss_function(outputs, labels)

Cross Entropy

Cross Entropy的手动计算:

import numpy as np
y = nn.array([1, 0, 0])
z = nn.array([0.2, 0.1, -0.1])
y_pred = np.exp(z) / np.exp(z).sum()
loss = -y * np.log(y_pred).sum() #有很多零项(忽略)

CrossEntropyLoss
是对输入进行softmax后再取log与标签经过one-hot编码的值计算损失。
注意神经网络的最后一层,不要做激活函数,因为把它变成分布的激活函数已经包含在交叉熵里面了。所以最后一层不要做非线性变换
标签y必须是长整型张量(LongTensor)
CrossEntropyLoss = LogSoftmax + NLLLoss
在这里插入图片描述
用pytorch计算CrossEntropyLoss:

import torch
y = torch.LongTensor([0])
z = torch.Tensor([0.2, 0.1, -0.1])
criterion = torch.nn.CrossEntropyLoss()
loss = criterion(z, y)

交叉熵是用来衡量两个分布之间的距离,nn.LogSoftmax是用来将输出值归一化到概率取值分布为0-1之间
在weight模式下,mean时是除以权值的份数
在这里插入图片描述

NLLLoss

NLLLoss:只是实现了负号的功能
在这里插入图片描述
NLLLoss:(Negative Log Likelihood Loss)
右边的输入是0,1,2,3…这样的标签,左边的输入是算完softmax之后紧跟着算log对数的值。这里它并不计算对数,而是算完对数之后的输入与标签之间的损失是多少.
在这里插入图片描述

BCELoss

BCELoss
BCELoss的标签与CrossEntropyLoss不一样,CrossEntropyLoss是LongTensor,而BCELoss是torch.float,是每一个神经元都要计算loss,不是一整个神经元向量计算loss。
注意:输入值取值在[]0, 1]之间,所以得使用sigmoid,符合概率取值
在这里插入图片描述
在输入之后加了sigmoid函数,将输入压缩到0-1之间

inputs = torch.tensor([[1, 2], [2, 2], [3, 4], [4, 5]], dtype=torch.float)
target = torch.tensor([[1, 0], [1, 0], [0, 1], [0, 1]], dtype=torch.float)
inputs = torch.sigmoid(inputs) # 将输入压缩到0-1之间
loss_f_none = nn.BCELoss(weight=None, reduction='none')
loss_none = loss_f_none(inputs, target)

BCEWithLogitsLoss

BCEWithLogitsLoss
其内包含sigmoid函数,只需要把输入输进来,无需再进行sigmoid计算
在这里插入图片描述

nn.L1Loss与nn.MSELoss

在这里插入图片描述

inputs = torch.ones((2, 2))
target = torch.ones((2, 2)) * 3
# nn.L1Loss
loss_f = nn.L1Loss(reduction='none')
loss = loss_f(inputs, target)
# nn.MSELoss
loss_f_mse = nn.MSELoss(reduction='none')
loss_mse = loss_f_mse(inputs, target)

SmoothL1Loss

在这里插入图片描述
在这里插入图片描述

inputs = torch.linspace(-3, 3, steps=500)
target = torch.zeros_like(inputs)

loss_f = nn.SmoothL1Loss(reduction='none')
loss_smooth = loss_f(inputs, target)

PoissonNLLLoss
输出分类时,这个分类服从泊松分布时使用的损失函数
在这里插入图片描述

KLDivLoss

KL散度,就是相对熵,用来衡量两个分布之间的相似性(也可以认为是去计算两个分布之间的距离)
P为真实的分布,Q为输出的分布
pytorch中的公式和KL散度的公式不一样,在于括号里的对输出的分布没有求log,所以提前计算log(转化成分布)
在这里插入图片描述

inputs = torch.tensor([[0.5, 0.3, 0.2], [0.2, 0.3, 0.5]])
# pytorch函数计算公式不是原始定义公式,其对输入默认已经取log了,在损失函数计算中比公式定义少了一个log(input)的操作
# 因此公式定义里有一个log(y_i / x_i),在pytorch变为了 log(y_i) - x_i,
inputs = F.log_softmax(inputs, 1)
target = torch.tensor([[0.9, 0.05, 0.05], [0.1, 0.7, 0.2]], dtype=torch.float)
loss_f_none = nn.KLDivLoss(reduction='none')
loss_f_mean = nn.KLDivLoss(reduction='mean')
loss_f_bs_mean = nn.KLDivLoss(reduction='batchmean')

loss_none = loss_f_none(inputs, target)
loss_mean = loss_f_mean(inputs, target)
loss_bs_mean = loss_f_bs_mean(inputs, target)

nn.MarginRankingLoss

在这里插入图片描述

nn.MultiLabelMarginLoss

多标签的意思是指一张图片对应多个类别
在这里插入图片描述

用pytorch计算
x = torch.tensor([[0.1, 0.2, 0.4, 0.8]])
y = torch.tensor([[0, 3, -1, -1]], dtype=torch.long)

loss_f = nn.MultiLabelMarginLoss(reduction='none')
loss = loss_f(x, y)

#手动计算
x = x[0]
item_1 = (1-(x[0] - x[1])) + (1 - (x[0] - x[2]))    # [0]
item_2 = (1-(x[3] - x[1])) + (1 - (x[3] - x[2]))    # [3]

loss_h = (item_1 + item_2) / x.shape[0]

nn.SoftMarginLoss

在这里插入图片描述

nn.MultiLabelSoftMarginLoss

在这里插入图片描述

在这里插入图片描述

nn.TripletMarginLoss

在这里插入图片描述

nn.HingeEmbeddingLoss

在这里插入图片描述

nn.CosineEmbeddingLoss

在这里插入图片描述

nn.CTCLoss

在这里插入图片描述
总结
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值