在使用tf.nn.weighted_cross_entropy_with_logits()
之前,是否有必要使用tf.nn.softmax()来获取logmax的softmax?
我在不平衡集上进行二元分类,并将pos_weight
值设置为[1.0,15.0],以补偿后一类在数据中的代表性不足。
其他类似的操作tf.nn.softmax_cross_entropy_with_logits()
明确表示不事先使用softmax,但加权版本未指定。无论是否使用,我都尝试过,当我在模型没有学习之前使用softmax时(例如AUC收敛到0.500
)。
我模型中的最后一层是在[batch_size, 2]
张量上使用洗脱激活。对于第一个类,我的标签被编码为[1, 0]
,而对于第二个类,我的标签被编码为[0, 1]
。
答案 0 :(得分:2)
在使用tf.nn.weighted_cross_entropy_with_logits()之前,是否有必要使用tf.nn.softmax()来获取logmax的softmax?
你不应该因为weighted_cross_entropy_with_logits
将sigmoid应用于目标。
您可以在code:
中看到def weighted_cross_entropy_with_logits(targets, logits, pos_weight, name=None):
"""Computes a weighted cross entropy.
For brevity, let `x = logits`, `z = targets`, `q = pos_weight`.
The loss is:
qz * -log(sigmoid(x)) + (1 - z) * -log(1 - sigmoid(x))
= qz * -log(1 / (1 + exp(-x))) + (1 - z) * -log(exp(-x) / (1 + exp(-x)))
= qz * log(1 + exp(-x)) + (1 - z) * (-log(exp(-x)) + log(1 + exp(-x)))
= qz * log(1 + exp(-x)) + (1 - z) * (x + log(1 + exp(-x))
= (1 - z) * x + (qz + 1 - z) * log(1 + exp(-x))
= (1 - z) * x + (1 + (q - 1) * z) * log(1 + exp(-x))
Setting `l = (1 + (q - 1) * z)`, to ensure stability and avoid overflow,
the implementation uses
(1 - z) * x + l * (log(1 + exp(-abs(x))) + max(-x, 0))
"""
# The logistic loss formula from above is
# (1 - z) * x + (1 + (q - 1) * z) * log(1 + exp(-x))
# For x < 0, a more numerically stable formula is
# (1 - z) * x + (1 + (q - 1) * z) * log(1 + exp(x)) - l * x
# To avoid branching, we use the combined version
# (1 - z) * x + l * (log(1 + exp(-abs(x))) + max(-x, 0))
log_weight = 1 + (pos_weight - 1) * targets
return math_ops.add(
(1 - targets) * logits,
log_weight * (math_ops.log1p(math_ops.exp(-math_ops.abs(logits))) +
nn_ops.relu(-logits)),
name=name)