什么是交叉熵? [关闭]

Posted

技术标签:

【中文标题】什么是交叉熵? [关闭]【英文标题】:What is cross-entropy? [closed] 【发布时间】:2017-06-18 19:38:03 【问题描述】:

我知道关于什么是交叉熵有很多解释,但我还是一头雾水。

只是描述损失函数的一种方法吗?我们可以使用梯度下降算法通过损失函数找到最小值吗?

【问题讨论】:

不适合 SO。这是数据科学姐妹网站上的一个类似问题:datascience.stackexchange.com/questions/9302/… 简单的非数学解释,参考towardsdatascience.com/… 【参考方案1】:

交叉熵通常用于量化两个概率分布之间的差异。在机器学习的背景下,它是分类多类分类问题的误差度量。通常,“真实”分布(您的机器学习算法试图匹配的分布)用 one-hot 分布表示。

例如,假设对于特定的训练实例,真正的标签是 B(在可能的标签 A、B 和 C 中)。因此,此训练实例的 one-hot 分布为:

Pr(Class A)  Pr(Class B)  Pr(Class C)
        0.0          1.0          0.0

您可以将上述真实分布解释为训练实例有 0% 的概率为 A 类,100% 的概率为 B 类,0% 的概率为 C 类。

现在,假设您的机器学习算法预测以下概率分布:

Pr(Class A)  Pr(Class B)  Pr(Class C)
      0.228        0.619        0.153

预测分布与真实分布的接近程度如何?这就是交叉熵损失所决定的。使用这个公式:

其中p(x) 是真实概率分布(one-hot),q(x) 是预测概率分布。总和超过了 A、B 和 C 三个类别。在这种情况下,损失为 0.479

H = - (0.0*ln(0.228) + 1.0*ln(0.619) + 0.0*ln(0.153)) = 0.479

对数底

请注意,只要您始终使用相同的对数基数,您使用的对数基数并不重要。碰巧的是,Python Numpy log() 函数计算自然对数(以 e 为底的对数)。

Python 代码

这是上面使用 Numpy 用 Python 表示的示例:

import numpy as np

p = np.array([0, 1, 0])             # True probability (one-hot)
q = np.array([0.228, 0.619, 0.153]) # Predicted probability

cross_entropy_loss = -np.sum(p * np.log(q))
print(cross_entropy_loss)
# 0.47965000629754095

这就是您的预测与真实分布的“错误”或“相距甚远”。机器学习优化器将尝试最小化损失(即,它将尝试将损失从 0.479 减少到 0.0)。

损失单位

我们在上面的例子中看到损失是 0.4797。因为我们使用的是自然对数(以 e 为底的对数),单位为nats,所以我们说损失为 0.4797 nats。如果日志改为以 2 为基数,则单位为位。更多解释见this page。

更多示例

为了更直观地了解这些损失值所反映的内容,让我们看一些极端的例子。

再次假设真正的(单热)分布是:

Pr(Class A)  Pr(Class B)  Pr(Class C)
        0.0          1.0          0.0

现在假设你的机器学习算法做得非常好,并且以非常高的概率预测了 B 类:

Pr(Class A)  Pr(Class B)  Pr(Class C)
      0.001        0.998        0.001

当我们计算交叉熵损失时,我们可以看到损失很小,只有 0.002:

p = np.array([0, 1, 0])
q = np.array([0.001, 0.998, 0.001])
print(-np.sum(p * np.log(q)))
# 0.0020020026706730793

在另一个极端,假设您的 ML 算法做得很糟糕,而是以高概率预测了 C 类。由此产生的 6.91 损失将反映更大的误差。

Pr(Class A)  Pr(Class B)  Pr(Class C)
      0.001        0.001        0.998
p = np.array([0, 1, 0])
q = np.array([0.001, 0.001, 0.998])
print(-np.sum(p * np.log(q)))
# 6.907755278982137

现在,在这两个极端的中间会发生什么?假设您的 ML 算法无法下定决心并以几乎相等的概率预测这三个类别。

Pr(Class A)  Pr(Class B)  Pr(Class C)
      0.333        0.333        0.334

由此产生的损失是 1.10。

p = np.array([0, 1, 0])
q = np.array([0.333, 0.333, 0.334])
print(-np.sum(p * np.log(q)))
# 1.0996127890016931

适应梯度下降

交叉熵是许多可能的损失函数之一(另一种流行的损失函数是 SVM 铰链损失)。这些损失函数通常写为 J(theta),可以在梯度下降中使用,梯度下降是一种迭代算法,可将参数(或系数)移向最优值。在下面的等式中,您可以将J(theta) 替换为H(p, q)。但请注意,您需要先计算H(p, q) 对参数的导数。

所以直接回答你原来的问题:

只是描述损失函数的一种方法吗?

正确的交叉熵描述了两个概率分布之间的损失。它是许多可能的损失函数之一。

然后我们可以使用例如梯度下降算法来找到 最低限度。

是的,交叉熵损失函数可以用作梯度下降的一部分。

延伸阅读:我的一个other answers 与 TensorFlow 相关。

【讨论】:

因此,交叉熵通过每个示例 X 的概率总和来描述损失。 那么,我们是否可以不将误差描述为交叉熵,而是将误差描述为两个向量之间的角度(余弦相似度/角距离)并尝试最小化角度? 显然这不是最好的解决方案,但我只是想知道,理论上,我们是否可以使用cosine (dis)similarity通过角度来描述错误,然后尝试最小化角度。 @Stephen:如果您看一下我给出的示例,p(x) 将是每个类的真实概率列表,即[0.0, 1.0, 0.0。同样,q(x) 是每个类别的预测概率列表,[0.228, 0.619, 0.153]H(p, q) 然后是 - (0 * log(2.28) + 1.0 * log(0.619) + 0 * log(0.153)),结果是 0.479。注意,使用 Python 的 np.log() 函数很常见,它实际上是自然对数;没关系。 @HAr:对于真正标签的 one-hot 编码,我们只关心一个非零类。但是,交叉熵可以比较任意两个概率分布;没有必要其中之一具有 one-hot 概率。【参考方案2】:

简而言之,交叉熵 (CE) 是衡量您的预测值与真实标签之间的距离。

这里的叉指计算两个或多个特征/真实标签(如0、1)之间的熵。

熵这个词本身就是指随机性,所以它的值很大意味着你的预测与真实标签相去甚远。

因此更改权重以减少 CE,从而最终导致预测标签和真实标签之间的差异减少,从而提高准确性。

【讨论】:

【参考方案3】:

除了上述帖子之外,最简单的交叉熵损失形式称为 binary-cross-entropy(用作二元分类的损失函数,例如逻辑回归),而广义版本是categorical-cross-entropy(用作多类分类问题的损失函数,例如神经网络)。

想法保持不变:

    当训练实例的目标标签的模型计算 (softmax) 类概率接近 1 时(例如,用 one-hot-encoding 表示),相应的 CCE 损失会降低到零

    否则它会随着目标类对应的预测概率变小而增加。

下图演示了这个概念(从图中注意到,当y和p都为高或同时为低时,BCE变低,即一致):

交叉熵与计算两个概率分布之间距离的相对熵KL-散度密切相关。例如,在两个离散的pmf之间,它们之间的关系如下图所示:

【讨论】:

以上是关于什么是交叉熵? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow的四种交叉熵

交叉熵与KL散度

交叉熵损失函数

深度学习交叉熵详解

为什么交叉熵可以用于计算代价函数

信息熵,交叉熵,KL散度