返回列表

11th Place Solution

672. RSNA Intracranial Aneurysm Detection | rsna-intracranial-aneurysm-detection

开始: 2025-07-28 结束: 2025-10-14 医学影像分析 数据算法赛
第 11 名解决方案 - RSNA 颅内动脉瘤检测
竞赛: RSNA 颅内动脉瘤检测 (RSNA Intracranial Aneurysm Detection)
排名: 第 11 名 (11th Place)
作者: RihanPiggy (honglihang) - Grandmaster
发布日期: 2025-10-17

祝贺所有获奖者!感谢组织者举办如此有趣的比赛。这真的很难,但我非常享受。在这里分享我的解决方案。

TL;DR (太长不看版)

我的解决方案包含 4 个阶段:

  1. 使用 TotalSegmentator 生成脑掩膜,训练一个 3D Unet 来裁剪包含 Willis 环区域 (CoW Area) 的 ROI 区域。
  2. 训练 5 折 2.5D CoW 分割模型(分类损失 + 分割损失)并提取特征。
  3. 训练 5 折 2.5D 动脉瘤模型(分类 + 关键点损失)并提取特征。
  4. 在深度方向上,对来自 CoW 分割模型和动脉瘤模型的连接特征训练 RNN。

预处理

我使用了 dicom2nifti 将 dicom 文件转换为 nifti 文件,因为 TotalSegmentator 使用这个库。
我编写了一个自定义版本,将 train_localizers.csv 中的坐标和帧索引转换为与 nifti 文件对齐的新坐标。

阶段 1:脑掩膜 (Brain Mask)

脑掩膜生成

我使用 TotalSegmentator 为所有扫描生成脑掩膜。
奇怪的是,某些 CT 扫描由 TotalSegmentator MRI 生成的脑掩膜比 TotalSegmentator CT 生成的更好。因此,我为每个扫描生成了 2 个脑掩膜,并选择了像素更多的那个。
我还过滤掉了小于 100 万像素的小掩膜。最终,我得到了 4386 个脑掩膜。

脑分割 3D Unet

我训练了一个 3D Unet 来分割大脑。训练代码是复现自 Qishen Ha 的 RSNA2022 解决方案
我首先使用 Zenodo 上的 CTMRI 扫描对模型进行预训练,这是用于训练 TotalSegmentator 的训练数据的子集。然后,我使用 4386 个脑掩膜训练模型。模型采用 5 折训练。输入大小为 (128, 128, 128)。
我使用训练好的 3D Unet 为所有扫描生成脑掩膜并裁剪 ROI 区域。裁剪参数根据 CoWSeg 和 train_localizers.csv 进行调整,以确保裁剪区域包含 CoW 区域。

阶段 2:CoW 分割模型

与其他竞争者不同,我没有成功训练出一个好的 3D CoW 分割模型。相反,我训练了一个带有分类头的 2.5D CoW 分割模型。该模型的目的是提取位置特征输入到最终的 RNN 模型中。根据我在 RSNA2022 的经验,位置特征提升了 CV。因此,虽然 2.5D 模型的分割损失甚至更差 (dice=0.56),但提取的特征仍然有用。
训练代码是复现自 UWMGI 的 这个惊人的 notebook。我使用的骨干网络是 tf_efficientnetv2_b0.in1k (图像大小=224)。
此外,使用来自 CoW 分割模型的 OOF 分类 logits(如同阶段 1),我过滤掉了不包含 CoW 区域的切片。

阶段 3:动脉瘤模型

类似于 CoW 分割模型,我训练了一个带有分类头和关键点头的 2.5D 动脉瘤模型来提取特征。
成功训练此模型的关键如下:

  • 3 轮负采样。在第一轮中,我使用来自 CoW 分割模型的分类 logits 来采样包含血管的切片。在接下来的 2 轮中,我使用动脉瘤模型本身的 OOF 分类 logits 来采样硬负样本切片。
  • 启发式裁剪以使模型专注于血管区域。裁剪比例根据坐标进行调整。(确保所有坐标都在裁剪区域内)
  • alpha=0.75 的 Focal loss。
  • 使用 OOF logits 进行自蒸馏以处理标签噪声。
  • EMA (指数移动平均)。

我在这一阶段使用的骨干网络:

  • coatnet_rmlp_2_rw_384: 5 折,img_size=384
  • coatnet_rmlp_2_rw_384: 全数据训练,img_size=384
  • tf_efficientnetv2_s.in21k_ft_in1k: 另一个 5 折,img_size=384

全数据训练使用了不同版本的数据集,硬负样本图像较少。我首先训练了一个 5 折模型,并记录了最佳 CV 的 epoch 以计算全数据训练的总训练步数。

阶段 4:RNN 模型

我为每个动脉瘤模型训练了 4 种类型的 RNN 模型。模型开始很快过拟合,因此使用 EMA 和重度 mixup (mixup ratio=0.5) 来正则化训练。

对于 5 折 Coatnet:

  • Residual LSTM: 动脉瘤特征 + CoW 分割特征
  • Residual GRU: 仅动脉瘤特征
  • BiLSTM: 仅动脉瘤特征
  • Bert: 仅动脉瘤特征

对于 5 折 Efficientnet:

  • Residual LSTM: 动脉瘤特征 + CoW 分割特征
  • Residual GRU: 动脉瘤特征 + CoW 分割特征
  • LSTM: 仅动脉瘤特征
  • Bert: 仅动脉瘤特征

对于全数据训练 Coatnet:

  • Residual LSTM: 动脉瘤特征 + CoW 分割特征
  • Residual GRU: 动脉瘤特征 + CoW 分割特征
  • BiLSTM: 动脉瘤特征 + CoW 分割特征
  • Bert: 动脉瘤特征 + CoW 分割特征

这些 RNN 的集成达到了 auc=0.8909,并通过使用 OOF logits 进行自蒸馏,另一个提交达到了 auc=0.9035

  • 提交 1: CV: 0.8909, 公有榜:0.87689, 私有榜:0.82201
  • 提交 2: CV: 0.9035, 公有榜:0.86703, 私有榜:0.81321
    我仍然对公有榜和私有榜分数之间的巨大差距感到非常困惑。

最大化 GPU 利用率

为了最大化推理速度,我使用 Monai 在 GPU 上预处理图像。我使用了 2 块 T4 显卡,并将患者体积分成 2 部分以并行化 2.5D 模型的推理。对于 RNN 模型,我只是将模型分成 2 组并在 2 块 GPU 上并行运行。这就是我如何在 12 小时内完成 11 个动脉瘤模型和 45 个 RNN 模型的推理。
我在最后几天遇到了超时问题。希望 Kaggle 能修复新的评估框架。

同比赛其他方案