交叉熵函数推导CrossEntropy

本文演示了如何从零推导出交叉熵函数。通过对于下面这些概念的讲解,信息量、熵、KL散度,作者演示了交叉熵是如何从信息量的概念一步步推导到交叉熵。下一步作者对于交叉熵函数进行了变形,最后推导出用softmax函数表示交叉熵函数的公式。pytorch内置了这个函数F.log_softmax来实现上面这个公式。

目录

1. 交叉熵从何而来?从根上讲起

1.1 期望

1.2 熵 Entropy

[1]信息量

[2]熵的公式

[3]举个计算熵的例子  

1.3 相对熵(KL散度)

1.4 交叉熵 Cross Entropy

2. 交叉熵函数与softmax函数有什么关系?

3. 交叉熵与NLLoss


1. 交叉熵从何而来?从根上讲起

期望 → 熵 → 相对熵(KL散度) → 变形得到的交叉熵

1.1 期望

期望就是所有随机变量的均值

\mathrm{E}(\mathrm{x})=\mathrm{x}_1 \times \mathrm{P}\left(\mathrm{x}_1\right)+\mathrm{x}_2 \times \mathrm{P}\left(\mathrm{x}_2\right)+\cdots+\mathrm{x}_{\mathrm{n}} \times \mathrm{P}\left(\mathrm{x}_{\mathrm{n}}\right)

(1)如果x满足均匀分布,期望就等于均值。比如抛硬币。

抛硬币满足均匀分布是因为,抛正面的概率是0.5,抛反面的概率是0.5.

E(x) = 0.5 ×  1  +  0.5  *  0  =  0.5

(2)如果x不满足均匀分布

比如考试估分,我估计,能拿90分的概率是0.25,60分的概率是0.5,40分概率0.25。因此我考试分数的期望是  90  ×  0.25  +  60  ×  0.5  +  40  ×  0.25  = 

1.2 熵 Entropy

[1]信息量

熵表示所有信息量的期望

信息量如何计算呢?

        概率值取log,然后加个负号,就是信息量

        \mathrm{I}\left(\mathrm{x}_0\right)=-\log \left(\mathrm{P}\left(\mathrm{x}_0\right)\right)

        怎么理解这个公式定义呢?这样定义的合理之处在哪里呢?请你自圆其说。

                概率越小,信息量越大。

                如果我告诉你,“巴西下届世界杯要进总决赛”,你会觉得“你这不是废话吗?巴西哪届世界杯不进决赛啊?和没说有什么区别?”。那你为什么会这么想?因为巴西几乎99%的概率进世界杯,概率很大。概率越大的事件,能带来的信息量就越小。

                再比如,我告诉你,“下届世界杯,中国队要进总决赛”,你会说“说这个,我就不困了。细细讲讲。中国队不是这不行,那不行吗?凭啥你觉得下届世界杯中国能踢进总决赛?说说你咋分析的,你是不是有内幕消息?”。你会这么想是因为,中国队能进世界杯的概率太小,小到几乎为零,无限逼近于零。这么小概率的事情发生,你说这里面的信息量大不大?

[2]熵的公式

熵就是在信息量的基础之上求一个期望(也就是先乘概率值再累计求和)。熵的公式定义如下。

\mathrm{H}(\mathrm{x})=-\sum_{\mathrm{i}=1}^{\mathrm{n}} \mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right) \log \left(\mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right)\right)

以上的log函数全部底为2。

[3]举个计算熵的例子  

对于二项分布,只有两种可能的情况,一个发生的概率为P(x),另一个发生的概率为1-P(x),此时的信息量计算过程如下

\small \mathrm{H}(\mathrm{x})=-\sum_{\mathrm{i}=1}^{\mathrm{n}} \mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right) \log \left(\mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right)\right)=-\mathrm{P}(\mathrm{x}) \log (\mathrm{P}(\mathrm{x}))-(1-\mathrm{P}(\mathrm{x})) \log (1-\mathrm{P}(\mathrm{x}))

第一步是求和,一共就两种可能,因此第二步是两个式子。第二步实际上把外面那个负号带进去

交叉熵就是损失函数。信息量是各种情况熵的期望。熵的公式里面填的数字都是概率值。两种情况的事件,概率值只有两种,P(x)  和  1-P(x) ,带进去如上。

1.3 相对熵(KL散度)

