18种损失函数全详解及其PyTorch实现与机制


该篇笔记整理自余庭嵩的讲解。如果主要看损失函数如何使用则先看交叉熵损失函数的使用部分,该部分对损失函数pytorch实现时的各变量解释详细,并且其他损失函数的reduction变量与其大同小异,在这些部分里就不再重新说明reduction变量了。

基础概念

损失函数就是衡量模型输出与真实标签之间的差异。除损失函数外,平常接触到似乎也包含类似功能的还有代价函数和目标函数。那么这三者之间的区别和联系是什么呢?

损失函数(Loss Function)

功能:计算一个样本输出和真实标签之间的差异,表达式如下
Loss = f ( y ^ , y ) \text {Loss}=f\left(\hat y, y\right) Loss=f(y^,y)

代价函数(Cost Function)

功能:计算整个训练集的loss的平均值,表达式如下
c o s t = 1 N ∑ i N f ( y ^ i , y i ) \rm{cost}=\frac{1}{N} \sum_{i}^{N} f\left(\hat y_{i}, y_{i}\right) cost=N1iNf(y^i,yi)

目标函数(Objective Function)

定义:在机器学习中代表最终的训练目标,表达式如下
O b j = c o s t + r e g u l a r i z a t i o n Obj = cost+regularization Obj=cost+regularization
这里的regularization代表正则化。

PyTorch实现与机制

在定义损失函数的时候,经常可以看到首先会对损失函数的计算规则进行定义,以交叉熵损失函数为例,定义语句如下:

criterion = torch.nn.CrossEntropyLoss()

执行这句话的时候,就可以看到,其实所有损失函数都会继承一个父类,这个父类的名称是_Loss,其内容如下:

class _Loss(Module):
    def __init__(self, size_average=None, reduce=None, 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

定义完成之后,就是执行部分了,还是以交叉熵损失为例,执行的语句如下:

loss = criterion(outputs, labels)

这句话本质上也是属于前向传播的一部分,同样也是会执行torch.nn.Module的forward函数。forward函数内容如下:

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

而forward函数的核心是调用了torch.nn.functional里定义的函数cross_entropy,这个函数的内容如下:

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)

于是我们就可以通过这样的调用关系清楚了解到损失函数的功能与运行机制。

nn.CrossEntropyLoss

功能与使用

由前面pytorch实现机制中的介绍可以看到,交叉熵函数是nn.Logsoftmax()与nn.NLLLoss()结合,进行交叉熵计算。这里的nn.Logsoftmax()函数将输入的数据进行了归一化处理,变成了概率分布的形式,再取log后进行输出。而nn.NLLLoss()则是取负号操作。整个过程的数学表达式如下,无weight时:
loss ⁡ ( x ,  class  ) = − log ⁡ ( exp ⁡ ( x [  class  ] ) ∑ j exp ⁡ ( x [ j ] ) ) = − x [  class  ] + log ⁡ ( ∑ j exp ⁡ ( x [ j ] ) ) \operatorname{loss}(x, \text { class })=-\log \left(\frac{\exp (x[\text { class }])}{\sum_{j} \exp (x[j])}\right)=-x[\text { class }]+\log \left(\sum_{j} \exp (x[j])\right) loss(x, class )=log(jexp(x[j])exp(x[ class ]))=x[ class ]+log(jexp(x[j]))
有weight时:
loss ⁡ ( x ,  class  ) =  weight  [  class  ] ( − x [  class  ] + log ⁡ ( ∑ j exp ⁡ ( x [ j ] ) ) ) \operatorname{loss}(x, \text { class })=\text { weight }[\text { class }]\left(-x[\text { class }]+\log \left(\sum_{j} \exp (x[j])\right)\right) loss(x, class )= weight [ class ](x[ class ]+log(jexp(x[j])))
在使用CrossEntropyLoss函数时,其主要参数有

  • weight:各类别的loss设置权值(例如某类计算好loss后再乘1.5倍)
  • ignore_ index:忽略某个类别(在某类不计算loss)
  • reduction :计算模式,可为none/sum/mean
  • size_average&reduce:不管,现在这两个变量用reduction就可以替代其作用了

其中
none代表逐个元素计算
sum代表所有元素求和,返回标量
mean代表加权平均,返回标量
reduction需要以字符串的的形式赋值上面三个字符串中的任意一个。

数学原理

如果需要了解交叉熵,首先需要了解信息熵以及相对熵的概念。

信息熵

