PyTorch中Sigmoid搭配BCELoss报autocast错误却复现失败是为何?
问题原因说明
这个报错是PyTorch自动混合精度(AMP)模块的专属校验触发的,你无法复现的核心原因是遗漏了2个关键场景条件:
- 没有启用
torch.cuda.amp.autocast()自动混合精度上下文管理器,只有开启AMP时PyTorch才会对BCELoss的使用场景做安全性校验 - 复现代码默认运行在CPU上,AMP是为CUDA设备设计的优化特性,CPU场景不会触发对应校验逻辑
可复现报错的示例代码
import torch from torch import nn # 初始化组件 sigmoid = nn.Sigmoid() bce_loss = nn.BCELoss() # 数据迁移到CUDA设备 device = 'cuda' if torch.cuda.is_available() else 'cpu' true_cls = torch.tensor([ [0.], [1.]]).to(device) pred_logits = torch.tensor([ [0.4949], [0.4824]],requires_grad=True).to(device) # 开启autocast上下文触发校验 with torch.cuda.amp.autocast(): pred_cls = sigmoid(pred_logits) out = bce_loss(pred_cls, true_cls) out.backward()
运行上述代码即可复现你训练时碰到的RuntimeError报错。
修复方案
推荐方案
删除模型最后一层的torch.nn.Sigmoid(),损失函数替换为torch.nn.BCEWithLogitsLoss,直接输入模型输出的原始logits计算损失,该方案同时满足autocast安全要求,且数值稳定性更高,是PyTorch官方推荐的二分类损失实现方式。
兼容方案
如果业务逻辑必须保留Sigmoid+BCELoss的结构,在计算损失的代码块外层关闭autocast即可:
with torch.cuda.amp.autocast(enabled=False): pred_cls = sigmoid(pred_logits) out = bce_loss(pred_cls, true_cls)
内容的提问来源于stack exchange,提问作者Celso França
相关产品推荐
相关产品推荐

