我很难计算张量流中的交叉熵。特别是,我正在使用函数:
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错误。提前感谢您的帮助。
答案 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(float32
,float64
或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]]