pytorch(15)损失函数

损失函数

1. 损失函数概念

损失函数:衡量模型输出与真实标签的差异

\[损失函数(Loss Function): Loss = f(\hat y,y) \]
\[代价函数(Cost Function): Cost =\frac{1}{N} \sum^{N}_{i}f(\hat y_i ,y_i) \]
\[目标函数(Objective Function): Obj = Cost+Regularization \]

损失函数:计算一个样本的一个差异代价函数:计算整个样本的loss的平均值目标函数:表示最终的一个目标,目标函数来说在有约束条件下的最小化就是损失函数(loss function)
代价函数未必是越小越好,因为很可能出现过拟合。因此为了不让代价函数达到最小,出现过拟合。于是我们就添加了Regularization的正则项L1,L2。

  1. 损失函数
class _Loss(Module):
	def __init__(self,reduction='mean'):
		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

分析流程:
crossentropyLoss的流程:

loss_functoin = nn.CrossEntropyLoss()   #①处

先通过nn.CrossEntropyLoss构建损失函数赋给loss_function,紧接着在训练过程中通过

loss = loss_functoin(outputs, labels)   #②处

进行计算其损失函数,输入神经网络模型的输出outputs的值和标签进行loss。
在①②处设置断点,step into①处时,进入loss.py,调用class CrossEntropyLoss类,继承_WeightedLoss类,也就是会继承一个带权值的Loss类。进入init的初始化类,能够看到它调用了一个父类的super(CrossEntropyLoss)的初始化类,再step into,能够看到它是一个_WeightedLoss类的init初始化,这个类继承_Loss这个基本类。再通过step into能够看到是继承的Module类,其主要是设置reduction。在这里reduction="mean"。
接下来我们在step into②处进行step into。刚刚在lossfunction处我们已经知道lossfunction是一个Module类型,所以这里输入一个outputs和labels之后就是执行了一个forward.在这里step into后的hook就比较熟悉,我们直接进入到

result = self.forward(*input, **kwargs)

再进入到step into后,进入到forward模块

def forward(self, input: Tensor, target: Tensor) -> Tensor:
        return F.cross_entropy(input,target,weight=self.weight,ignore_index=self.ignore_index,reduction=self.reduction)

step into [F.cross_entropy],进入到functional.py中

if size_average is not None or reduce is not None:
        reduction = _Reduction.legacy_get_string(size_average, reduce)
    return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)

接下来就能够计算出loss,在这里为[loss:tensor(0.7012, grad_fn=<NllLossBackward>)]

损失函数
  1. nn.CrossEntropyLoss
    功能:nn.LogSoftmax()[采用softmax进行归一化处理]与nn.NLLLoss()结合,进行交叉熵计算[和公式意义上的交叉熵不同之处:采用softmax进行归一化,把数据值归一到一个概率输出的模式,交叉熵损失函数常常用在分类任务当中,分类任务中通常需要计算两个输出的概率值,因为在分类任务当中我们的输出常常是以概率值为主的,所以交叉熵在这里主要是衡量两个概率分布之间的差异,所以交叉熵的值越低,表示两个概率分布越近越相似]
    交叉熵=信息熵+相对熵
\[{交叉熵: } H(P,Q) = -\sum^{N}_{i=1}P(x_i)log Q(x_i)\\ {自信息: }I(x)=-log[p(x)]\\ {熵(信息熵):}H(P)=E_{x\sim p}[I(x)]=-\sum^{N}_{i}P(x_i)logP(x_i)\\ {相对熵:}D_KL(P,Q)=E_{x\sim p}\Big[log \frac{P(x)}{Q(x)}\Big]\\ =E_{x\sim p}[logP(x)-logQ(x)]\\ =\sum_{i=1}^{N}P(x_i)[log P(x_i)-logQ(x_i)]\\ =\sum_{i=1}^{N}P(x_i)logP(x_i)-\sum_{i=1}^{N}P(x_i)logQ(x_i)\\ =H(P,Q)-H(P)\\ {交叉熵:}H(P,Q) = D_{KL}(P,Q)+H(P) \]

