交叉熵和相对熵是从信息论的角度推导的,而负对数似然是用概率论工具推导的,按照顺序,我们先从信息熵说起。

信息熵(Entropy)

事件的不确定性越大,其包含的信息量越多,熵也越大。

考虑”昨天太阳升起”这一事件,信息量是如此之少,因为我们知道如果没有特别的天气情况,是一定能看到太阳升起的。而”昨天发生了日食”就包含了很大的信息量,因为日食是一个不大可能发生的事件,却奇迹般地发生了,使人感到不可思议。

下面给出事件熵的公式,仍可用上面的例子理解它。

$$
S = -\sum_{i=1}^{K}{p_ilog(p_i)}
$$

例如”明天太阳会升起”的情况, p1 表示”太阳不升起”的概率,p2 表示”太阳升起”的概率。明天太阳是一定会升起的,所以对应的概率向量 p=(0.0, 1.0),信息熵为0。

观察公式可以发现,事件发生的概率越接近0或1,不确定性越小,其信息熵也越小。

相对熵

也称做KL散度(Kullback-Leibler Divergence)。顾名思义,是以一个基准事件的概率分布作为参考,另一事件的相对基准事件的信息量度量。

例如抛硬币,正常情况,我们认为正面朝上的概率和反面朝上的概率相等,即对应的概率向量 p=(0.5,0.5) 。即我们认为抛硬币得到0.5的概率是意料之中的,没有信息量。

这时,你找来一个外星造币开始抛,发现正面朝上的概率是0.8,相比”抛正常硬币”的情况,使人觉得不可思议,包含较大的信息量(可能外星造币有强烈的磁场)。于是,我们可以使用相对熵来衡量某个概率分布与基准分布的差异,事件B相对事件A的熵定义如下:

$$
D_{KL}(A||B) = \sum_{i=1}^{K}{p_A(i)log(\frac{p_A(i)}{p_B(i)})}
$$

在机器学习分类任务中,p_A(i)表示标签的真实分布,即y_{true},p_B(i)表示预测的类别概率,即p_B(i),假设标签是一个one_hot向量(即只有一个元素为1,其他元素为0),那么上述等式的左半部分,即A的熵:

$$
S(A) = \sum_{i=1}^{K}{p_A(i)log(p_A(i))} = 0
$$

此时,相对熵就是交叉熵:

接下来,再看通过多项式分布推导交叉熵的思路。

负对数似然(Negative Log Likelihood)

先从熟悉的两点分布说起,对应二分类问题,其分布律为:

$$
P(X=x | p) = p^x(1-p)^{1-x}= \begin{cases} p & \text{if } x = 1 \ 1-p & \text{if } x = 0 \end{cases}
$$

对于多分类问题,只需将其扩展到多项分布,假设X有K种可能的取值:

$$
P(X=x|p_{1},p_{2},…,p_{k})=\prod_{i=1}^{K}p_{i}^{x_{i}}
$$

$$
\sum_{i=1}^{K}{p_{i}} =\sum_{i=1}^{K}{x_{i}}= 1, x_i\in{{0,1}}
$$

其中,p_i表示X属于各类别的概率,x是用one_hot向量表示的类别。

现在假设分类器输出了一组预测概率:

$$
y_{pred} = (p_1, p_2, …, p_k)
$$

我们想知道:如果以这组概率为多项分布的参数,观测到对应y_true的概率是多少。如果观测到y_true的概率大,表示模型预测的精准。这就是似然函数:

将其取对数进行化简,得到对数似然函数:

$$
L(y_{true}| y_{pred}) = \prod_{i=1}^{K}y_{pred}(i)^{y_{true}(i)}
$$

通常机器学习都是最小化损失函数的,所以我们给 加上负号,变成负对数似然。最小化负对数似然等价于最大化似然函数,即交叉熵:

$$
CrossEntropy(y_{true}, y_{pred}) =-log(L)= - \sum_{i=1}^{K}{y_{true}(i)log(y_{pred}(i))}
$$

不适合用交叉熵的情况

多数情况下,分类任务的标签y_true全是one_hot向量,此时交叉熵和相对熵等价,而交叉熵的计算更简单,使用交叉熵作为损失函数。然而,有一些情况需要谨慎使用。

不平衡的标签平滑

如果 使用了标签平滑,例如 (0.0, 0.0, 1.0, 0.0) 采用 \lambda=0.1 进行平滑,得到(0.025, 0.025,0.925, 0.025),此时相对熵的第一项,即S(y_true)!=0,交叉熵和相对熵在数值上不再等价。

此时y_true还是一个常数,两个损失函数的求导运算仍然等价,即最小化交叉熵等价于最小化相对熵。若对整个样本集不采用统一的 \lambda,例如,部分样本使用\lambda=0.1,另一部分使用\lambda=0.2的情形,由于包含多套基准,样本损失的数值不再具有可比性,关于它们的任何分析也将失去意义。

连续型概率分布

当y_true涉及到复杂的连续型概率分布,采用相对熵是合适的。此种情况下,两个完全相等的概率分布的交叉熵非0,这一现象可能使你感到困惑。

1
2
3
4
5
6
7
8
>>> import tensorflow.keras as keras
>>> import tensorflow as tf

>>> y_pred = tf.constant([0.1, 0.7, 0.1, 0.1])
>>> y_true = tf.constant([0.1, 0.7, 0.1, 0.1])

>>> keras.losses.categorical_crossentropy(y_true, y_pred).numpy()
0.94044805

采用KL散度,就能得到期望的0。

1
2
>>> keras.losses.kld(y_true, y_pred).numpy()
0.0

最后,当标签分布不是恒定值时,应使用相对熵。