二分类任务中能否用tf.nn.softmax_cross_entropy_with_logits解决负熵问题?
问题分析与解决方案
嘿,我一眼就看到你代码里的一个关键错误,这应该就是你得到负交叉熵值的核心原因!
1. 先修正你当前的代码问题
你调用tf.nn.sigmoid_cross_entropy_with_logits时把labels和logits的参数顺序搞反了!这个函数的定义是用labels传入真实标签,logits传入模型输出的原始未激活值,而你现在写的labels=y, logits=y_完全颠倒了——y是模型的输出(logits),y_才是真实标签。
正确的写法应该是:
cross_entropy = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y_, logits=y))
参数顺序纠正后,你应该就能得到正常的正交叉熵值了。毕竟交叉熵是衡量两个概率分布的差异,正常情况下不可能为负,你的负值完全是参数传反导致的计算逻辑错误。
2. 关于用tf.nn.softmax_cross_entropy_with_logits替代的问题
能不能用这个函数,得看你的二分类场景类型:
- 如果是单标签二分类(比如每个样本只能是A或B中的一个,非此即彼):可以用,但需要调整模型和标签格式:
- 输出层的
Labels要设为2(对应两个类别) - 真实标签
y_需要是one-hot编码形式(比如类别0用[1, 0]表示,类别1用[0, 1]表示)
- 输出层的
- 如果是多标签二分类(比如一个样本可以同时属于多个类别,比如一张图里既有猫又有狗):绝对不能用
softmax_cross_entropy_with_logits!因为softmax会强制所有类别的概率和为1,这不符合多标签场景中每个类别独立判断的逻辑,这种情况下必须用sigmoid_cross_entropy_with_logits。
3. 额外建议
对于普通的单标签二分类,其实sigmoid_cross_entropy_with_logits更简洁:你只需要把输出层维度设为1,真实标签用0或1的数值即可,不需要做one-hot编码,计算效率也更高。
内容的提问来源于stack exchange,提问作者python
相关产品推荐
相关产品推荐

