【问题标题】:How does the categorical cross entropy function work in Tensorflow?分类交叉熵函数在 Tensorflow 中如何工作?
【发布时间】:2021-06-25 06:08:30
【问题描述】:

我想在 Tensorflow 中手动实现分类交叉熵函数。我做到了:

def my_CE(y_true, y_pred):
    log_y_pred = tf.math.log(y_pred)
    element_wise = -tf.math.multiply_no_nan(x=log_y_pred, y=y_true)
    return tf.reduce_mean(tf.reduce_sum(element_wise,axis=1))

通过测试,我意识到我做对了:

true = np.array([[0.0, 1.0], [1.0, 0.0]])
pred = np.array([[0.01, 0.99], [0.01, 0.99]])

print('Tensorflow CE : ',tf.keras.losses.CategoricalCrossentropy()(true, pred))
print('My CE : ',my_CE(true, pred))



*Tensorflow CE :  tf.Tensor(2.307610273361206, shape=(), dtype=float64)
My CE :  tf.Tensor(2.307610260920796, shape=(), dtype=float64)*

但在另一个测试中,我发现答案不同:

y_true = tf.constant([[0 , 0 , 0 , 0 , 1.0]])
y_pred = tf.constant([[0 , 0 , 0 ,0 ,  .3]])

print('Tensorflow CE : ',tf.keras.losses.CategoricalCrossentropy()(y_true, y_pred).numpy())
print('My CE : ',my_CE(y_true, y_pred).numpy())


Tensorflow CE :  1.192093e-07
My CE :  1.2039728

更糟糕的是,我意识到 tensorflow 函数在我的理解中不起作用! 也就是随着我增加类正确的概率,不亚于tensorflow损失函数的值

for i in np.arange(.1,1,0.1):
    y_true = tf.constant([[0 , 0 , 0 , 0 , 1.0]])
    y_pred = tf.constant([[0 , 0 , 0 ,0 ,  i]])
    print('Tensorflow CE : ',tf.keras.losses.CategoricalCrossentropy()(y_true, y_pred).numpy())

Tensorflow CE :  1.192093e-07
Tensorflow CE :  1.192093e-07
Tensorflow CE :  1.192093e-07
Tensorflow CE :  1.192093e-07
Tensorflow CE :  1.192093e-07
Tensorflow CE :  1.192093e-07
Tensorflow CE :  1.192093e-07
Tensorflow CE :  1.192093e-07
Tensorflow CE :  1.192093e-07

【问题讨论】:

  • 您可能会在CategoricalCrossentropy 中看到reduction= 参数。见tf.keras.losses.Reduction
  • @ShubhamPanchal 谢谢,但我以某种方式检查了这个问题。我的基本问题是为什么增加或减少正确类别的概率不会影响张量流损失函数。
  • 您传递的 y_pred 总和不等于 1。您需要对 y_pred 进行 softmax 或将 from_logits 设置为 True。摆姿势前请阅读tensorflow documentation
  • @gobrewers14 感谢您的回答。我的问题解决了。

标签: python tensorflow loss-function


【解决方案1】:

来自 cmets

您传递的 y_pred 不等于 1。你需要要么 softmax 您的 y_pred 或将 from_logits 设置为 True。更多 您可以阅读的信息 here。 (转述自 gobrewers14)

import tensorflow as tf
import numpy as np

def my_CE(y_true, y_pred):
    log_y_pred = tf.math.log(y_pred)
    element_wise = -tf.math.multiply_no_nan(x=log_y_pred, y=y_true)
    return tf.reduce_mean(tf.reduce_sum(element_wise,axis=1))

# y_pred sum to 1
y_true = tf.constant([[0 , 0 , 0 , 0 , 1.0]])
y_pred = tf.constant([[0 , 0.7 , 0 ,0 ,  .3]])

print('Tensorflow CE : ',tf.keras.losses.CategoricalCrossentropy()(y_true, y_pred).numpy())
print('My CE : ',my_CE(y_true, y_pred).numpy())

输出:

Tensorflow CE :  1.2039728
My CE :  1.2039728
#softmax y_pred 
y_true = tf.constant([[0 , 0 , 0 , 0 , 1.0]])
y_pred = tf.nn.softmax(tf.constant([[0 , 0.0 , 0 ,0 ,  .3]]))

print('Tensorflow CE : ',tf.keras.losses.CategoricalCrossentropy()(y_true, y_pred).numpy())
print('My CE : ',my_CE(y_true, y_pred).numpy())

输出:

Tensorflow CE :  1.3770702
My CE :  1.3770702

【讨论】:

    猜你喜欢
    • 2019-05-23
    • 1970-01-01
    • 2019-07-13
    • 2020-01-03
    • 2017-07-20
    • 2017-11-11
    • 2021-07-17
    • 1970-01-01
    • 2020-09-10
    相关资源
    最近更新 更多