[熵是香农从热力学方面引申的一个概念,用来描述该事情的不确定性,一个事件越不确定,它的熵就越大,例如明天下雨这件事的熵就比明天太阳升起这件事的熵要大。自信息是用来衡量单个事件的不确定性,px是事件x的概率,对概率取一个-log。熵是整个概率分布的不确定性,用来描述整个概率分布,它是自信息的一个期望。相对熵又叫KL散度,用来衡量两个分布之间的差异距离,虽然是可以计算的,但是它不是一个距离函数,距离函数是有对称性的,这里的相对熵没有对称性。从公式上来看,P是真实的分布,Q是模型输出的一个分布,我们需要用Q去拟合P的分布,所以是不具备对称性的。它是对log P(x)/Q(x)]求取期望。因此在深度学习的模型中,我们去优化交叉熵,实际上就是去优化相对熵的,训练集的P是固定的常数,所以在优化中是优化DKL(P,Q)]
在伯努利模型中,很容易发现概率为0.5的Loss值是0.69,通常意义表明模型训练坏了,当前模型不具备任何判别能力。因为它对任何的输出都是0.5,可能或者不可能。
主要参数:

  • weight:各类别的loss设置权值,在公式中如下,如果我们想让第0类的loss更大点,让模型更关注第0类,我们可以把它的weight设置为1.2
  • ignore_index:忽略某个类别,不计算Loss
  • reduction:计算模式,可为none/sum/mean
    none:逐个元素计算
    sum:所有元素求和,返回标量
    mean:加权平均,返回标量
    nn.CrossEntropyLoss(weight=None,size_average=None,ignore_index=-100,reduce=None,reduction='mean')

交叉熵的计算公式如下:

\[x是概率值,class是类别值 \\H(P,Q)=\sum^{N}_{i=1}P(x_i)logQ(x_i)\\ loss(x,class)=-log\Big(\frac{exp(x[class])}{\sum_j exp(x[j])} \Big)=-x[class]+log\Big(\sum_j exp(x[j]) \Big)\\ softmax归一化=\frac{exp(x[class])}{\sum_j exp(x[j])}\\ 将这一个神经元的输出值归一化到一个概率取值区间。 \]
  1. NLL/BCE/BCEWithLogits Loss

nn.NLLLoss
功能:实现负对数似然函数中的负号功能
主要参数:

  • weight:各类别的Loss设置权值
  • ignore_index:忽略某个类别
  • reduction:计算模式,可为none/sum/mean
nn.NLLLoss(weight=None,size_average=None,ignore_index=-100,reduce=None,reduction='mean')
\[l(x,y)=L=\{l_1,...,l_N\}^T,l_n=-{w_{y_n}}x_{n,y_n} \]

nn.BCELoss
功能:二分类交叉熵
注意事项:输入值取值在[0,1]
主要参数:

  • weight:各类别的Loss设置权值
  • ignore_index:忽略某个类别
  • reduction:计算模式,可为none/sum/mean
    none-逐个元素计算
    sum-所有元素求和,返回标量
    mean-加权平均,返回标量
nn.BCELoss(weight=None,size_average=None,reduce=None,reduction='mean')
\[l_n = -w_n[y_n*log{x_n} +(1-y_n)*log(1-x_n) ] \]

nn.BCEWithLogitsLoss
功能:结合Sigmoid与二分类交叉熵注意事项:网络最后不加sigmoid函数
主要参数:

  1. pos_weight:正样本的权值
  2. weight:各类别的Loss设置权值
  3. ignore_index:忽略某个类别
  4. reduction:计算模式:none,sum,mean
    代码:
nn.BCEWithLogitsLoss(weight=None,size_average=None,reduce=None,reduction='mean',pos_weight=None)
\[l_n = -w_n[y_n * log(1- \sigma{(x_n)})] \]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值