返回列表

2nd place solution : Segmentation + 2.5D CNN + GRU Attention

513. RSNA 2022 Cervical Spine Fracture Detection | rsna-2022-cervical-spine-fracture-detection

开始: 2022-07-28 结束: 2022-10-27 医学影像分析 数据算法赛
第二名方案:分割 + 2.5D CNN + GRU Attention

第二名方案:分割 + 2.5D CNN + GRU Attention

作者:Ryan R, Jackeylov3, Zhenghan Chen, Hao Chen
比赛排名:第 2 名

感谢 Kaggle 和 RSNA 举办了这样一场精彩的比赛,我们很高兴能获得第二名。在这个复杂的比赛中,我们试图找到最简洁高效的解决方案,并收获了很多知识。这也是我经历过的对硬盘读写要求最高的比赛之一,因为没有足够的空间保存高分辨率的伪标签体素数据,我们在加载数据上浪费了一些时间。

长话短说,我们的解决方案包含两个阶段,并使用了 2.5D CNN,这是我们在 UWM 比赛中向 @Awsaf 学习到的技巧 (UWMGI: 2.5D Train [PyTorch] | Kaggle)。

阶段 1:2.5D CNN + Unet 用于分割

阶段 2:CNN + BiGRU + Attention 用于分类

阶段 1 (Stage 1)

首先,我们使用了组织者提供的 87 个分割样本。我们按照以下方法重建了掩码标签:

0 ---> 背景  
1 ---> C1  
2 ---> C2  
...
8 ---> T1 - T12  

我们使用了更通用的 2.5D 方法,输入为 3 通道的图像数据,即原始图像 i 及其两侧的图像:i-1 和 i+1。

分割示意图

这里的数据增强部分如下,类似于 UWMGI: 2.5D [Train] [PyTorch] | Kaggle,没有太大的改动。

我们也尝试了更重的数据增强,但效果并没有更好。

Resize(CFG.img_size, CFG.img_size, interpolation=cv2.INTER_NEAREST),
HorizontalFlip(p=0.5),
ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.05, rotate_limit=10, p=0.5),
OneOf([
    GridDistortion(num_steps=5, distort_limit=0.05, p=1.0),
    ElasticTransform(alpha=1, sigma=50, alpha_affine=50, p=1.0)
], p=0.25),

对于分割模型,我们使用了 segmentation_models_pytorch 库,主干网络为 efficientnet-b0,解码器为 unet。

优化器 = "AdamW"

学习率调度器 = "CosineAnnealingLR" + "GradualWarmupSchedulerV3"

体素裁剪

一旦我们训练好分割模型,就将其推广到所有的 2019 个样本。我们对输入数据进行了与之前相同的预处理,在模型预测出结果后,我们人工查看了几张预测图像,发现准确率相当不错。

我们分别裁剪了每个样本的所有 7 个颈椎。每个颈椎对应来自 train.csv 的一个骨折标签。根据我们的 EDA(探索性数据分析),大多数样本包含 200-300 张切片,因此每个椎骨的平均切片数约为 30 张。我们选择了 24 张切片,这能满足大多数椎骨的需求。对于超过 24 张切片的颈椎,我们使用了一个简单的 numpy 函数来均匀获取 24 张切片。

sample_index = np.linspace(0, len(one_study_cid)-1, sample_num, dtype=int)

我们面临的挑战之一是本次比赛的训练图像有 300GB,如果我们要在本地保存裁剪后的 3D 高分辨率训练图像,将会超过硬盘的容量。因此,我们被迫选择只记录裁剪的坐标范围 [x0:x1, y0:y1, z0:z

同比赛其他方案