繁体   English   中英

如何在 TensorFlow 中选择交叉熵损失?

[英]How to choose cross-entropy loss in TensorFlow?

分类问题,例如逻辑回归或多项逻辑回归,可以优化交叉熵损失。 通常情况下,交叉熵层跟在softmax层之后,产生概率分布。

在 tensorflow 中,至少有十几种不同的交叉熵损失函数

  • tf.losses.softmax_cross_entropy
  • tf.losses.sparse_softmax_cross_entropy
  • tf.losses.sigmoid_cross_entropy
  • tf.contrib.losses.softmax_cross_entropy
  • tf.contrib.losses.sigmoid_cross_entropy
  • tf.nn.softmax_cross_entropy_with_logits
  • tf.nn.sigmoid_cross_entropy_with_logits
  • ...

哪一个只适用于二元分类,哪一个适用于多类问题? 什么时候应该使用sigmoid而不是softmax sparse函数与其他函数有何不同,为什么只有softmax

相关(更面向数学)讨论: Keras 和 TensorFlow 中所有这些交叉熵损失之间有什么区别? .

初步事实

  • 在函数意义上, sigmoid 是 softmax 函数 的部分情况,当类数等于 2 时。它们都执行相同的操作:将 logits(见下文)转换为概率。

    在简单的二元分类中,两者之间没有太大区别,但是在多项分类的情况下,sigmoid 允许处理非排他标签(又名multi-labels ),而 softmax 处理排他类(见下文)。

  • logit (也称为分数)是在计算概率之前与 class 关联原始未缩放值 就神经网络架构而言,这意味着 logit 是密集(全连接)层的输出。

    Tensorflow 命名有点奇怪:下面的所有函数都接受 logits,而不是 probabilities ,并自己应用转换(这只是更有效)。

Sigmoid 函数族

如前所述, sigmoid损失函数用于二元分类。 但是当类别独立时,张量流函数更通用并且允许进行多标签分类。 换句话说, tf.nn.sigmoid_cross_entropy_with_logits一次解决了N二元分类。

标签必须是单热编码或可以包含软类概率。

tf.losses.sigmoid_cross_entropy还允许设置批内权重,即使某些示例比其他示例更重要。 tf.nn.weighted_cross_entropy_with_logits允许设置类权重(记住,分类是二进制的),即使正误差大于负误差。 这在训练数据不平衡时很有用。

Softmax 函数族

这些损失函数应该用于多项互斥分类,即从N类中挑选一个。 N = 2时也适用。

标签必须是单热编码或可以包含软类概率:特定示例可以 50% 的概率属于 A 类,50% 的概率属于 B 类。 请注意,严格来说,这并不意味着它属于两个类别,但可以这样解释概率。

就像在sigmoid家族中一样, tf.losses.softmax_cross_entropy允许设置批内权重,即让一些例子比其他例子更重要。 据我所知,从 tensorflow 1.3 开始,没有设置类权重的内置方法。

[UPD]在 tensorflow 1.5 中, 引入v2版本并且不推荐使用原始的softmax_cross_entropy_with_logits损失。 它们之间的唯一区别是,在较新的版本中,反向传播发生在 logits 和标签中(这是为什么这可能有用的讨论)。

稀疏函数族

和上面普通的softmax一样,这些损失函数应该用于多项互斥分类,即从N类中挑一个。 区别在于标签编码:类被指定为整数(类索引),而不是单热向量。 显然,这不允许软类,但是当有数千或数百万个类时,它可以节省一些内存。 但是,请注意logits参数仍然必须包含每个类的 logits,因此它至少消耗[batch_size, classes]内存。

像上面一样, tf.losses版本有一个weights参数,它允许设置批量权重。

采样的 softmax 函数族

这些函数为处理大量类提供了另一种选择。 他们不是计算和比较精确的概率分布,而是从随机样本中计算损失估计。

的参数weightsbiases指定一个用于计算一个选择的采样的logits单独的完全连接的层。

像上面一样, labels不是单热编码,而是具有形状[batch_size, num_true]

采样函数仅适用于训练。 在测试时,建议使用标准的softmax损失(稀疏或单热)来获得实际分布。

另一种替代损失是tf.nn.nce_loss ,它执行噪声对比估计(如果您有兴趣,请参阅此非常详细的讨论)。 我已将此函数包含在 softmax 系列中,因为 NCE 保证在极限内逼近 softmax。

但是,对于 1.5 版,必须改用softmax_cross_entropy_with_logits_v2 ,同时将其参数与argument key=... ,例如

softmax_cross_entropy_with_logits_v2(_sentinel=None, labels=y,
                                    logits=my_prediction, dim=-1, name=None)

虽然接受的答案包含的信息比所问的要多得多,但我觉得分享一些通用的拇指规则将使答案更加紧凑和直观:

  • 只有一个真正的损失函数。 这是交叉熵(CE) 对于二元分类的特殊情况,这种损失称为二元 CE (注意公式不变),对于非二元或多类情况,也称为分类 CE (CCE) 稀疏函数是分类 CE 的一种特殊情况,其中预期值不是单热编码而是整数
  • 我们有softmax公式,它是多类场景的激活。 对于二元场景,相同的公式被赋予一个特殊的名称——sigmoid激活
  • 因为在处理对数函数时有时会出现数值不稳定性(对于极值),TF 建议将激活层和损失层合并为一个函数。 这种组合函数在数值上更稳定。 TF 提供了这些组合函数,它们都以_with_logits为后缀

有了这个,让我们现在处理一些情况。 假设有一个简单的二元分类问题- 图像中是否存在猫? 激活函数和损失函数的选择是什么? 这将是一个 sigmoid 激活和一个(二进制)CE。 所以可以使用sigmoid_cross_entropy或更优选sigmoid_cross_entropy_with_logits 后者结合了激活函数和损失函数,应该是数值稳定的。

多类分类怎么样。 假设我们想知道图像中是否存在猫、狗或驴。 激活函数和损失函数的选择是什么? 这将是一个 softmax 激活和一个(分类)CE。 所以可以使用softmax_cross_entropy或更优选softmax_cross_entropy_with_logits 我们假设预期值是单热编码(100 或 010 或 001)。 如果(出于某种奇怪的原因),情况并非如此,并且预期值为整数(1 或 2 或 3),则您可以使用上述函数的“稀疏”对应项。

可能还有第三种情况。 我们可以有一个多标签分类 因此,同一图像中可能有一只狗一只猫。 我们如何处理? 这里的技巧是将这种情况视为多重二元分类问题 - 基本上是猫或没有猫/狗或没有狗和驴或没有驴。 找出这 3 个(二元分类)中每一个的损失,然后将它们相加。 所以基本上这归结为使用sigmoid_cross_entropy_with_logits损失。

这回答了您提出的 3 个具体问题。 上面共享的功能是所有需要的。 您可以忽略已弃用且不应使用的 tf.contrib 系列。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM