如何选择张量流中的交叉熵损失?

时间:2017-10-31 11:59:50

标签: machine-learning tensorflow neural-network logistic-regression cross-entropy

分类问题,例如逻辑回归或多项式 逻辑回归,优化交叉熵损失。 通常,交叉熵层遵循 softmax 层, 它产生概率分布。

在张量流中,至少存在<十几种不同的交叉熵损失函数:

  • 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代替softmaxsparse的功能与其他功能有何不同?为什么只有softmax

相关(更多以数学为导向)的讨论:cross-entropy jungle

3 个答案:

答案 0 :(得分:105)

初步事实

  • 在功能意义上,sigmoid is a partial case of the softmax function,当类的数量等于2.它们都执行相同的操作:将logits(见下文)转换为概率。

    在简单的二元分类中,两者之间没有太大的区别, 但是在多项分类的情况下,sigmoid允许处理 使用非独家标签(a.k.a。多标签),而softmax交易 有专属课程(见下文)。

  • 在计算概率之前, logit (也称为分数)是raw unscaled value associated with a class。就神经网络架构而言,这意味着logit是密集(完全连接)层的输出。

    Tensorflow命名有点奇怪:以下所有函数都接受logits,而不是概率,并自行应用转换(效率更高)。

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

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

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

[UPD] 在张量流1.5中,v2版本was introduced和原始softmax_cross_entropy_with_logits丢失已弃用。它们之间的唯一区别是,在较新的版本中,反向传播发生在logits和标签中(here's a discussion为什么这可能有用)。

稀疏函数族

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

如上所述,tf.losses版本有一个允许的weights参数 设置批内重量。

采样softmax函数族

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

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

如上所述,labels不是单热编码,但形状为[batch_size, num_true]

示例功能仅适用于培训。在测试时间内,建议使用 使用标准softmax损失(稀疏或单热)来获得实际分布。

另一个替代损失是tf.nn.nce_loss,执行噪音对比估算(如果您有兴趣,请参阅此very detailed discussion)。我已将此功能包含在softmax系列中,因为NCE保证在极限范围内逼近softmax。

答案 1 :(得分:5)

但是对于版本1.5,必须使用softmax_cross_entropy_with_logits_v2,而使用argument key=...的参数,如下面的&gt;

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

答案 2 :(得分:1)

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

  • 只有一个真正的损失函数。这就是交叉熵 (CE)。对于二元分类的特殊情况,这种损失称为二元CE(注意公式不变),对于非二元分类或多类情况同样被称为categorical 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 系列。