575. RSNA 2023 Abdominal Trauma Detection | rsna-2023-abdominal-trauma-detection
感谢RSNA举办这场有趣的竞赛,也祝贺所有获奖者付出的努力。
我是一名仅仅转专业从物理学到软件工程一年的初学者,我喜欢通过实践来学习,因此选择了Kaggle竞赛平台,这里有许多优秀的学习资源。
我非常高兴能够从对3D图像处理一无所知,到击败基线并最终获得银牌。我希望我的竞赛经验能给你带来一些启发,特别是对于那些和我一样刚开始挣扎着击败基线的初学者。
出于学习目的,我计划在本竞赛中尝试2D分类、3D分类、2D分割、3D分割等多种方法。因此我的流程可能会稍微复杂一些。
2D UNet 分割肝脏、脾脏、左肾、右肾和肠道3D UNet 进一步优化脾脏分割X3D_l 对肝脏、脾脏和肾脏进行分类(对于肾脏,仅反向传播概率更高的正样本)convnext_tiny 作为特征提取器。输入数据(B, N, 4, 512, 512)经过特征提取器后将转换为特征(B, N, 768)。如果 N < 64,将使用零特征进行填充,最终输出特征形状为(B, 64, 768)lstm + attention pooling concat maxpooling 进行特征融合nn.Linear 进行分类convnext_tiny 作为特征提取器。输入数据(B, N, 5, 3, 512, 512)将转换为特征(B, N, 5, 768)。如果 N < 64,将使用零特征进行填充,最终输出特征形状为(B, 64, 5, 768)attention_pooling concat maxpooling 融合每个切片的5个特征,输出形状为(B, 64, 768)lstm + attention pooling concat maxpooling 进行特征融合nn.Linear 进行分类albumentations.BBoxSafeRandomCropFixedSize(288, 288),这是一个围绕边界框随机裁剪图像的数据增强函数,能帮助 convnext_tiny 更关注小区域。对于负样本,使用 albumentations.RandomCrop(288, 288) 随机裁剪输入mask.sum() >= 1000(掩码由TotalSegmentator生成)。因此我认为 mask.sum() < 1000 的切片可以被忽略,从而使网络更专注于ROI区域gc.collect() 有很大帮助DataLoader.num_workers 可以节省内存,设置 DataLoader.pin_memory=False 可以节省GPU内存maxpooling 可能比 avgpooling 更好convnext_tiny + lstm + attention pooling concat maxpooling + nn.Linear(我看到本地CV提升很大,但比赛结束前没有足够时间提交)uniformer 替代 X3Defficientnetv2_s 替代 convnext_tiny我知道当你第一次参加不熟悉的竞赛时会有点困难。我将列出一些个人经验,帮助初学者迈出第一步。
加入竞赛前,你必须首先明确竞赛任务类型(3D CT多标签分类),并估算所需的计算资源、存储容量和硬盘空间。这用于判断你是否应该参加这个竞赛,因为当硬盘空间不足以存储处理后的数据时,你可能会感到沮丧。
对于不熟悉的任务(3D CT分类),最好的入门方式是阅读已结束的类似竞赛解决方案。巧合的是,RSNA过去几年举办了许多类似的竞赛。我发现RSNA 2022颈椎骨折检测(去年)和RSNA STR肺栓塞检测(三年前)与本次竞赛高度相关,它们的任务都是3D CT分类。你应该大量阅读优胜者的解决方案来决定自己的实验方法。我的发现是:2D骨干网络提取特征(或2.5D)+ 1D RNN融合的方式往往表现最佳。
阅读顶级解决方案后,你有两条路线来开发自己的流程。第一是复制并修改公开代码,但你必须理解每一行代码。第二是参考公开代码,使用自己的编程习惯或代码段来开发流程。我使用第二种方法,因为它能极大提高我的编码能力。在我过去一年的深度学习学习过程中,我不断积累并编写了一个基于PyTorch的简单多折训练、验证、测试、预测框架。它既能锻炼我的编码技能,又能极大提高编码速度,拥有自己的代码感觉真的很棒。同时,这种代码积累对未来类似任务也很有益。
大多数人的方法无法击败基线,可能是因为他们只是简单地将3D数据输入网络进行训练。我一开始也这样做,但结果很差。GUANSHUO XU的第一名解决方案告诉我,裁剪ROI非常重要。也许是因为在3D分类任务中,网络很难从几千个训练数据中就学会ROI。因此我认为分割每个器官是重要的第一步。
由于肠道和渗出物有2D分类标签,我决定对两者都使用2D分类方法,而对肝脏、脾脏和肾脏使用3D分类方法。
通过Selim的第四名解决方案(CSN)和IAN PAN的第六名解决方案(X3D),似乎使用 transformer 作为骨干网络在小训练数据量上效果不佳。最终我选择 X3D_l 作为3D分类器。
接下来是为肠道和渗出物分类设计2D + 1D方法。根据QISHEN HA的第一名解决方案和Đăng Nguyễn Hồng的第一名解决方案,convnext 是2D特征提取器的好选择。根据Guanshuo Xu的第一名解决方案,lstm + attention pooling concat maxpooling 模型被选作特征融合。
对于分割,由于我在上一次竞赛 hubmap-hacking-the-human-vasculature 中已经编写过2D分割代码,因此决定早期实验中直接训练2D UNet。后来我发现2D UNet分割脾脏效果不佳(可能是我训练技术不好),于是使用3D UNet,仅输入2D UNet粗分割的边界框裁剪数据来进一步优化脾脏分割(脾脏Dice:0.880 -> 0.943)。
在简要阅读其他获胜队伍的解决方案后,我列出了一些未来可能尝试的技巧。
resnet18 裁剪器官、使用 RNN 聚合前一个模型的信息并直接优化竞赛指标Mask2Former 思想、使用图像级标签辅助特征学习、裁剪方法max(logits, gt) 而非 gt(因为图像级标签噪声)、region_crop() 移除外部黑色区域