【问题标题】:BCELoss for binary pixel-wise segmentation pytorch用于二进制逐像素分割的 BCELoss
【发布时间】:2017-12-24 09:09:47
【问题描述】:

我在使用 Sigmoid 和 BCELoss 时实现了一个用于二进制分割的 UNet。问题在于,经过几次迭代后,网络试图预测每个像素的非常小的值,而对于某些区域,它应该预测接近 1 的值(对于地面实况掩码区域)。它对错误行为有任何直觉吗?

此外,还有用于像素损失的 NLLLoss2d。目前,我只是忽略了这一点,我直接使用 MSELoss() 。我应该使用带有 Sigmoid 激活层的 NLLLoss2d 吗?

谢谢

【问题讨论】:

    标签: python deep-learning pytorch


    【解决方案1】:

    在我看来,您的 Sigmoid 正在使激活图饱和。图像未正确归一化或缺少某些批归一化层。如果您有一个使用其他图像的实现,请检查图像加载器并确保它不会使像素值饱和。这通常发生在 16 位通道上。你能分享一些输入图像吗?

    PS 很抱歉在答案中发表评论。这是一个新帐户,我还不能发表评论。

    【讨论】:

    • 感谢您的回复。好吧,我在我的网络中使用了 batchNormalization,并且所有层都使用了 RELU,除了最后一个是 Sigmoid。 “饱和像素值”到底是什么意思?
    • 1.在这种情况下,请检查 Sigmoid 的输出激活图是否太高或太低。有效范围在 ±sqrt(3) 之间。 2. RE:“饱和像素值”,pytorch 中的 PIL 加载器将 16 位图像的所有像素设置为 1。我建议编写一个打印像素值并将其用作 lambda 变换的小函数。在此函数中,您将在第一个参数中获取加载的图像,以检查是否已加载正确的值。 3. 你的归一化参数是什么?
    【解决方案2】:

    您可能想使用torch.nn.BCEWithLogitsLoss(),替换 Sigmoid 和 BCELoss 函数。

    docs 的摘录告诉您为什么使用这种损失函数实现总是更好。

    这种损失将 Sigmoid 层和 BCELoss 组合在一个类中。这个版本比使用简单的 Sigmoid 后跟 BCELoss 在数值上更稳定,因为通过将操作组合到一层,我们利用 log-sum-exp 技巧来实现数值稳定性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-16
      • 1970-01-01
      • 2011-10-22
      • 2017-08-05
      • 2021-08-09
      • 2021-01-04
      • 2014-01-16
      • 2014-12-26
      相关资源
      最近更新 更多