先来解释信息熵的概念,信息熵由香农提出,从热力学领域借鉴而来,其主要衡量了信息的不确定程度,一个信息的熵越大说明越不确定。其表达式如下:
H ( P ) = E x ∼ p [ I ( x ) ] = − ∑ i N P ( x i ) log ⁡ P ( x i ) \mathbf{H}(\mathbf{P})=\boldsymbol{E}_{\boldsymbol{x} \sim \boldsymbol{p}}[\boldsymbol{I}(\boldsymbol{x})]=-\sum_{\boldsymbol{i}}^{\boldsymbol{N}} \boldsymbol{P}\left(\boldsymbol{x}_{\boldsymbol{i}}\right) \log \boldsymbol{P}\left(\boldsymbol{x}_{\boldsymbol{i}}\right) H(P)=Exp[I(x)]=iNP(xi)logP(xi)
这里可以发现,如果把log以及后面看成一个整体,信息熵似乎是在求某个东西的期望,这个东西就叫做自信息,其表达式如下:
I ( x ) = − log ⁡ [ p ( x ) ] \mathbf{I}(\boldsymbol{x})=-\boldsymbol{\operatorname { l o g }}[\boldsymbol{p}(\boldsymbol{x})] I(x)=log[p(x)]
这样就可以理解熵的概念,信息熵就是描述整个概率分布的不确定性,所以需要对自信息求期望,这样得出的结果才能评价整个概率分布。
值得一提的是,如果只有两个类别,那么两个类别概率相等的时候信息熵最大,此时的loss值是0.69。这就说明模型对数据没有任何判别能力。

相对熵(KL散度)

接下来解释相对熵:相对熵主要衡量了两个分布之间的差异,描述了两个分布之间的距离。但是需要注意的是,相对熵和距离函数有着本质区别。距离函数满足一个重要性质就是对称性:点P到点Q的距离等于点Q到点P的距离,而相对熵并不满足这个基本性质。其表达式如下:
D K L ( P , Q ) = E x ∼ p [ log ⁡ P ( x ) Q ( x ) ] = E x ∼ p [ log ⁡ P ( x ) − log ⁡ Q ( x ) ] = ∑ i = 1 N P ( x i ) [ log ⁡ P ( x i ) − log ⁡ Q ( x i ) ] = ∑ i = 1 N P ( x i ) log ⁡ P ( x i ) − ∑ i = 1 N P ( x i ) log ⁡ Q ( x i ) = H ( P , Q ) − H ( P ) \begin{aligned} \boldsymbol{D}_{\boldsymbol{K L}}(\boldsymbol{P}, \boldsymbol{Q}) &=\boldsymbol{E}_{\boldsymbol{x} \sim \boldsymbol{p}}\left[\log \frac{\boldsymbol{P}(\boldsymbol{x})}{\boldsymbol{Q}(\boldsymbol{x})}\right] \\ &=\boldsymbol{E}_{\boldsymbol{x} \sim \boldsymbol{p}}[\log \boldsymbol{P}(\boldsymbol{x})-\log \boldsymbol{Q}(\boldsymbol{x})] \\ &=\sum_{i=1}^{N} \boldsymbol{P}\left(\boldsymbol{x}_{i}\right)\left[\log P\left(\boldsymbol{x}_{i}\right)-\log \boldsymbol{Q}\left(\boldsymbol{x}_{i}\right)\right] \\ &=\sum_{i=1}^{N} \boldsymbol{P}\left(\boldsymbol{x}_{i}\right) \log \boldsymbol{P}\left(\boldsymbol{x}_{i}\right)-\sum_{i=1}^{N} \boldsymbol{P}\left(\boldsymbol{x}_{i}\right) \log \boldsymbol{Q}\left(\boldsymbol{x}_{i}\right) \\ &=\boldsymbol{H}(\boldsymbol{P}, \boldsymbol{Q})-\boldsymbol{H}(\mathrm{P}) \end{aligned} DKL(P,Q)=Exp[logQ(x)P(x)]=Exp[logP(x)logQ(x)]=

  • 58
    点赞
  • 309
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
交叉熵损失函数pytorch中的一个常用函数,用于衡量分类任务中模型预测结果与真实标签之间的差异。在pytorch中,交叉熵损失函数的定义为nn.CrossEntropyLoss()。 该函数结合了nn.LogSoftmax()和nn.NLLLoss()两个函数的功能。其中,nn.LogSoftmax()用于对模型的输出进行log softmax操作,将其转化为概率分布;nn.NLLLoss()则用于计算负对数似然损失。因此,nn.CrossEntropyLoss()可以直接接收模型的输出和真实标签作为输入,并自动进行相应的处理,避免了手动进行softmax和计算负对数似然损失的麻烦。 在使用nn.CrossEntropyLoss()时,可以通过参数进行进一步的定制,比如设置权重、忽略特定的类别等。具体参数包括weight、size_average、ignore_index、reduce和reduction等。可以根据实际需要进行调整。 总结而言,交叉熵损失函数pytorch中是一个方便且常用的函数,用于衡量模型的预测结果与真实标签之间的差异,并可通过参数进行进一步的定制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【Pytorch】交叉熵损失函数 CrossEntropyLoss() 详解](https://blog.csdn.net/weixin_44211968/article/details/123906631)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【pytorch】交叉熵损失函数 nn.CrossEntropyLoss()](https://blog.csdn.net/weixin_37804469/article/details/125271074)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值