首页 > 解决方案 > keras 的 binary_crossentropy 损失函数范围

问题描述

当我使用 keras 的binary_crossentropy作为损失函数(调用tensorflow 的 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 是否正确?

标签: pythontensorflowmachine-learningkerasdeep-learning

解决方案


交叉熵函数确实没有上界。但是,如果预测非常错误,它只会采用较大的值。让我们首先看一下随机初始化网络的行为。

使用随机权重,许多单元/层通常会复合以导致网络输出近似一致的预测。也就是说,在具有n类的分类问题中,您将获得每个类的大约概率1/n(在两类情况下为 0.5)。在这种情况下,交叉熵将围绕 n 类均匀分布的熵,即log(n)某些假设下(见下文)。

这可以如下所示:单个数据点的交叉熵是-sum(p(k)*log(q(k)))真实p概率(标签)、q预测、k不同类别以及总和在类别上的位置。现在,对于硬标签(即 one-hot 编码),只有一个p(k)是 1,所有其他都是 0。因此,该术语减少到-log(q(k))现在k是正确类别的位置。如果使用随机初始化的网络q(k) ~ 1/n,我们得到-log(1/n) = log(n).

我们也可以去定义交叉熵,一般是entropy(p) + kullback-leibler divergence(p,q)。如果pq是相同的分布(例如p,当我们对每个类有相同数量的示例时是均匀的,并且q对于随机网络来说是均匀的),那么 KL 散度变为 0,剩下entropy(p)

现在,由于训练目标通常是减少交叉熵,我们可以将其log(n)视为一种最坏情况值。如果它变得更高,则您的模型可能有问题。因为看起来你只有两个类(0 和 1),log(2) < 1所以你的交叉熵通常会很小。


推荐阅读