TensorFlow 2中Sigmoid与Softmax交叉熵结果不一致的疑问
问题解析:二分类下Softmax交叉熵手动计算与官方函数的“不一致”问题
其实你遇到的并不是真正的结果不一致,而是对tf.nn.softmax_cross_entropy_with_logits的输出逻辑理解有偏差,咱们一步步拆解:
1. 先确认Sigmoid部分的正确匹配
你在Sigmoid场景下的测试是完全正确的:
- 当labels全为
[1,1]时,tf.nn.sigmoid_cross_entropy_with_logits的公式简化为-log(sigmoid(logits)),和你手动计算的逻辑完全一致,所以输出结果匹配,这部分没问题。
2. Softmax场景的“误解点”
你觉得结果不一致,核心是混淆了全类别交叉熵和官方函数针对标签类别的交叉熵输出:
- 你的手动计算代码
-tf.math.log(tf.nn.softmax(tf.convert_to_tensor([0.6,0.4]))),输出的是该样本两个类别的交叉熵值:正类(第一个位置)的0.59813887,负类(第二个位置)的0.79813886。 - 而
tf.nn.softmax_cross_entropy_with_logits的输入labels是独热编码[[1,0],[1,0]],它的逻辑是对每个样本,只提取labels中为1的那个位置对应的交叉熵值:- 第一个样本logits为
[0.6,0.4],labels为[1,0],所以取正类的交叉熵0.59813887; - 第二个样本logits为
[0.4,0.6],labels为[1,0],所以取正类的交叉熵(也就是-log(softmax([0.4,0.6])[0])),计算结果正好是0.79813886。
- 第一个样本logits为
所以官方函数输出的[0.59813887 0.79813886],其实就是你手动计算结果中,每个样本对应label为1的位置的值,完全符合预期,不存在不一致。
3. 再明确二分类下Sigmoid与Softmax交叉熵的等价性
二分类场景下两者的等价性,体现在正类的交叉熵计算结果一致:
- 对Softmax来说,正类概率是
softmax(logits)[0] = sigmoid(logits[0] - logits[1]); - 因此正类的交叉熵
-log(softmax(logits)[0]),和Sigmoid场景下以logits[0]-logits[1]为输入的正类交叉熵-log(sigmoid(logits[0]-logits[1]))结果完全一致。
比如你第二个样本logits为[0.4,0.6],logits[0]-logits[1] = -0.2,计算-log(sigmoid(-0.2))会得到和Softmax正类交叉熵一样的0.79813886,这就是两者等价的体现。
内容的提问来源于stack exchange,提问作者ste
相关产品推荐
相关产品推荐

