672. RSNA Intracranial Aneurysm Detection | rsna-intracranial-aneurysm-detection
首先,我们要感谢竞赛主办方 @evancalabrese, @shosys 以及每一位参与数据准备和竞赛相关流程的 RSNA 成员,同时也感谢 Kaggle 工作人员组织本次竞赛。
下面,我们将介绍团队 Vibes and Genius Trade-Off 的解决方案!
我们的解决方案结合了三种互补的方法:
最终概率是通过平均 YOLO 2.5D 模型、带有 2D Effv2s 提取器的 3D CenterNet 以及三个元分类器的输出获得的。
以下是我们方法的图表。
我们使用了两种不同版本的 YOLO:
timm/tf_efficientnetv2_s.in21k_ft_in1k 作为骨干的 YOLO 架构关于 YOLO+timm 自定义的详细信息,请参阅 BYU _writeup。
我们将 13 个血管位置视为单独的边界框类别:
图像被调整为 512×512,使用最小 - 最大值归一化,并转换为 2.5D 变体:
R (红通道) = 切片 i-1
G (绿通道) = 切片 i
B (蓝通道) = 切片 i+1
下图展示了 2D 与 2.5D 变体的切片示例:
正如示例中所示,图像差异很大,因为我们没有标准化 Z 轴间距。
我 (@sersasj) 花了 1-2 周时间尝试 Z 轴调整大小,但结果一直更差。也许是我做错了什么,但没有时间进一步调查。
我们非常不愿意在没有 proper Z-spacing resize 的情况下尝试 2.5D(在我看来这不是个好主意 - @sersasj)。尽管如此,即使没有 Z 轴重采样,2.5D 方法也在 CV 中提高了 0.02+ 的结果。
数据采样策略:
对于负样本,我们从每个序列中均匀采样 10 个切片。
例如:对于 100 切片的序列 → 切片 [1, 11, 22, 33, 44, 56, 67, 78, 89, 99]
对于正样本,我们使用了所有包含标注的切片
batch_size: 16
epochs: 50
mixup: 0.4
mosaic: 0.4
drop_path_rate: 0.2
cls_loss: 1.0
optimizer: AdamW
momentum: 0.9
learning_rate: auto
batch_size: 32
epochs: 80
mixup: 0.4
mosaic: 0.4
droput: 0.3
cls_loss: 1.0
optimizer: AdamW
momentum: 0.9
learning_rate: auto
我们还修改了适应度函数以包含 AUC 指标并优先考虑 mAP@50。
fitness = 0.5 × mAP@50 + 0.25 × mAP@50-95 + 0.25 × mAUC
这有帮助吗?也许有一点。在 BYU 竞赛中,我们已经发现优先考虑 mAP@50 而不是 Ultralytics 标准的 1.0×mAP@50-95 能带来更好的结果。
添加 AUC 当时看起来是个好主意,因为它是竞赛指标,但我们没有彻底调查它是否显著提高了性能。好处可能是微乎其微的,但为了保持一致性我们保留了它。
训练硬件和时间
| 硬件设置 | GPU | CPU | 内存 | 每折时间 | 总计 (5 折) |
|---|---|---|---|---|---|
| @sersasj | RTX 3090 | Intel Core i5-12400F (12) @ 4.4GHz | 32GB | 4-5 小时 | ~24 小时 |
| @iamparadox | RTX 4090 | AMD Ryzen 9 7950X (32) @ 5.883GHz | 64GB | ~2 小时 | ~10 小时 |
对于推理,我们按空间位置对 DICOM 切片进行排序 (SliceLocation → ImagePositionPatient → InstanceNumber),为切片 1 到 N-1 创建 2.5D 三元组。
在两个模型上运行批量推理,提取每个类别的最大置信度,并使用 max(localization_confidences) 作为整体动脉瘤存在概率。
该过程可以在下面的 gif 中观察到:
使用 MultilabelStratifiedKFold 对折进行分层,以确保在以下方面分布平衡:
| 折 (Fold) | loc_macro_auc | cls_auc | combined_mean |
|---|---|---|---|
| fold0 | 0.8184 | 0.7549 | 0.7867 |
| fold1 | 0.8114 | 0.7897 | 0.8005 |
| fold2 | 0.8134 | 0.7827 | 0.7981 |
| fold3 | 0.8162 | 0.7872 | 0.8017 |
| fold4 | 0.8540 | 0.8281 | 0.8410 |
| 平均 | 0.8227 | 0.7885 | 0.8056 |
| 折 (Fold) | loc_macro_auc | cls_auc | combined_mean |
|---|---|---|---|
| fold0 | 0.7978 | 0.7790 | 0.7884 |
| fold1 | 0.8159 | 0.8269 | 0.8214 |
| fold2 | 0.8155 | 0.7921 | 0.8038 |
| fold3 | 0.8153 | 0.7907 | 0.8030 |
| fold4 | 0.8499 | 0.8560 | 0.8529 |
| 平均 | 0.8189 | 0.8090 | 0.8139 |
| 折 (Fold) | loc_macro_auc | cls_auc | combined_mean |
|---|---|---|---|
| fold0 | 0.8393 | 0.7849 | 0.8121 |
| fold1 | 0.8330 | 0.8291 | 0.8310 |
| fold2 | 0.8399 | 0.8135 | 0.8267 |
| fold3 | 0.8370 | 0.8093 | 0.8232 |
| fold4 | 0.8738 | 0.8620 | 0.8679 |
| 平均 | 0.8446 | 0.8198 | 0.8322 |
在 YOLO 开发的初始阶段,@sersasj 创建了一个集成,包含 3xYolo11m 和 0.69LB 的 EfficientNetB2 公开笔记本。这给了我们 0.78 的 LB 分数,并在竞赛早期阶段将我们置于前 3 名。
在稍微探测 leaderboard 之后,@iamparadox 发现 YOLO 的动脉瘤分类 AUROC 非常低(约 ~0.58)。然后我们开始开发能够补充 YOLO 并提高动脉瘤分类 AUROC 的模型。(我们后来发现,早期 YOLO 开发结果不佳是由于训练中负样本数量不足。)
我们使用的一类模型是仅检测给定序列中动脉瘤存在的 2.5D 模型,带有辅助分割头。这些模型灵感来自 https://www.kaggle.com/code/hengck23/3d-unet-using-2d-image-encoder。这些模型与 yolo11m 结合给了我们 0.80 的 LB。
当我们与 @chihantsai, @atom1231 合并后,这些模型变得过时了。
在 BYU 竞赛中,我们表现最好的骨干是 timm/convnextv2_base.fcmae_ft_in22k_in1k。然而,在本次竞赛中,使用半精度训练导致损失迅速变为 NaN。根据我们的调查,这似乎是 ConvNeXt 架构的常见问题。我们假设如果在全精度下训练,该骨干可以实现与 YOLO11m 和 timm/tf_efficientnetv2_s.in21k_ft_in1k 相当的性能。不幸的是,由于时间限制,我们无法验证这一点。
修改 neck 和 head 也被考虑过。根据我们与 @tatamikenn 的 出色的逆向工程笔记本 的调查,P3 特征似乎是最常用的。我们在单个折上进行了快速测试,但验证结果大致相同,所以我们决定继续前进。
我们还尝试使用我们的 3D 分割结果来 过滤掉 YOLO 的无效位置预测,但召回率下降了很多。
此外,我们尝试使用 YOLO 提取补丁,并在预测类别之前对补丁应用小波和 log-polar 变换;然而,这种方法 没有产生好的结果。
这是一个高度实验性的项目,在 AI 的大量帮助下完成。我们从流行的"LB 0.69 公开笔记本”开始,从中重建了整个训练管道和数据预处理,然后结合了CenterNet -like 机制来检测动脉瘤的中心。
我们采用切片式 2D 编码器 + 浅层 3D 头设计:
timm 的 2D ImageNet 预训练 EfficientNetV2-S (tf_efficientnetv2_s.in21k_ft_in1k),处于 features_only 模式,使用倒数第二个特征图 (out_indices = (1,-2))。(B, C=1, D, H, W) 被重排为 B·D 个 2D 切片,独立编码,然后在 3D 头之前重新组装为 (B, C_feat, D, H′, W′)。如果骨干需要 3 个通道,单通道输入会被通道重复。base_channels) 聚合深度信号。num_classes = 13 血管位置 (3D 中心图)(dz, dy, dx)(D, H, W);使用 (stride_d=1, stride_h=stride_w=16) 映射到输出网格,因此输出为 D × H/16 × W/16。血管掩码是在物理空间中通过训练 3D DynUNet 生成的,体积重采样到 0.7 mm 各向同性间距。提供的 13 个血管类别的体素级标注被合并为单个二值血管掩码用于训练。生成的 3D 掩码随后被转换为切片式 2D 掩码以监督辅助头。
我们使用四项进行训练并加权求和:
给定热力图 logits H ∈ ℝ^{B×13×D×H′×W′}:
每类序列 logits: 对 13 个类别中的每一个在 (D, H′, W′) 上进行空间最大值。
动脉瘤存在 (全局) logit: 13 个类别 logits 的最大值。
这14 个 logits 驱动 BCE 损失并导出用于元集成。
.npy 体积;(D,H,W) 扩展为 (1,D,H,W)— 这里 D = 64。T_max = epochs, eta_min = 1e-6);也支持 StepLR / ReduceLROnPlateau。1, 横向 16pretrained=True, 默认不冻结| 折 (Fold) | loc_macro_auc | cls_auc | combined_mean |
|---|---|---|---|
| fold0 | 0.7762 | 0.7747 | 0.7754 |
| fold1 | 0.7676 | 0.8069 | 0.7873 |
| fold2 | 0.7508 | 0.7892 | 0.7700 |
| fold3 | 0.7553 | 0.7778 | 0.7666 |
| fold4 | 0.7734 | 0.7758 | 0.7746 |
| 平均 | 0.7647 | 0.7848 | 0.7748 |
| 折 (Fold) | loc_macro_auc | cls_auc | combined_mean |
|---|---|---|---|
| fold0 | 0.7779 | 0.7991 | 0.7885 |
| fold1 | 0.7828 | 0.7987 | 0.7908 |
| fold2 | 0.7601 | 0.8051 | 0.7826 |
| fold3 | 0.7683 | 0.7826 | 0.7755 |
| fold4 | 0.7586 | 0.7954 | 0.7770 |
| 平均 | 0.7695 | 0.7962 | 0.7829 |
Flayer 使用浅层 3D 头将 2D EfficientNetV2-S 切片特征转换为 3D 证据图,使用 CenterNet 风格的热力图 + 偏移进行监督,并生成稳健的14-logit 序列级预测(包括聚合的动脉瘤存在 logit),这些预测可以 cleanly 插入我们的堆叠元分类器中。
我们设计了一个堆叠集成架构来整合来自 YOLO11m, YOLO11-EffV2s, 和 EffV2s-3D-CenterNet 模型的预测。具体来说,每个元分类器接收来自所有基础模型的连接预测作为输入,并为动脉瘤存在和特定位置检测生成最终预测。这种设置使模型能够通过考虑所有模型中所有位置的预测来评估给定位置的动脉瘤存在,有效地捕捉集成对动脉瘤存在的集体推理。
# 对于每个 fold_id
metadata = np.array([age, sex])
X = np.concatenate([np.array([yolo11m_cls_preds[fold_id]]), yolo11m_loc_preds[fold_id],
np.array([effv2s_cls_preds[fold_id]]), effv2s_loc_preds[fold_id],
flayer_fold_preds[fold_id], metadata], axis=0)[None, :]
lgb_pred = predict_prob_lgb(X, fold_id) #(14, )
xgb_pred = predict_prob_xgb(X, fold_id)
cat_pred = predict_prob_cat(X, fold_id)
我们尝试了两种集成结构:
(30 特征,[yolo(14) + flayer(14) + meta(2)])
(44 特征,[yolo11m(14) + yolo_effnets(14)+ flayer(14) + meta(2)])
这种比较允许我们评估在并行中组合多个特征流是否提供了超越顺序(串联)配置的额外互补信息。
我们发现,在并行中组合来自不同 YOLO 骨干和 flayer 的预测比在集成 CV 分数中的串联提供了更好的改进。这表明 GBDT 有效地利用了每个模型对跨位置动脉瘤存在的感知来做出准确判断。由于最后一天遇到的问题,我们未能完成 5 折提交。因此,我们在此展示我们最终选择的结果,该结果基于 2 折的平均值。
| 串联 (Series) | 并联 (Parallel) | |
|---|---|---|
| 5 折 CV (平均) | 0.84 | 0.852 |
| 5 折 CV (Nelder-Mead 优化) | 0.841 | 0.858 |
| 公共分数 (平均; 2 折) | 0.83 | 0.83082 |
| 私有分数 (平均; 2 折) | 0.81 | 0.8230 |
我们之前也在 Tom 的 BYU 方法 中尝试过基于关键点的双图预测器,发现它在集成 CV 性能方面表现良好。然而,基于 YOLO 的特征提取和预处理太耗时,经常导致超时。因此,我们没有将此方法包含在最终解决方案中。