PyTorch中BCEWithLogitsLoss输出维度与公式不符的疑问解析
解惑PyTorch中BCEWithLogitsLoss的输出结果问题
你遇到的这个疑惑其实是PyTorch中BCEWithLogitsLoss默认参数设置导致的,很多刚接触这个损失函数的开发者都会有类似疑问。
问题回顾
先看你给出的PyTorch示例代码和输入输出:
>>> loss = nn.BCEWithLogitsLoss() >>> input = torch.randn(3, requires_grad=True) >>> target = torch.empty(3).random_(2) >>> output = loss(input, target) >>> output.backward()
输入:tensor([0.4764, -2.4063, 0.1563], requires_grad=True)
目标值:tensor([0., 1., 1.])
输出:tensor(1.3567, grad_fn=<BinaryCrossEntropyWithLogitsBackward>)
你最初认为按照公式,输出应该是和输入形状一致的(3,)数组,但实际得到的是单一数值,这核心原因就是默认的reduction参数设置。
关键原因:默认reduction='mean'
BCEWithLogitsLoss的reduction参数决定了最终损失的计算方式,默认值是'mean'——也就是对所有样本的损失值取算术平均值。
你自己手动验证的过程也完美印证了这一点:
>>> target_n = target.numpy() >>> input_n = input.detach().numpy() >>> def sigmoid(array):return 1/(1+np.exp(-array)) >>> output_n = -1*(target_n*np.log(sigmoid(input_n))+(1-target_n)*np.log(1-sigmoid(input_n))) 输出数组:array([0.95947516, 2.4926252 , 0.61806685], dtype=float32) >>> np.mean(output_n) 1.3567224
手动计算的均值和PyTorch输出的1.3567完全匹配,说明默认情况下损失函数确实在做均值计算。
拓展:reduction的其他选项
如果你想要得到每个样本的损失数组(也就是你最初预期的(3,)形状),只需要将reduction设置为'none':
>>> loss = nn.BCEWithLogitsLoss(reduction='none') >>> output = loss(input, target) >>> output tensor([0.9595, 2.4926, 0.6181], grad_fn=<BinaryCrossEntropyWithLogitsBackward>)
另外还有'sum'选项,会返回所有样本损失的总和:
>>> loss = nn.BCEWithLogitsLoss(reduction='sum') >>> output = loss(input, target) >>> output tensor(4.0702, grad_fn=<BinaryCrossEntropyWithLogitsBackward>)
这个数值正好是你手动计算数组的总和(0.95947516+2.4926252+0.61806685≈4.070167)。
内容的提问来源于stack exchange,提问作者helloswift123
相关产品推荐
相关产品推荐

