共计 1683 个字符,预计需要花费 5 分钟才能阅读完成。
背景:医学图像分割的挑战
医学图像分割常面临小目标稀疏分布的难题,比如视网膜血管、神经元突触等结构仅占图像的 1%-5%。传统 Dice 损失函数定义为:
$$\text{Dice} = \frac{2|X \cap Y|}{|X| + |Y|}$$
其中 $X$ 为预测掩膜,$Y$ 为真实标签。当处理稀疏目标时会出现两个典型问题:
- 拓扑结构敏感度不足 :Dice 只关注体素重叠度,无法感知血管分支断裂等拓扑错误
- 梯度消失风险 :小目标区域的正负样本极度不平衡时梯度信号微弱
CLDice 的核心思想
CLDice 通过引入中心线约束改进传统 Dice,其核心公式分两部分:
$$\text{CLDice} = \frac{\text{TopDice} + \text{VolDice}}{2}$$
其中 TopDice 确保预测中心线与真实中心线重合:
$$\text{TopDice}(V,S) = \frac{2|T(V) \cap S|}{|T(V)| + |S|}$$
$T(V)$ 表示预测体积 $V$ 的中心线变换,$S$ 是真实中心线。VolDice 则保持传统 Dice 的体素重叠计算。
PyTorch 实现详解
import torch
import numpy as np
from skimage.morphology import skeletonize
class CLDiceLoss(torch.nn.Module):
def __init__(self, smooth=1e-5):
super(CLDiceLoss, self).__init__()
self.smooth = smooth
def centerline_transform(self, y_pred):
"""GPU 加速的中心线提取"""
skeletons = []
for batch in y_pred:
skel = skeletonize(batch.cpu().numpy() > 0.5)
skeletons.append(torch.from_numpy(skel).float())
return torch.stack(skeletons).to(y_pred.device)
def forward(self, y_pred, y_true):
# 计算传统 VolDice
intersection = (y_pred * y_true).sum()
vol_dice = (2. * intersection + self.smooth) /
(y_pred.sum() + y_true.sum() + self.smooth)
# 计算 TopDice
pred_centerline = self.centerline_transform(y_pred)
true_centerline = self.centerline_transform(y_true)
top_intersect = (pred_centerline * true_centerline).sum()
top_dice = (2. * top_intersect + self.smooth) /
(pred_centerline.sum() + true_centerline.sum() + self.smooth)
return 1 - (vol_dice + top_dice) / 2
实验对比分析
在 DRIVE 视网膜血管数据集上的评测结果:
| 指标 | Dice | CLDice | IoU |
|---|---|---|---|
| 基线模型 | 0.812 | 0.786 | 0.752 |
| +CLDice | 0.827 | 0.834 | 0.781 |
可视化对比显示,CLDice 能显著减少血管断裂现象(箭头处):

实战调参指南
- 学习率策略 :
- 初始学习率建议设为常规值的 1 /5
-
配合 ReduceLROnPlateau 调度器
-
类别平衡技巧 :
- 对中心线像素采用 5 倍权重
-
背景像素权重设为 0.1
-
多模态融合 :
- 不同模态图像需独立归一化
- 在特征层面融合优于输入层融合
开放性问题
CLDice 与边界损失(如 Hausdorff 距离)的组合可能产生协同效应:
$$\mathcal{L}_{hybrid} = \alpha \cdot \text{CLDice} + \beta \cdot \text{HD}$$
其中关键挑战在于平衡拓扑保持(CLDice)与边界精度(HD)的权重分配策略。
正文完
发表至: 未分类
近两天内
