返回列表

4th place solution. Boundary DoU Loss is all you need!

596. SenNet + HOA - Hacking the Human Vasculature in 3D | blood-vessel-segmentation

开始: 2023-11-07 结束: 2024-02-06 医学影像分析 数据算法赛
第4名解决方案:Boundary DoU Loss足矣!

首先,我想用几句重要的话开始我的解决方案描述:

我要感谢乌克兰武装部队、乌克兰国家安全局、乌克兰国防情报局和乌克兰国家紧急服务局,为参与这项伟大的竞赛、完成这项工作提供了安全和保障,并帮助科学、技术和商业不仅没有停滞,反而不断前进。

背景

方法概述

我的最终模型是2D和3D模型的混合体,并采用了d4 TTA(测试时增强)。对于2D模型,应用了多视角TTA。所有模型都采用2折交叉验证设置,选择kidney_2和kidney_3_dense作为验证集。集成时对2D和3D模型赋予相等权重。

提交细节

数据准备和训练验证方案

所有最终(3D和2D)模型都在kidney_1_dense、kidney_2、kidney_3_dense、kidney_3_sparse以及伪标签50um_LADAF-2020-31_kidney_pag-0.01_0.02_jp2_上进行训练。最初我使用逐片归一化来归一化图像,但后来改为基于百分位的堆栈级归一化。

2D模型采用多视角设置进行训练:所有图像被堆叠成一个张量,随后在不同轴上进行切片。在训练过程中,增强策略和采样策略至关重要。加权采样基于稀疏度百分比:密集样本权重为1,而稀疏样本的权重等于其稀疏度。对于伪标签,我选择与kidney_2相同的权重,例如:

kidney_1_dense: 1, 
kidney_2: 0.65, 
kidney_3_dense: 1, 
kidney_3_sparse: 0.85, 
50um_LADAF-2020-31_kidney_pag-0.01_0.02_jp2_: 0.65.

增强策略如下,有0.5的概率应用CutMix增强。裁剪来自同一器官和同一投影轴。然后在CutMix之上,应用下一个增强管道:

A.Compose(
    [
          A.PadIfNeeded(*crop_size),
          A.CropNonEmptyMaskIfExists(*crop_size, p=1.0),
          A.ShiftScaleRotate(scale_limit=0.2),
          A.HorizontalFlip(p=0.5),
          A.VerticalFlip(p=0.5),
          A.RandomRotate90(p=0.5),
          A.OneOf([
                A.RandomBrightnessContrast(), 
                A.RandomBrightness(), 
                A.RandomGamma(),
          ],p=1.0,),
    ],p=1.0,)

裁剪大小设置为512。我也尝试过更高分辨率,但效果相差不大。

我进行了一些2.5D方法的实验(3通道和5通道),但结果相同或更差。

3D模型的增强方案仅包含d4增强和随机裁剪。裁剪时有0.5的概率裁剪到空掩码区域。这是为了处理在肾脏体积外出现的假阳性问题。这可以通过引入两类3D分割来改进,但我没有足够的时间和资源进行此类实验。因此,我决定创建一个后处理来解决这个问题。3D模型的裁剪大小为192x192x192。

两个模型都采用2折交叉验证设置,使用kidney_2(fold_1)和kidney_3_dense(fold_0)作为验证。从训练集中移除kidney_1会导致CV和LB性能下降,因此我放弃了fold_2,没有在该设置下进行训练。

模型设置

我能够获得的最佳结果是使用efficientnet系列模型与UnetPlusPlus解码器以及来自segmentation_models_pytorch库的SCSE注意力机制。我尝试过resnet50模型(如讨论部分所述)、不同的transformer和seresnext模型,但都无法超越efficientnet-b5的性能(它在CV和LB上表现最佳)。在我的本地验证中,efficientnet_b7编码器和mit_b5编码器获得了不错的分数,但在LB上分数显著降低。

训练进行了30个epoch,使用从3e-4到1e-6的余弦学习率调度器。我保存了前3个检查点,并提交时使用了best-last检查点。

