[损失函数]——交叉熵

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[损失函数]——交叉熵相关的知识,希望对你有一定的参考价值。

参考技术A

在了解交叉熵之前我们需要关于熵的一些基本知识,可以参考我的上一篇 博客 [1] 。

信息熵的定义为离散随机事件的出现概率 [2] 。当一个事件出现的概率更高的时候,我们认为该事件会传播的更广,因此可以使用信息熵来衡量信息的价值。
当一个信源具有多种不同的结果,记为:U1,U2,...,Un,每个事件相互独立,对应的概率记为:P1,P2,...,Pn。信息熵为各个事件方式概率的期望,公式为:

对于二分类问题,当一种事件发生的概率为p时,另一种事件发生的概率就为(1-p),因此,对于二分类问题的信息熵计算公式为:

相对熵(relative entropy),又被称为Kullback-Leibler散度(Kullback-leibler divergence),是两个概率分布间差异的一种度量 [3] 。在信息论中,相对熵等于两个概率分布的信息熵的差值。
相对熵的计算公式为:

其中 代表事件的真实概率, 代表事件的预测概率。例如三分类问题的标签为 ,预测标签为 。

因此该公式的字面上含义就是真实事件的信息熵与理论拟合的事件的香农信息量与真实事件的概率的乘积的差的累加。[4]

当p(x)和q(x)相等时相对熵为0,其它情况下大于0。证明如下:

KL散度在 Pytorch 中的使用方法为:

在使用过程中, reduction 一般设置为 batchmean 这样才符合数学公式而不是 mean ,在以后的版本中 mean 会被替换掉。
此外,还要注意 log_target 参数,因为在计算的过程中我们往往使用的是log softmax函数而不是softmax函数来避免underflow和overflow问题,因此我们要提前了解target是否经过了log运算。

torch.nn.KLDivLoss() 会传入两个参数 (input, target) , input 是模型的预测输出, target 是样本的观测标签。

下面我们用一个例子来看看 torch.nn.KLDivLoss() 是如何使用的:

输出结果如下:

相对熵可以写成如下形式:

等式的前一项为真实事件的熵,后一部分为 交叉熵 [4] :

在机器学习中,使用KL散度就可以评价真实标签与预测标签间的差异,但由于KL散度的第一项是个定值,故在优化过程中只关注交叉熵就可以了。一般大多数机器学习算法会选择交叉熵作为损失函数。

交叉熵在pytorch中可以调用如下函数实现:

其计算方法如下所示 [5] :
假设batch size为4,待分类标签有3个,隐藏层的输出为:

经过 softmax 激活函数之后得到预测值:

softmax函数的输出结果每一行相加为1。
假设这一个mini batch的标签为

根据交叉熵的公式:

代表真实标签,在真实标签中,除了对应类别其它类别的概率都为0,实际上,交叉熵可以简写为:

所以该mini batch的loss的计算公式为(别忘了除以batch size,我们最后求得的是mini batch的平均loss):

因此,我们还需要计算一次对数:

计算结果为:

根据交叉熵的计算公式,loss的最终计算等式为:

运算结果和pytorch内置的交叉熵函数相同:

结果为:

除了 torch.nn.CrosEntropyLoss() 函数外还有一个计算交叉熵的函数 torch.nn.BCELoss() 。与前者不同,该函数是用来计算二项分布(0-1分布)的交叉熵,因此输出层只有一个神经元(只能输出0或者1)。其公式为:

在pytorch中的函数为:

用一个实例来看看如何使用该函数:

输出结果为:

它是如何计算的呢,我们接下来一步步分析:

首先输入是:

需要经过 sigmoid 函数得到一个输出

输出结果为:

然后我们根据二项分布交叉熵的公式:

得到 loss 的如下计算公式:

和pytorch的内置函数计算结果相同。
另外,需要注意的是, 当使用交叉熵作为损失函数的时候,标签不能为onehot形式,只能是一维的向量 ,例如,当batch size是5时,这一个batch的标签只能时[0,1,4,2,6]这样的形式。

以上是关于[损失函数]——交叉熵的主要内容,如果未能解决你的问题,请参考以下文章

交叉熵损失函数关于交叉熵损失函数的一些理解

交叉熵损失函数

语义分割损失函数

交叉熵损失函数修正Huber损失极大似然估计负对数似然似然与交叉熵KL散度

谈谈交叉熵损失函数

交叉熵损失函数详解