Skip to content

Commit 3c9c3d3

Browse files
committed
updates
1 parent a6920ee commit 3c9c3d3

File tree

1 file changed

+146
-2
lines changed

1 file changed

+146
-2
lines changed

src/other/语义分割中常用的损失函数.md

Lines changed: 146 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: 语义分割中常用的损失函数
33
icon: file
44
category:
5-
- tools
5+
- 损失函数
66
tag:
77
- 已发布
88
footer: 技术共建,知识共享
@@ -693,10 +693,154 @@ class TverskyLoss(nn.Module):
693693

694694
Lovasz Hinge Loss的设计思想是,在计算IoU得分之前,根据预测误差对预测结果进行排序,然后累积计算每个误差对IoU得分的影响。然后,将该梯度向量与初始误差向量相乘,以最大程度地惩罚降低IoU得分的预测结果。
695695

696-
696+
[https://github.com/bermanmaxim/LovaszSoftmax](https://github.com/bermanmaxim/LovaszSoftmax)
697697

698698

699699
### Combo Loss
700700

701+
**Combo Loss** 是一种结合了多个损失函数优点的混合损失函数,特别适用于图像分割任务。它将 **Dice Loss****交叉熵损失(CrossEntropy Loss)** 相结合,并引入一个可调节的权重参数,使得模型在训练过程中可以更灵活地平衡这两部分损失。
702+
703+
核心思想:
704+
705+
> Combo Loss = α × CrossEntropy + (1 - α) × Dice Loss
706+
707+
或者更广义地:
708+
> Combo Loss = α × 分类误差(CE)+ β × 区域重叠误差(Dice)
709+
710+
其中 α + β = 1,α 控制分类误差的重要性,β 控制区域匹配误差的重要性。
711+
712+
---
713+
714+
***数学定义:***
715+
716+
假设我们有预测概率图 $p_i \in [0,1]$,真实标签 $y_i \in \{0,1\}$,那么:
717+
718+
1. 交叉熵损失(Binary Cross Entropy):
719+
720+
$$
721+
\mathcal{L}_{\text{CE}} = -\sum_i \left[ y_i \log(p_i) + (1 - y_i)\log(1 - p_i) \right]
722+
$$
723+
724+
2. Dice Loss:
725+
726+
$$
727+
\mathcal{L}_{\text{Dice}} = 1 - \frac{2 \sum_i y_i p_i}{\sum_i y_i + \sum_i p_i}
728+
$$
729+
730+
3. Combo Loss 定义为:
731+
732+
$$
733+
\mathcal{L}_{\text{Combo}} = \alpha \cdot \mathcal{L}_{\text{CE}} + (1 - \alpha) \cdot \mathcal{L}_{\text{Dice}}
734+
$$
735+
736+
其中:
737+
738+
- $\alpha \in [0,1]$:控制两个损失之间的权重比例
739+
740+
- 若 $\alpha=1$:仅使用交叉熵损失
741+
742+
- 若 $\alpha=0$:仅使用 Dice Loss
743+
744+
---
745+
746+
为什么使用 Combo Loss:
747+
748+
| 优势 | 描述 |
749+
|------|------|
750+
| ✔️ 兼顾像素级精度和区域重叠度 | CE 关注每个像素的分类准确性,Dice 关注整体区域匹配程度 |
751+
| ✔️ 对类别不平衡问题鲁棒 | 在前景像素远少于背景像素时表现良好(如医学图像) |
752+
| ✔️ 更稳定的训练过程 | 避免单一损失可能带来的训练不稳定性 |
753+
| ✔️ 可调性强 | 通过调整 α 参数,适应不同任务需求 |
754+
755+
对比其他损失函数:
756+
757+
| 损失函数 | 是否关注像素分类? | 是否关注区域匹配? | 是否可调? | 是否适合类别不平衡? |
758+
| --- | --- | --- | --- | --- |
759+
| CrossEntropy Loss |||||
760+
| Dice Loss |||||
761+
| Tversky Loss || ✅ ✅ || ✅ ✅ |
762+
| Combo Loss | ✅ ✅ ||| ✅ ✅ |
763+
764+
---
765+
766+
代码实现:
767+
768+
```python
769+
# 超参数设置说明:
770+
ALPHA = 0.5 # 控制交叉熵中正负样本的权重
771+
# 如果 ALPHA < 0.5:对假阳性(FP)惩罚更重(更关注精确率)
772+
# 如果 ALPHA > 0.5:对假阴性(FN)惩罚更重(更关注召回率)
773+
774+
CE_RATIO = 0.5 # 控制交叉熵损失和 Dice 损失之间的权重分配
775+
# CE_RATIO 越大,交叉熵在总损失中的占比越高
776+
777+
778+
class ComboLoss(nn.Module):
779+
def __init__(self, weight=None, size_average=True):
780+
"""
781+
初始化函数
782+
783+
参数:
784+
weight: 可选,类别权重(用于处理类别不平衡)
785+
size_average: 如果为 True,则返回所有样本损失的平均值
786+
"""
787+
super(ComboLoss, self).__init__()
788+
# 这里不直接使用 weight 和 size_average,但保留作为接口兼容
789+
self.weight = weight
790+
self.size_average = size_average
791+
792+
def forward(self, inputs, targets, smooth=1, alpha=ALPHA, beta=BETA, eps=1e-9):
793+
"""
794+
前向传播计算 Combo Loss
795+
796+
参数:
797+
inputs: 模型输出的概率值(经过 Sigmoid),形状如 (N, H, W)
798+
targets: 真实标签,形状与 inputs 相同,值为 0 或 1
799+
smooth: 平滑系数,防止除以零
800+
alpha: 控制 FP/FN 的惩罚比例(用于交叉熵部分)
801+
eps: 防止 log(0) 出现的小常数
802+
803+
返回:
804+
combo_loss: 计算得到的 Combo Loss
805+
"""
806+
807+
# 将输入和目标张量展平为一维,便于后续计算
808+
inputs = inputs.view(-1)
809+
targets = targets.view(-1)
810+
811+
# 计算 Dice Loss 所需的交集
812+
intersection = (inputs * targets).sum()
813+
814+
# Dice Score(区域匹配度)
815+
dice_score = (2. * intersection + smooth) / (inputs.sum() + targets.sum() + smooth)
816+
817+
# 加入数值稳定性处理,防止 log(0) 出现 NaN
818+
inputs = torch.clamp(inputs, eps, 1.0 - eps)
819+
820+
# 加权交叉熵损失(Weighted Cross Entropy)
821+
# 根据 ALPHA 参数调整正类和负类的权重
822+
weighted_ce = - (ALPHA * targets * torch.log(inputs)) - ((1 - ALPHA) * (1 - targets) * torch.log(1 - inputs))
823+
824+
# 对损失求均值
825+
weighted_ce = weighted_ce.mean()
826+
827+
# Combo Loss 是交叉熵和 Dice Loss 的加权组合
828+
# 注意:这里使用的是负的 Dice Score(因为要最小化损失)
829+
combo_loss = (CE_RATIO * weighted_ce) - ((1 - CE_RATIO) * dice_score)
830+
831+
return combo_loss
832+
```
833+
> 上面代码实现中使用的是加权交叉熵损失:
834+
>
835+
> $$
836+
> \mathcal{L}_{\text{CE}} = - \alpha \cdot y_i \log(p_i) - (1 - \alpha) \cdot (1 - y_i) \log(1 - p_i)
837+
> $$
838+
839+
## 如何选择?
840+
841+
任务需求:根据特定的分割任务的需求和特点,选择适合的损失函数。例如,对于类别不平衡的数据集,可以考虑使用Tversky Loss或Combo Loss等能够处理不平衡情况的损失函数。
842+
843+
实验评估:在实验中,使用不同的损失函数进行训练,并评估它们在验证集或测试集上的性能。比较它们在IoU、准确率、召回率等指标上的表现,选择性能最佳的损失函数。
701844

845+
超参数调整:一些损失函数具有额外的超参数,如Tversky Loss中的alpha和beta,可以通过调整这些超参数来进一步优化损失函数的性能。
702846

0 commit comments

Comments
 (0)