Entropy
$$ \begin{aligned} \text{Entropy} &= \sum_i P(i)\log\frac{1}{P(i)} \\ &= -\sum_i P(i)\log P(i) \end{aligned} $$
上面的公式是香农熵的定义,但看这个式子可能没有什么感觉,下面我们举个例子
假设有四个人,每个人中奖概率是均等的(都是 $\frac {1}{4}$),我们算一下这个分布的 Entropy
- a = torch.full([4], 1/4.) # tensor([0.2500, 0.2500, 0.2500, 0.2500])
- print("Entropy:", -(a*torch.log2(a)).sum()) # Entropy: tensor(2.)
熵越高,代表越稳定,越没有惊喜度
假设还是四个人,但中奖概率变为 0.1,0.1,0.1,0.7,此时 Entropy 变成多少了呢?
- a = torch.tensor([0.1, 0.1, 0.1, 0.7])
- print("Entropy:", -(a*torch.log2(a)).sum()) # Entropy: tensor(1.3568)
我们计算得到这种情况熵变小了,可以理解为,假设在这种概率分布的情况下,告诉你中奖了,你的惊喜程度会比同等中奖概率下的惊喜程度要大
最后,假设中奖概率变为 0.001,0.001,0.001,0.997,此时 Entropy 变为多少了呢?
- a = torch.tensor([0.001, 0.001, 0.001, 0.997])
- print("Entropy:", -(a*torch.log2(a)).sum()) # Entropy: tensor(0.0342)
这种情况的熵更小了,说明在这种概率分布情况下,你中奖的惊喜程度特别特别大
Cross Entropy
计算一个分布 $p$ 的 Entropy,我们通常用 $H (p)$ 来表示。计算两个分布的 Cross Entorpy,我们通常用 $H (p,q)$ 来表示,$H (p,q)$ 的计算公式为
$$ \begin{aligned} H(p,q)&= -\sum p(x) \log q(x) \\ &= H(p) + D_{KL}(p|q) \end{aligned} $$
其中 $D_{KL}$,即 Kullback–Leibler divergence,中文翻译是相对熵或信息散度,其公式为
$$ D_{KL}(P|Q) = -\sum_i P(i)\ln\frac{Q(i)}{P(i)} $$
简单一点理解就是,假如把 P 和 Q 作为函数画出来,它俩重叠的部分越少,$D_{KL}$ 越大,如果两个函数图像几乎完全重合,$D_{KL}≈0$。如果 $P=Q$, 则 Cross Entropy 就等于 Entropy
对于一个 Classification 问题,我们得到的 pred 是一个 0-1 Encoding,即 [0 0...1...0...0],很明显,这个 pred 的 Entropy $H (p)=0$,因为 $1\log1=0$,那么这个 pred 和真实的 Encoding $q$ 之间的 Cross Entropy
$$ \begin{aligned} H(p,q)&= H(p) + D_{KL}(p|q) \\ &= D_{KL}(p|q) \end{aligned} $$
也就意味着,当我们去优化 $p$ 和 $q$ 的 Cross Entropy 的时候,如果是 0-1 Encoding,它就相当于直接优化 $p$ 和 $q$ 的 KL divergence,而前面也说了,$p$ 和 $q$ 的 KL divergence 是衡量这两个分布的重叠情况,当 KL divergence 接近于 0 时,$p$ 和 $q$ 就越来越接近,这恰好就是我们要优化的目标
下面我们举个例子来说明 $H (p,q)$ 就是我们需要优化的目标,假设现在有一个 5 分类问题(可以想象为五种动物),真实值 $p = [1\ 0\ 0\ 0\ 0]$,预测值 $q = [0.4\ 0.3\ 0.05\ 0.05\ 0.2]$,则
$$ \begin{aligned} H(p,q)&= -\sum_i p(i)\log q(i) \\ &= -(1\log0.4 + 0\log0.3 + 0\log0.05 + 0\log0.05 + 0\log0.2) \\ &= -\log0.4 \\ &≈ 0.916 \end{aligned} $$
假设经过一轮参数更新以后,预测值发生了变化 $q = [0.98\ 0.01\ 0\ 0\ 0.01]$,则
$$ \begin{aligned} H(p,q)&= -\sum_i p(i)\log q(i) \\ &= -(1\log0.98 + 0\log0.01 + 0\log0 + 0\log0 + 0\log0.01) \\ &= -\log0.4 \\ &≈ 0.02 \end{aligned} $$
Cross Entropy 大概下降了 0.8 左右,假如使用 MSE 作为 Loss,大概只会下降 0.3~0.4 左右,所以我们感性认识一下,使用 Cross Entropy 梯度下降的更快
- import torch
- import torch.nn.functional as F
- x = torch.randn(1, 784) # [1, 784]
- w = torch.randn(10, 784) # [10, 784]
- logits = x@w.t() # [1, 10]
- pred = F.softmax(logits, dim=1)
- pred_log = torch.log(pred)
-
- '''
- 注意下面cross_entropy和nll_loss传入参数的区别
- '''
- print(F.cross_entropy(logits, torch.tensor([3])))
- # cross_entropy()函数已经把softmax和log打包在一起了,所以必须传一个原生的值logits
-
- print(F.nll_loss(pred_log, torch.tensor([3])))
- # null_loss()函数传入的参数需要经过softmax和log
感性认识是不对的
哈哈,您说的有道理
熵越大不确定性越大,确定性越小,比如等概率分布,你也不知道选的是哪个,所以有很大的随机性。
等概率分布的时候四种情况都有可能,所以有较大的熵。
是不是应该这么理解?