相同样例输入下TensorFlow与PyTorch交叉熵损失返回值为何不同
差异原因
两个框架返回结果不同的核心原因是交叉熵损失接口对输入y_pred的默认假设、内部预处理逻辑完全不匹配,和数值精度误差无关:
- PyTorch的
nn.CrossEntropyLoss默认接收未经过任何归一化、激活处理的原始模型输出(logits),内部会自动沿类别维度做Softmax指数归一化得到合法概率分布,再计算目标类的负对数损失。你当前的PyTorch代码使用默认参数,就是按logits规则处理输入,计算得到约1.5的损失值。 - TensorFlow的
tf.keras.losses.SparseCategoricalCrossentropy默认参数为from_logits=False,此时接口期望输入是已经归一化完成的合法概率分布(沿类别维度和为1、所有值落在[0,1]区间)。你传入的预测值不满足合法概率要求,接口不会自动做Softmax处理,而是直接对输入做L1归一化(即每个类的预测值除以当前样本所有类预测值的和)后再计算负对数损失,最终得到约1.69的结果。
修正方法
如果你传入的是和测试样例一样的原始logits值,只需要修改TensorFlow侧损失初始化参数,让两个框架的预处理逻辑对齐即可:
# 给TF的损失加上from_logits=True,内部会自动做Softmax,和PyTorch逻辑一致 scce3 = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=tf.keras.losses.Reduction.AUTO)
修改后两边的计算结果会完全对齐。
如果你要传入的是已经经过Softmax处理的合法概率值,则需要修改PyTorch侧的实现:手动对概率值取对数后传入nn.NLLLoss,因为nn.CrossEntropyLoss是LogSoftmax+NLLLoss的封装,不支持直接输入概率。
内容的提问来源于stack exchange,提问作者ankur singhania
相关产品推荐
相关产品推荐

