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

问题描述

初步事实

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

Tensorflow的命名有点奇怪: ,并且自己应用转换(这更高效)。

tf.nn.sigmoid_cross_entropy_with_logits

如前所述,sigmoid损失函数用于二进制分类。但是tensorflow函数更通用,并且当类是独立的时允许进行多标签分类。换句话说,立即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开始,还没有内置的方法来设置 类权重

在tensorflow 1.5中引入v2版本并且原来的softmax_cross_entropy_with_logits损失已被弃用。它们之间的唯一区别是,在较新的版本中,反向传播同时发生在logit和标签中(这里讨论了为什么这样做可能有用)。

稀疏函数

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

像上面一样,tf.lossesversion具有weights允许设置批内权重的参数。

采样的softmax函数系列

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

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

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

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

另一个替代损耗是tf.nn.nce_loss,它执行 噪声对比估计 (如果您有兴趣,请参阅此非常详细的讨论)。我已将此功能包括在softmax系列中,因为NCE保证极限值近似于softmax。

解决方法

分类问题(例如逻辑回归或多项式逻辑回归)可优化 交叉熵 损失。通常,交叉熵层跟随 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代替使用softmax?如何在sparse功能与别人不同,为什么仅是它softmax

猜你在找的技术问答相关文章

如何检查配对的蓝牙设备是打印机还是扫描仪(Android)
是否允许实体正文进行HTTP DELETE请求?
如何将ZipInputStream转换为InputStream?
java.util.logging Java 8中的变量
PowerMockito.doReturn返回null
Java中的RESTful调用
Swing / Java:如何正确使用getText和setText字符串
特殊字符和重音字符
Android Studio中的ndk.dir错误
错误“找不到主类”