我正在使用Sigmoid和BCELoss实现一个用于二进制分割的UNet。问题是,经过几次迭代,网络试图预测每个像素的非常小的值,而对于某些区域,它应该预测接近1的值(对于地面实况掩码区域)。它是否给出了关于错误行为的任何直觉?
此外,还有用于像素损失的NLLLoss2d。目前,我只是忽略了这一点,我直接使用MSELoss()。我应该使用带有Sigmoid激活层的NLLLoss2d吗?
谢啦
在我看来,你的Sigmoid正在使激活图饱和。图像没有正确规范化,或者缺少一些批量规范化层。如果您有一个使用其他图像的实现,请检查图像加载器并确保它没有使像素值饱和。这通常发生在16位通道上。你能分享一些输入图像吗?
PS抱歉在回答中评论,这是一个新账号,还不允许我评论。
您可能想要使用torch. nn.BCEWellLogitsLoss()
,替换Sigmoid和BCELoss函数。
文档的摘录告诉您为什么使用这个损失函数实现总是更好。
这种损失将Sigmoid层和BCELoss组合在一个类中。这个版本在数值上比使用普通Sigmoid后跟BCELoss更稳定,因为通过将操作组合到一个层中,我们利用log-sum-exp技巧来实现数值稳定性。