当我使用keras的binary_crossentropy
作为loss function(调用tensorflow's sigmoid_cross_entropy时,似乎只在[0, 1]
之间产生损耗值。但是,方程本身
# The logistic loss formula from above is
# x - x * z + log(1 + exp(-x))
# For x < 0, a more numerically stable formula is
# -x * z + log(1 + exp(x))
# Note that these two expressions can be combined into the following:
# max(x, 0) - x * z + log(1 + exp(-abs(x)))
# To allow computing gradients at zero, we define custom versions of max and
# abs functions.
zeros = array_ops.zeros_like(logits, dtype=logits.dtype)
cond = (logits >= zeros)
relu_logits = array_ops.where(cond, logits, zeros)
neg_abs_logits = array_ops.where(cond, -logits, logits)
return math_ops.add(
relu_logits - logits * labels,
math_ops.log1p(math_ops.exp(neg_abs_logits)), name=name)
表示范围从[0, infinity)
开始。那么Tensorflow是否正在执行某种我没有捕捉到的剪裁?而且,由于它正在做math_ops.add()
,所以我肯定会确定它大于1。我是否正确地假设损失范围肯定可以超过1?
答案 0 :(得分:2)
交叉熵函数确实没有向上限制。但是,只有在预测非常错误的情况下,它才会采用较大的值。首先让我们看一下随机初始化的网络的行为。
使用随机权重,许多单元/层通常会复合在一起,从而导致网络输出近似均匀的预测。也就是说,在具有n
类的分类问题中,每个类的概率约为1/n
(在两类情况下为0.5)。在这种情况下,交叉熵将围绕n类均匀分布的熵,在某些假设下log(n)
, (见下文)。
这可以如下所示:单个数据点的交叉熵为-sum(p(k)*log(q(k)))
,其中p
是真实概率(标签),q
是预测,{{1 }}是不同的类,总和超过了这些类。现在,使用硬标签(即一次热编码),只有一个k
为1,所有其他均为0。因此,该术语归结为p(k)
,其中-log(q(k))
现在是正确的类。如果使用随机初始化的网络k
,我们将得到q(k) ~ 1/n
。
我们也可以定义交叉熵的定义,通常为-log(1/n) = log(n)
。如果entropy(p) + kullback-leibler divergence(p,q)
和p
是相同的分布(例如,当我们每个类具有相同数量的示例时,q
是统一的,而对于随机网络,p
则是统一的)那么KL散度变为0,我们就剩下q
。
现在,由于训练目标通常是减少交叉熵,因此我们可以将entropy(p)
视为一种最坏情况的值。如果它变得更高,则您的模型可能存在问题。由于看起来您只有两个类别(0和1)log(n)
,因此您的交叉熵通常会很小。