from_logits=True 但损失为 0
Posted
技术标签:
【中文标题】from_logits=True 但损失为 0【英文标题】:from_logits=True but loss is 0 【发布时间】:2021-06-30 15:24:25 【问题描述】:我正在学习 tensorflow,并希望将 tensorflow 实现与数学联系起来。
据我所知,数学交叉熵要求其输入之和为 1。在以下代码中,y_true
是有效输入,而 y_pred
不是数学有效输入:
y_true = [[0, 1]]
y_pred = [[1.0, 20.0]]
print(tf.keras.losses.CategoricalCrossentropy(from_logits=False).call(y_true, y_pred))
print(tf.keras.losses.CategoricalCrossentropy(from_logits=True).call(y_true, y_pred))
给予:
tf.Tensor([0.04879016], shape=(1,), dtype=float32)
tf.Tensor([0.], shape=(1,), dtype=float32)
请找到要点here。
This answer 说:
如果from_logits=False,表示输入是概率
This answer 说:
from_logits=True
表示crossEntropy层的输入正常 张量/logits
This answer 说:
"上面代码中
raw_predictions
的另一个名字是logit
from_logits
,我猜,意思是输入是raw_predictions
。
由于我输入的不是概率,所以我设置了from_logits=True
,但我得到的结果是0。
谁能解释一下?
【问题讨论】:
【参考方案1】:标签 [[0, 1]]
和 logits [[1, 20]]
之间的交叉熵应该是一个非常接近于 0 的值(由于浮点不精确,某些输出可能将其表示为零)。以概率表示,这些 logits 大约为 [[0.000000005, 1]]
。请注意这些概率与标签的接近程度。因此交叉熵应该非常低。
正如 OP 在他们的问题中指出的那样,from_logits=True
在未缩放的输出上运行时应该使用。实际上,from_logits=True
用于在输出 before softmax 上进行操作。 Softmax 将未缩放的输出映射到概率。要计算这些概率的交叉熵,应该使用from_logits=False
。
这是一个例子:
import tensorflow as tf
y_true = tf.convert_to_tensor([[0, 1]], "float32")
y_pred = tf.convert_to_tensor([[1, 20]], "float32")
ce_logits_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
ce_probs_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=False)
print(ce_logits_fn(y_true, y_pred))
# tf.Tensor(0.0, shape=(), dtype=float32)
print(ce_probs_fn(y_true, tf.nn.softmax(y_pred)))
# tf.Tensor(1.1920929e-07, shape=(), dtype=float32)
尝试更紧密地预测。在上面的例子中,正确类的值远高于错误类的值,所以交叉熵会很低。
import tensorflow as tf
y_true = tf.convert_to_tensor([[0, 1]], "float32")
y_pred = tf.convert_to_tensor([[5, 7]], "float32")
ce_logits_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
ce_probs_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=False)
print(ce_logits_fn(y_true, y_pred))
# tf.Tensor(0.12692805, shape=(), dtype=float32)
print(ce_probs_fn(y_true, tf.nn.softmax(y_pred)))
# tf.Tensor(0.126928, shape=(), dtype=float32)
【讨论】:
这说明了很多,谢谢!我发现ce_logits_fn(y_true, tf.nn.softmax(y_pred))
输出不同的结果。我猜softmax的softmax不是幂等的。如果输入恰好是 [0.1,0.9],我应该设置from_logits=True
吗?我是否应该检查每个输入,如果任何输入看起来不像概率,我假设输入没有通过 softmax?
好吧,我真正关心的是可以一直打开from_logits=True
吗?如果我的模型已经有一个 softmax 层,保持from_logits=True
会影响训练吗?
因为你的模型给出了概率,你应该使用from_logits=False
。 tf.keras
的较新版本(不确定从何时开始)将隐含 use the logits if they are available。有趣的一点是,概率的 softmax 不会返回相同的值......我很想知道为什么。
如果您在概率上使用from_logits=True
,那么您的损失将是错误的,您的模型将无法正确学习。以上是关于from_logits=True 但损失为 0的主要内容,如果未能解决你的问题,请参考以下文章