计算TensorFlow中的交叉熵

时间:2017-03-01 00:58:23

标签: python machine-learning tensorflow cross-entropy

我很难计算张量流中的交叉熵。特别是,我正在使用函数:

tf.nn.softmax_cross_entropy_with_logits()

使用看似简单的代码,我只能让它返回零

import tensorflow as tf
import numpy as np

sess = tf.InteractiveSession()

a = tf.placeholder(tf.float32, shape =[None, 1])
b = tf.placeholder(tf.float32, shape = [None, 1])
sess.run(tf.global_variables_initializer())
c = tf.nn.softmax_cross_entropy_with_logits(
    logits=b, labels=a
).eval(feed_dict={b:np.array([[0.45]]), a:np.array([[0.2]])})
print c

返回

0

我对交叉熵的理解如下:

H(p,q) = p(x)*log(q(x))

其中p(x)是事件x的真实概率,q(x)是事件x的预测概率。

如果输入p(x)和q(x)的任何两个数字,则使用

0<p(x)<1 AND 0<q(x)<1

应该存在非零交叉熵。我期待我正在使用tensorflow错误。提前感谢您的帮助。

3 个答案:

答案 0 :(得分:15)

除了Don的回答(+1)之外,this answer written by mrry可能会让您感兴趣,因为它给出了计算TensorFlow中交叉熵的公式:

  

另一种写作方式:

xent = tf.nn.softmax_cross_entropy_with_logits(logits, labels)
     

......将是:

softmax = tf.nn.softmax(logits)
xent = -tf.reduce_sum(labels * tf.log(softmax), 1)
     

然而,这种替代方案将是(i)数值较少稳定(因为   softmax可以计算更大的值)和(ii)效率更低   (因为一些冗余计算会在backprop中发生)。对于   实际使用,我们建议您使用   tf.nn.softmax_cross_entropy_with_logits()

答案 1 :(得分:11)

就像他们说的那样,如果没有“softmax”,就不能拼写“softmax_cross_entropy_with_logits”。 [0.45]的Softmax为[1]log(1)0

  

测量离散分类任务中的概率误差   类是互斥的(每个条目只有一个类)。对于   例如,每个CIFAR-10图像都标有一个且只有一个标签:图像   可以是狗或卡车,但不是两者。

     

注意:虽然这些类是相互排斥的,但它们的概率   不必是。所需要的只是labels的每一行都是。labels   有效的概率分布。如果他们不是,计算的   渐变是不正确的。

     

如果使用独占sparse_softmax_cross_entropy_with_logits(其中一个且仅限一个   一个类一次是真的,见softmax

     

警告:此操作需要未缩放的日志记录,因为它执行logits   在softmax内部提高效率。不要把这个叫做   输出logits,因为它会产生不正确的结果。

     

labels[batch_size, num_classes]必须具有相同的形状float16   和相同的dtype(float32float64 NSWorkspace.shared().notificationCenter.addObserver(self, selector: #selector(sessionResignActive(_:)), name: NSNotification.Name.NSWorkspaceSessionDidResignActive, object: nil) NSWorkspace.shared().notificationCenter.addObserver(self, selector: #selector(sessionBecomeActive(_:)), name: NSNotification.Name.NSWorkspaceSessionDidBecomeActive, object: nil) )。

答案 2 :(得分:0)

这里是Tensorflow 2.0中的一个实现,以防将来有人(可能是我)需要它。

@tf.function
def cross_entropy(x, y, epsilon = 1e-9):
    return -2 * tf.reduce_mean(y * tf.math.log(x + epsilon), -1) / tf.math.log(2.)

x = tf.constant([
    [1.0,0],
    [0.5,0.5],
    [.75,.25]
    ]
,dtype=tf.float32)

with tf.GradientTape() as tape:
    tape.watch(x)
    y = entropy(x, x)

tf.print(y)
tf.print(tape.gradient(y, x))

输出

[-0 1 0.811278105]
[[-1.44269502 29.8973541]
 [-0.442695022 -0.442695022]
 [-1.02765751 0.557305]]