为什么在TF2.0中使用梯度带对分类交叉熵损失相对于logit的梯度为0?

时间:2019-09-11 15:34:53

标签: tensorflow gradient

我正在学习Tensorflow 2.0,并且试图弄清楚Gradient Tapes如何工作。我有一个简单的示例,其中,我评估了logit和标签之间的交叉熵损失。我想知道为什么逻辑对数的梯度为零。 (请查看下面的代码)。 TF的版本是tensorflow-gpu == 2.0.0-rc0。

logits = tf.Variable([[1, 0, 0], [1, 0, 0], [1, 0, 0]], type=tf.float32)
labels = tf.constant([[1, 0, 0], [0, 1, 0], [0, 0, 1]],dtype=tf.float32)
with tf.GradientTape(persistent=True) as tape:
    loss = tf.reduce_sum(tf.losses.categorical_crossentropy(labels, logits))

grads = tape.gradient(loss, logits)
print(grads)

我得到了

 tf.Tensor(
[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]], shape=(3, 3), dtype=float32)

因此,但是它不应该告诉我应该更改多少logit以最大程度地减少损失吗?

1 个答案:

答案 0 :(得分:0)

计算交叉熵损失时,请在from_logits=True中设置tf.losses.categorical_crossentropy()。默认情况下,它为false,这意味着您可以直接使用-p*log(q)计算交叉熵损失。通过设置from_logits=True,您正在使用-p*log(softmax(q))计算损失。

更新:

只需找到一个有趣的结果。

logits = tf.Variable([[0.8, 0.1, 0.1]], dtype=tf.float32)
labels = tf.constant([[1, 0, 0]],dtype=tf.float32)

with tf.GradientTape(persistent=True) as tape:
    loss = tf.reduce_sum(tf.keras.losses.categorical_crossentropy(labels, logits, from_logits=False))

grads = tape.gradient(loss, logits)
print(grads)

毕业生将是tf.Tensor([[-0.25 1. 1. ]], shape=(1, 3), dtype=float32)

以前,我认为张量流将使用loss=-\Sigma_i(p_i)\log(q_i)来计算损失,如果我们从q_i推导,我们将得到导数为-p_i/q_i。因此,预期的毕业人数应为[-1.25, 0, 0]。但是输出等级看起来好像都增加了1。但这不会影响优化过程。

就目前而言,我仍在努力弄清为什么将研究生人数增加一。阅读tf.categorical_crossentropy的源代码后,我发现即使我们设置了from_logits=False,它仍然可以归一化概率。那将改变最终的梯度表达式。具体来说,渐变将为-p_i/q_i+p_i/sum_j(q_j)。如果p_i=1sum_j(q_j)=1,则最终渐变将加1。这就是为什么渐变将为-0.25的原因,但是我还没有弄清楚为什么最后两个渐变将为1.

要证明所有梯度都增加了1/sum_j(q_j)

logits = tf.Variable([[0.5, 0.1, 0.1]], dtype=tf.float32)
labels = tf.constant([[1, 0, 0]],dtype=tf.float32)

with tf.GradientTape(persistent=True) as tape:
    loss = tf.reduce_sum(tf.keras.losses.categorical_crossentropy(labels, logits, from_logits=False))

grads = tape.gradient(loss, logits)
print(grads)

应届毕业生为tf.Tensor([[-0.57142866 1.4285713 1.4285713 ]],应为[-2,0,0]

它表明所有梯度都增加了1/(0.5+0.1+0.1)。对于p_i==1,增加1/(0.5+0.1+0.1)的渐变对我来说很有意义。但是我不明白为什么p_i==0的梯度仍会增加1/(0.5+0.1+0.1)