训练语义分割模型时,类别不平衡怎么解决?

训练语义分割最让我崩溃的时刻,不是 loss 不降,而是 loss 降得很漂亮,推理出来一看——小类别整个消失了,全被背景吞得干干净净。如果你也遇到过这种"指标挺好、结果没法看"的情况,大概率就是类别不平衡在作怪。

训练语义分割模型时,类别不平衡怎么解决?

先说怎么确认。别只盯着 IoU 的平均值,把每个类别的 IoU 单独拉出来看,再配合可视化结果。我之前就是平均分看着不错,一可视化才发现某些类几乎全错,边缘还一堆杂点。平均值会撒谎,单类指标和可视化不会。

确认是不平衡之后,我一般会从三个层面下手。

损失函数是最先动的。 交叉熵本质上是按像素逐个评分,背景像素占绝大多数,模型很容易学会"全猜背景也能拿高分"。这时候 Dice 或 focal loss 就派上用场了——Dice 更关心整体重合度,对占比小的类别友好得多。我的习惯是直接上交叉熵加 Dice 的混合损失,基本作为第一选择。

类别权重也很直接。 class weighting 的思路就是给稀有类别更高的犯错成本,让模型不敢忽视它们。如果某个类别死活学不出来,我会把它单独拎出来做个小实验:调大权重、专门做增强,看看它到底能不能被救回来。

采样层面同样能做文章。 小目标容易被背景淹没,那就提高包含小目标样本的采样权重,让模型多见它们几次,再配合随机裁剪这类增强,效果往往比单纯调损失更稳。

最后想提醒一句:别一上来就换模型。类别不平衡大多数时候不是结构问题,而是损失设计和数据分布的问题。先把权重、损失、采样这三板斧试完,多看失败样本长什么样,再决定要不要动结构。我自己踩过的坑告诉我:流程对了,一个普通的基线模型也能交出不错的答卷。

参与讨论

0 条评论

延伸阅读