KL散度的定义:

        同一随机变量x,有两个单独的概率分布P(x)和Q(x)。用KL散度来衡量P(x)和Q(x)两个独立分布之间的差异的。KL散度值越小,表示P和Q的分布越接近、

        给这样的定义,一个直观的理解:

                之所以说是在对比两个分布的差异,可以看最后一项,看着是两个概率值做除法,但是别忘了前面有个log。log里面的相除,拿出来就是相减。做减法不就是计算二者的差异吗?

D_{K L}(P \| Q)=\sum_{i=1}^n P\left(x_i\right) \log \left(\frac{P\left(x_i\right)}{Q\left(x_i\right)}\right)

1.4 交叉熵 Cross Entropy

先说交叉熵函数是用来干啥的。用来做损失函数的,表示你对于数据的分类情况和真实的类别情况之间的距离。我们进行梯度下降优化的目的就是,使得你分类的结果尽可能的逼近真实的分类结果。也就是使得KL散度越小越好。

第一步

        带入KL散度公式,是下面这样。那我们就像啊,能不能把公式推导化简一下呢?于是下一步

\mathrm{D}_{\mathrm{KL}}(\mathrm{P} \| \mathrm{Q})=\sum_{\mathrm{i}=1}^{\mathrm{n}} \mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right) \log \left(\frac{\mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right)}{\mathrm{Q}\left(\mathrm{x}_{\mathrm{i}}\right)}\right) \\

第二步

        对上一步,最右边这个P(xi)/Q(xi)拆开,从除变成减,两边都有P(xi),求和符号也带着

\mathrm{D}_{\mathrm{KL}}(\mathrm{P} \| \mathrm{Q})=\sum_{\mathrm{i}=1}^{\mathrm{n}} \mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right) \log \left(\mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right)\right)-\sum_{\mathrm{i}=1}^{\mathrm{n}} \mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right) \log \left(\mathrm{Q}\left(\mathrm{x}_{\mathrm{i}}\right)\right) \\

\mathrm{H}(\mathrm{x})=-\sum_{\mathrm{i}=1}^{\mathrm{n}} \mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right) \log \left(\mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right)\right)

此时我们发现前面这块,按照熵的公式定义(我上面写了对信息量求期望,也就是概率值与这种情况的值,再求和),就是P(x)的熵。因此下一步,左边这项做了替换,右边那项不变,如下是第三步。

第三步

\mathrm{D}_{\mathrm{KL}}(\mathrm{P} \| \mathrm{Q})=-\mathrm{H}(\mathrm{P}(\mathrm{x}))+\left[-\sum_{\mathrm{i}=1}^{\mathrm{n}} \mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right) \log \left(\mathrm{Q}\left(\mathrm{x}_{\mathrm{i}}\right)\right)\right] \\

此时我们发现P(X)是个常数不是个变量(P(x)是常数,P(xi)才是变量)。既然是常数,那在优化中相当于不起作用,因为你怎么更新参数,常量他也不跟着变,那你管它干嘛?

于是删掉  -H(P(x)),只剩下右边这一项,我们把右边这一项命名为交叉熵,把他定位分类任务的优化目标。

第四步

\mathrm{H}(\mathrm{P}, \mathrm{Q})=-\sum_{i=1}^{\mathrm{n}} \mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right) \log \left(\mathrm{Q}\left(\mathrm{x}_{\mathrm{i}}\right)\right)

为啥这叫交叉熵呢?哪里交叉了?

        我们先来看熵的公式也就是对信息量求期望,如下,自己这个事件的概率P(xi)和自己事件的信息量log(P(xi))相乘。但是你看上面这个交叉熵函数,P(xi)这个 P的概率   和Q(xi)这个Q的信息量相乘,是不是混搭?是不是就交叉了。所以叫交叉熵。

\mathrm{H}(\mathrm{x})=-\sum_{\mathrm{i}=1}^{\mathrm{n}} \mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right) \log \left(\mathrm{P}\left(\mathrm{x}_{\mathrm{i}}\right)\right)

2. 交叉熵函数与softmax函数有什么关系?

公式如下。其实softmax就是在做了一个归一化。左边这个a是softmax的输出,右边是输入。右边的分母是所有的输入值,一共k个吗,全部加一起,求和。分子是每个输入。当然了所有的输入都放进了e这个指数函数里面。输出是一个长条的向量,向量中每个元素就是这个输入占总输入的比重。

