625. RSNA 2024 Lumbar Spine Degenerative Classification | rsna-2024-lumbar-spine-degenerative-classification
与其他参赛者类似,我们实现了一个由三个核心模型(加上一个用于预训练的额外模型)组成的两阶段系统:
有关详细的训练 specifics,请参考附带的代码。
我们最初尝试了边界框检测器和分割模型,但关键点提供了最好的结果和灵活性。模型输出 6 对 XY 坐标(共 12 个),其中 5 对用于矢状面图像,1 对用于轴向图像。我们采用了 修正的数据集标签,由 @brendanartley 分享。这允许我们使用倾斜裁剪,尽管性能提升微乎其微。
损失函数基于欧几里得距离,并应用掩码以避免在矢状面图像中传播轴向关键点误差,反之亦然。我们还在池化 (pooling) 之前将位置编码引入骨干特征,以增强模型性能。
对于轴向图像,我们开发了一个简单的图像模型来预测相应的级别。一些元数据与骨干特征连接以增强模型性能。
我们观察到偶尔的预测不一致(例如,在同一系列中 L5-S1 预测在 L1-L2 旁边)。为了解决这个问题,我们将任务重新定义为回归问题,预测 0.0 到 1.0 之间的值,间隔为 0.25(例如,L1-L2 为 0.0,L2-L3 为 0.25 等),使用均方误差 (MSE) 作为损失函数。这种方法更严厉地惩罚远离真实值的预测。
利用解剖对称性,我们使用研究 - 级别 - 侧输入训练了一个模型。
详情如下所述。
我们使用关键点和级别模型创建补丁,每个轴向补丁对应一个或多个脊柱级别。由于级别模型是回归模型,我们应用了带有公差范围的阈值来捕获额外的上下文。例如,对应于 L2-L3(0.25 输出)的补丁可以跨越 0.10 到 0.40。
为了确保一致性,我们在每个平面保持了统一的像素间距。我们使用了 96x96 的补丁。矢状面补丁在顶部和底部偏移以防止级别泄漏。
示例:
在训练序列模型之前,我们使用相同的损失函数(稍后定义)使用单个补丁预训练了一个补丁模型。这一步显著提高了序列模型的收敛性。
2D 模型 + 编码器 - 解码器 Transformer。
该架构结合了 2D 图像模型与编码器 - 解码器 Transformer。我们发现最好的骨干网络是 regnetz_b16.ra3_in1k 和 hgnet_tiny.ssld_in1k。
元数据(修改后的 XYZ 世界坐标)被馈送到编码器,而图像特征被传递到解码器。我们在解码器中添加了三个可学习向量,每个代表一种疾病分类(类似于 CLS 令牌)。测试了各种池化策略,包括 max/mean pooling 和 attention pooling。
该模型设计为灵活的,允许它处理整个研究或单个级别 - 侧。这种适应性使我们能够在级别 - 侧训练模型,而在整个研究上评估它。
如何处理脊柱(狭窄)?
由于脊柱狭窄影响中心而不是特定侧,我们在训练期间为两侧复制了标签。在推理时,我们在将可学习向量传递到分类头之前聚合了两侧的向量(解码器中添加的那些)。我们测试了多种聚合方法,最终选择了 max pooling。
我们使用了 PyTorch 中实现的特定于竞赛的损失函数。虽然我们探索了几种变体,例如竞赛损失的 focal 版本,但都没有产生显著更好的结果。
| 描述 | 骨干网络 | 本地平均 CV | 公共榜单 | 私人榜单 |
|---|---|---|---|---|
| 最佳公共榜单:集成 4 个模型(去掉 1 个)TTA 20 | regnet | 0.4027 | 0.3452 | 0.4121 |
| 最佳本地验证:集成 5 个模型 TTA 40 | hgnet | 0.3883 | 0.3612 | 0.4215 |
| 最佳私人榜单:集成 5 个模型 TTA 16 | regnet | 0.4076 | 0.3472 | 0.4118 |
选定的两个提交分别是本地验证最好的和公共榜单最好的。公共榜单最好的提交在私人榜单中排名第 3。