machine-learning - TensorFlow 中 sigmoid 后跟交叉熵和 sigmoid_cross_entropy_with_logits 有什么区别?

标签 machine-learning tensorflow classification cross-entropy sigmoid

当尝试使用 sigmoid 激活函数获取交叉熵时,之间存在差异

  1. loss1 = -tf.reduce_sum(p*tf.log(q), 1)
  2. loss2 = tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(labels=p, logits=logit_q),1)

但是当使用softmax激活函数时它们是相同的。

示例代码如下:

import tensorflow as tf

sess2 = tf.InteractiveSession()
p = tf.placeholder(tf.float32, shape=[None, 5])
logit_q = tf.placeholder(tf.float32, shape=[None, 5])
q = tf.nn.sigmoid(logit_q)
sess.run(tf.global_variables_initializer())

feed_dict = {p: [[0, 0, 0, 1, 0], [1,0,0,0,0]], logit_q: [[0.2, 0.2, 0.2, 0.2, 0.2], [0.3, 0.3, 0.2, 0.1, 0.1]]}
loss1 = -tf.reduce_sum(p*tf.log(q),1).eval(feed_dict)
loss2 = tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(labels=p, logits=logit_q),1).eval(feed_dict)

print(p.eval(feed_dict), "\n", q.eval(feed_dict))
print("\n",loss1, "\n", loss2)

最佳答案

您混淆了二元多类问题的交叉熵。

多类交叉熵

您使用的公式是正确的,它直接对应于 tf.nn.softmax_cross_entropy_with_logits :

-tf.reduce_sum(p * tf.log(q), axis=1)

pq预计是 N 个类别的概率分布。具体来说,N 可以是 2,如下例所示:

p = tf.placeholder(tf.float32, shape=[None, 2])
logit_q = tf.placeholder(tf.float32, shape=[None, 2])
q = tf.nn.softmax(logit_q)

feed_dict = {
  p: [[0, 1],
      [1, 0],
      [1, 0]],
  logit_q: [[0.2, 0.8],
            [0.7, 0.3],
            [0.5, 0.5]]
}

prob1 = -tf.reduce_sum(p * tf.log(q), axis=1)
prob2 = tf.nn.softmax_cross_entropy_with_logits(labels=p, logits=logit_q)
print(prob1.eval(feed_dict))  # [ 0.43748799  0.51301527  0.69314718]
print(prob2.eval(feed_dict))  # [ 0.43748799  0.51301527  0.69314718]

请注意q正在计算 tf.nn.softmax ,即输出概率分布。所以它仍然是多类交叉熵公式,仅适用于N = 2。

二元交叉熵

这次正确的公式是

p * -tf.log(q) + (1 - p) * -tf.log(1 - q)

虽然从数学上来说这是多类情况的部分情况,但 p含义q是不同的。在最简单的情况下,每个 pq是一个数字,对应A类的概率。

重要:不要被常见的 p * -tf.log(q) 所迷惑。部分和总和。上一页 p以前是一个单热向量,现在它是一个数字,零或一。 q 相同- 以前是概率分布,现在是数字(概率)。

如果p是一个向量,每个单独的分量都被视为一个独立的二元分类。请参阅this answer概述了 tensorflow 中 softmax 函数和 sigmoid 函数之间的区别。所以定义p = [0, 0, 0, 1, 0]并不意味着一个one-hot向量,而是5个不同的特征,其中4个是关闭的,1个是打开的。定义q = [0.2, 0.2, 0.2, 0.2, 0.2]表示 5 个功能中每一个都有 20% 的概率。

这解释了 sigmoid 的使用交叉熵之前的函数:其目标是将 logit 压缩为 [0, 1]间隔。

上面的公式对于多个独立特征仍然成立,而这正是 tf.nn.sigmoid_cross_entropy_with_logits 计算:

p = tf.placeholder(tf.float32, shape=[None, 5])
logit_q = tf.placeholder(tf.float32, shape=[None, 5])
q = tf.nn.sigmoid(logit_q)

feed_dict = {
  p: [[0, 0, 0, 1, 0],
      [1, 0, 0, 0, 0]],
  logit_q: [[0.2, 0.2, 0.2, 0.2, 0.2],
            [0.3, 0.3, 0.2, 0.1, 0.1]]
}

prob1 = -p * tf.log(q)
prob2 = p * -tf.log(q) + (1 - p) * -tf.log(1 - q)
prob3 = p * -tf.log(tf.sigmoid(logit_q)) + (1-p) * -tf.log(1-tf.sigmoid(logit_q))
prob4 = tf.nn.sigmoid_cross_entropy_with_logits(labels=p, logits=logit_q)
print(prob1.eval(feed_dict))
print(prob2.eval(feed_dict))
print(prob3.eval(feed_dict))
print(prob4.eval(feed_dict))

您应该看到最后三个张量相等,而 prob1只是交叉熵的一部分,所以只有当p时才包含正确的值。是 1 :

[[ 0.          0.          0.          0.59813893  0.        ]
 [ 0.55435514  0.          0.          0.          0.        ]]
[[ 0.79813886  0.79813886  0.79813886  0.59813887  0.79813886]
 [ 0.5543552   0.85435522  0.79813886  0.74439669  0.74439669]]
[[ 0.7981388   0.7981388   0.7981388   0.59813893  0.7981388 ]
 [ 0.55435514  0.85435534  0.7981388   0.74439663  0.74439663]]
[[ 0.7981388   0.7981388   0.7981388   0.59813893  0.7981388 ]
 [ 0.55435514  0.85435534  0.7981388   0.74439663  0.74439663]]

现在应该很清楚了,求和 -p * tf.log(q)沿axis=1在此设置中没有意义,尽管它在多类情况下是有效的公式。

关于machine-learning - TensorFlow 中 sigmoid 后跟交叉熵和 sigmoid_cross_entropy_with_logits 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46291253/

相关文章:

tensorflow - 带有 CART 树的 TensorFlow 随机森林使用什么杂质指数(基尼系数、熵?)?

python - ValueError : Error when checking target: expected avg_pool to have 4 dimensions, 但得到形状为 (100, 2) 的数组

machine-learning - 对于不平衡数据,要预测哪一类?

python - scikit-learn (sklearn) 中 GaussianMixture 的负 BIC 值

machine-learning - 为什么向线性回归添加特征会降低准确性?

python - 经过训练的 TensorFlow 模型始终输出零

tensorflow - 用于 ML 预测的 Celery 任务在执行中挂起

python - 机器学习模型如何更新?

python - 谷歌 tensorflow 速成类(class)。表示问题 :Programming exercises Task 2: Make Better Use of Latitude

algorithm - 是否有针对数据的一对多分类算法(1 :n) relationship?