采用此设置训练的efficientnet_b5_UnetPlusPlus模型在0.05阈值下,公共LB得分为0.878,私有LB得分为0.714。

黄色为TP,绿色为FP,红色为FN。

3D模型的设计很大程度上受到nnUnet模型架构的启发,两者基本相同。我使用monai库中的DynUnet代替原生的nnUnet模型,配置几乎为默认设置,训练设置也与nnUnet几乎相同。优化器使用初始学习率为0.01的SGD,并采用余弦退火学习率方案(而非LinearLR),训练500个epoch,每个epoch包含2000个样本。

该模型在公共LB上得分为0.869(0.868和0.866——分别为fold 0和fold 1),私有LB上得分为0.694(0.758和0.663——分别为fold 0和fold 1)。

两个模型都使用BoundaryDOULoss(https://arxiv.org/pdf/2308.00220.pdf)进行训练,该损失函数表现最佳。我曾尝试修改它以更好地处理稀疏数据,但未能成功。

伪标签

根据预印本,我从http://human-organ-atlas.esrf.eu网站下载了额外数据(2个数据集)。结果显示,其中一个数据集与kidney_3重叠,因此为避免泄露,我将其剔除。我使用另一个数据集生成伪标签。对于伪标签生成,我使用了一个由2D模型(efficientnet-b5和efficientnet-b6与UnetPlusPlus)组成的集成,这些模型采用相同的设置训练但不包含CutMix。CutMix的正确设置以及3D模型我是在竞赛截止日期前才发现的,因此我没有重新训练原始集成,而是坚持使用第一版本的伪标签。

推理设置与后处理

两个模型的推理都使用monai库的sliding_window_inference进行。此外,对于2D模型,我执行了多视角TTA,这有助于检测小血管并提升整体性能。

对于2D模型,裁剪大小为800像素,而对于3D模型——256像素,重叠率为0.25,并使用高斯合并。所有模型都使用ttach库的d4_transform。我曾forked ttach仓库并实现了3D图像的逻辑,但推理时间显著增加,性能提升不大,因此我坚持对2D和3D模型都使用2D d4_transform :)

如前所述,3D模型在非空立方体上表现良好,但空立方体容易使模型混淆。为处理此问题,我决定尝试后处理。思路如下:尝试找到血管存在的感兴趣区域(ROI)。由于2D模型没有此问题,我决定为每个2D切片找到血管的边界多边形。获得ROI掩码后,我将其与3D模型的预测结果相乘,使单个3D模型的得分从0.869提升到公共LB的0.881和私有LB的0.701。

将2D模型和3D模型的预测结果以1:1的权重集成,我的得分从公共LB的0.881提升到0.884,私有LB提升到0.712。

我尝试的另一种后处理方法是使用cv2的Canny滤波器来分割肾脏。该分割算法并不完美,但应用此类后处理使我的公共LB得分从0.884提升到0.892,而在私有LB上表现糟糕,仅得0.313。

无效尝试

  • 直接使用nnUnet。在挑战开始时,阅读预印本后,我尝试复现nnUnet的结果。本地分数很有希望,但LB得分为0。我认为此问题的原因与数据归一化和间距(比例)有关,但我没有尝试修复它,而是决定构建自己的解决方案。
  • BCE和Focal Loss
  • 2D和3D模型中的Transformer
  • 3D图像的缩放和亮度增强
  • 基于稀疏数据集的伪标签。我曾尝试通过伪标签和聚合来填补数据集的稀疏性,但未能提升分数。
  • 额外的投影。我对2D模型和从3D堆栈生成的额外切片进行了实验,但LB性能下降了20%,而CV基本保持不变。
  • 距离变换或质心中心等辅助输出
  • 最重要的是:验证

P.S. 如果你能读到这里,私有LB上的最高分是2D和2.5D模型的简单组合(1通道和3通道):)

P.P.S. 感谢阅读!

同比赛其他方案