分类问题,例如逻辑回归或多项逻辑回归,可以优化损失 . 通常,交叉熵层遵循 softmax 层,这产生概率分布 .
在tensorflow中,至少有一个 dozen of different cross-entropy loss functions :
-
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
?
相关(更多以数学为导向)的讨论:cross-entropy jungle .
2 回答
初步事实
在简单的二进制分类中,两者之间没有太大的区别,但是在多项分类的情况下,sigmoid允许处理非独占标签(例如多标签),而softmax处理独占类(见下文) .
Tensorflow命名有点奇怪: all of the functions below accept logits, not probabilities ,并自己应用转换(这样效率更高) .
Sigmoid函数族
tf.nn.sigmoid_cross_entropy_with_logits
tf.nn.weighted_cross_entropy_with_logits
tf.losses.sigmoid_cross_entropy
tf.contrib.losses.sigmoid_cross_entropy(已弃用)
如前所述,
sigmoid
损失函数用于二进制分类 . 但是,当类是独立的时,tensorflow函数更通用,并允许进行多标签分类 . 换句话说,tf.nn.sigmoid_cross_entropy_with_logits
一次解决N
二进制分类 .标签必须是单热编码的,或者可以包含软类概率 .
tf.losses.sigmoid_cross_entropy
另外允许设置批内重量,即使一些例子比其他例子更重要 .tf.nn.weighted_cross_entropy_with_logits
允许设置类权重(记住,分类是二进制的),即使正误差大于负误差 . 当训练数据不 balancer 时,这很有用 .Softmax功能系列
tf.nn.softmax_cross_entropy_with_logits(已弃用1.5)
tf.nn.softmax_cross_entropy_with_logits_v2
tf.losses.softmax_cross_entropy
tf.contrib.losses.softmax_cross_entropy(已弃用)
这些损失函数应该用于多项互斥分类,即从
N
类中选择一个 . 适用于N = 2
时 .标签必须是单热编码的或者可以包含软类概率:特定示例可以属于具有50%概率的A类和具有50%概率的B类 . 请注意,严格来说,这并不意味着它属于这两个类,但可以用这种方式解释概率 .
就像
sigmoid
系列一样,tf.losses.softmax_cross_entropy
允许设置批内重量,即使一些例子比其他例子更重要 . 据我所知,从tensorflow 1.3开始,没有内置的方法来设置类权重 .[UPD] 在tensorflow 1.5中,
v2
版本was introduced和原始softmax_cross_entropy_with_logits
损失已弃用 . 它们之间的唯一区别在于,在较新版本中,反向传播发生在logits和标签中(here's a discussion为什么这可能有用) .稀疏函数族
tf.nn.sparse_softmax_cross_entropy_with_logits
tf.losses.sparse_softmax_cross_entropy
tf.contrib.losses.sparse_softmax_cross_entropy(已弃用)
与上面的普通
softmax
一样,这些损失函数应该用于多项互斥分类,即从N
类中选择一个 . 不同之处在于标签编码:类被指定为整数(类索引),而不是单热矢量 . 显然,这不允许软类,但是当有数千或数百万个类时它可以节省一些内存 . 但是,请注意logits
参数必须仍然包含每个类的logits,因此它至少消耗[batch_size, classes]
内存 .如上所述,
tf.losses
版本具有weights
参数,允许设置批内重量 .采样softmax函数系列
tf.nn.sampled_softmax_loss
tf.contrib.nn.rank_sampled_softmax_loss
tf.nn.nce_loss
这些函数为处理大量类提供了另一种选择 . 他们不是计算和比较精确的概率分布,而是根据随机样本计算损失估计 .
参数
weights
和biases
指定一个单独的完全连接层,用于计算所选样本的logits .如上所述,
labels
不是单热编码,但具有[batch_size, num_true]
形状 .采样功能仅适用于培训 . 在测试时间内,建议使用标准的
softmax
损失(稀疏或单热)来获得实际分布 .另一种替代损失是
tf.nn.nce_loss
,它执行噪声对比估计(如果您有兴趣,请参见very detailed discussion) . 我已将此函数包含在softmax系列中,因为NCE保证近似softmax在极限 .但是对于版本1.5,必须使用
softmax_cross_entropy_with_logits_v2
,而将其参数与argument key=...
一起使用,如下面的>