提问者:小点点

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


分类问题,如逻辑回归或多项式逻辑回归,优化了一个交叉熵损失。通常情况下,交叉熵层跟随softmax层,它会产生概率分布。

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

  • t f.损失。softmax_cross_entropy
  • t f.损失。sparse_softmax_cross_entropy
  • t f.损失。sigmoid_cross_entropy
  • t f. contrib.softmax_cross_entropy
  • t f. contrib.sigmoid_cross_entropy
  • t f. nn.softmax_cross_entropy_with_logits
  • t f. nn.sigmoid_cross_entropy_with_logits

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

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


共3个答案

匿名用户

>

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

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

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

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

    • t f. nn.sigmoid_cross_entropy_with_logits
    • t f. nn.weighted_cross_entropy_with_logits
    • t f.损失。sigmoid_cross_entropy
    • tf. contrib.losses.sigmoid_cross_entropy(已弃用)

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

    标签必须是one-Hot编码的,或者可以包含软类概率。

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

    • tf. nn.softmax_cross_entropy_with_logits(已弃用IN1.5)
    • t f. nn.softmax_cross_entropy_with_logits_v2
    • t f.损失。softmax_cross_entropy
    • tf. contrib.losses.softmax_cross_entropy(已弃用)

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

    标签必须是one-Hot编码的,或者可以包含软类概率:一个特定的例子可以属于50%概率的A类和50%概率的B类。注意,严格来说,这并不意味着它属于两个类,但可以这样解释概率。

    就像sigmoid系列中一样,tf. losses.softmax_cross_entropy允许设置批内权重,即使一些示例比其他示例更重要。据我所知,从TensorFlow 1.3开始,没有内置的方法来设置类权重。

    [UPD]在TensorFlow 1.5中,引入了v2版本,最初的softmax_cross_entropy_with_logits丢失被弃用。它们之间的唯一区别是,在较新的版本中,反向传播同时发生在日志和标签中(以下是为什么这可能有用的讨论)。

    • t f. nn.sparse_softmax_cross_entropy_with_logits
    • t f.损失。sparse_softmax_cross_entropy
    • tf. contrib.losses.sparse_softmax_cross_entropy(已弃用)

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

    与上面一样,tf. loss版本有一个权重参数,允许设置批处理内权重。

    • t f. nn.sampled_softmax_loss
    • t f. contrib.nn.rank_sampled_softmax_loss
    • t f. nn.nce_loss

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

    参数权重偏差指定一个单独的全连接层,用于计算所选样本的对数。

    和上面一样,标签不是one-Hot编码的,而是具有[batch_sizenum_true]的形状。

    采样函数只适合训练。在测试时,建议使用标准的softmax损失(稀疏或one-Hot)来获得实际分布。

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

  • 匿名用户

    但是,对于1.5版,必须使用softmax_cross_entropy_with_logits_v2,同时使用它的参数和参数键=…,例如

    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。我们假设期望值是one-hotded(100或010或001)。如果(出于某种奇怪的原因),情况并非如此,期望值是整数(1或2或3),您可以使用上述函数的“稀疏”对应项。

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

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