python - 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 是否正确?
解决方案
交叉熵函数确实没有上界。但是,如果预测非常错误,它只会采用较大的值。让我们首先看一下随机初始化网络的行为。
使用随机权重,许多单元/层通常会复合以导致网络输出近似一致的预测。也就是说,在具有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)
。如果p
和q
是相同的分布(例如p
,当我们对每个类有相同数量的示例时是均匀的,并且q
对于随机网络来说是均匀的),那么 KL 散度变为 0,剩下entropy(p)
。
现在,由于训练目标通常是减少交叉熵,我们可以将其log(n)
视为一种最坏情况值。如果它变得更高,则您的模型可能有问题。因为看起来你只有两个类(0 和 1),log(2) < 1
所以你的交叉熵通常会很小。
推荐阅读
- sql - 使用 SQL 比较 2 个 url 主机名
- javascript - 在 Gatsby 中使用链接标签将样式注入 DOM
- python - Python Openpyxl:如何停止推理或覆盖单元格数据类型
- android - 如何使用设计略有不同的相同自定义视图?
- vba - VBA 将行数据移动到其相关工作表,但如果发现重复行,则跳过该行
- javascript - 获取参数并将其用作 Javascript 中的数组名称
- django - Django sum 对象过滤另一个模型
- javascript - 为什么我不能从 jsp 中的嵌入文件执行代码?
- sql-server - 在 Microsoft SQL Server 上加载图像文件
- system-verilog - 对不同的地址范围使用隐含运算符