\mathrm{a}_{\mathrm{j}}^{\mathrm{L}}=\frac{\mathrm{e}^{z_{\mathrm{j}}^{\mathrm{L}}}}{\sum_{\mathrm{k}} \mathrm{e}^{z_{\mathrm{k}}^{\mathrm{L}}}}

softmax与交叉熵之间又有什么关系呢?

        分类用的是softmax得到你的prediction,有了你的prediction以后,再用交叉熵这个损失函数来评估你的prediction与ground truth之间的差异、距离。我们的优化是以降低这个差异、距离为目标的。

        交叉熵的函数可以继续推导

H(P, Q)=-\sum_{i=1}^n P\left(x_i\right) \log \left(Q\left(x_i\right)\right)=-\sum_i y_i \log a_i=-\sum_i y_i \log (\operatorname{softmax})

设P(x)为标签,Q(x)为预测。用yi来替换P(xi)这个标签,用ai来替换Q(xi)这个真实值,得到第三个式子。

yi表示标签,标签是预先就拿到的,是死的、固定的、不变的。唯一变的是后面这个a。a是Q(xi),是个概率值。

说到这里,我问你,啥是概率值?概率值具备什么特殊属性?概率值最典型的属性,就是所有概率值求和为1,没有任何一个概率值可能大于1,对不对?

那么我再问你,什么函数也能让所有的输入都归一化到0到1的区间,并且使这些输出的求和为0?

你想想,你仔细想想,我上面刚刚讲了一个激活函数。

是的,你说的没错,softmax就是来干归一化这个事的。

因此我们可以进一步把ai,也就是Q(xi),这个概率值,用softmax来表示。于是有了最后一个式子。

这时候你要问了,你推这个有什么用?你想说啥?

        我想说,很多人做分类任务的时候,损失函数直接用 -log(softmax)这样来设置损失函数,来达到损失函数是交叉熵的目的。比如下面这个pytorch的代码。

out = F.log_softmax(out,dim=1)

注意pytorch里面本身就有交叉熵函数的包,我为啥不用官方提供的,非要自己弄一个?
        因为你做论文和做工作,有时候要修改损失函数的定义吧?
        但是pytorch里面的这个交叉熵函数是封装好的,不允许你修改,但是你非要改。那你就不能用官方给的交叉熵函数了。你要自己改,改的基础是你得实现了和官方损失函数一样的东西,你在在此基础上改对吧。

这个对softmax取log,就完美实现了交叉熵函数。log_softmax是pytorch内置的,很多人都有这个需求,于是官方提供的。

               

你又问了,那人家这个交叉熵函数是 “负的 求和 yi log(softmax)”,请问yi去哪了?yi是你分类分出的你觉得对的标签,你输入剩下的东西 log(softmax) 就可以得到损失值。相当于 log(softmax)对yi做了线性变换。

        给你举个例子解释一下,拿到数据怎么用上面推导出来的这个公式,来算loss。假设,你分类的类别只有两种,红色和绿色,分别用[1, 0]和[0,1]来表示,也就是说y的取值只有两种可能0和1。a的话是概率值,取值范围是[0,1]。

Loss=-\sum_i y_i \log (\operatorname{a_i})

Loss是取的sum,是i个元素求和,也就是i个类别下求和。这里有两个类别。我们只看绿色这个类别[0,1]。单独一个类别类别下也有两个组成部分。我们用的是独热编码,因此有两部分组成,一部分是“热”的那一部分,也就是取1的那个,另一部分是“不热”,也就是取0的那个部分。对于“不热”取零的那个,yi=0,不管概率值a取什么数字,都是0,因此不起任何作用---正好和独热编码的特性相扣了,独热编码里面为0的部分也是不起作用。对于“热”的、yi取1的那个,这一项是-yi×log aj=-log aj。aj表示分对的概率,这里可以看到分对的概率越大,loss就越小,和我们的常识相符合。证明我们的带入方式是对的。

3. 交叉熵与NLLoss

NLLLoss= Negative Log Likelihood负对数似然损失函数

        计算方式与交叉熵相同,

        input在输入NLLLoss()之前,需要对input进行log_softmax函数激活,(即将input转化成概率分布的形式,并且取对数;就是先softmax,后log)

        只不过向里面传的不是softmax而是,log(softmax)

  • 12
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

德彪稳坐倒骑驴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值