返回列表

15th Place Solution

625. RSNA 2024 Lumbar Spine Degenerative Classification | rsna-2024-lumbar-spine-degenerative-classification

开始: 2024-05-17 结束: 2024-10-08 医学影像分析 数据算法赛
第 15 名解决方案 - RSNA 2024 腰椎退行性分类

第 15 名解决方案

作者: Sumo, Viktor Cikojevic
发布日期: 2024-10-11
比赛: RSNA 2024 腰椎退行性分类 (RSNA 2024 Lumbar Spine Degenerative Classification)

祝贺所有获奖者,以及那些在完成这次比赛后发现自己成为更好数据科学家的人们!尽管离金牌还差 2 个名次,但我们发现这次比赛非常有趣,因为没有简单直接的方法来解决这个问题,这使得它更加有趣。

最重要的是,我要感谢 @viktorcikojevic 与我组队参加这次(以及许多过去的)比赛。如果没有他,我不可能走到这一步。

概述

在更高层面上,我们的 pipeline 如下图所示:

Pipeline 概述图

它由三个阶段组成:

  1. 关键点检测阶段 (Keypoint detection stage)
  2. 裁剪提案阶段 (Crop proposal stage)
  3. 裁剪分类阶段 (Crop classification stage)

关于为何选择此设计的简要说明:

  • 此 pipeline 应允许所有模型在 每张图像 (per-image) 级别上进行训练,而不是 每位患者 (per-patient) 级别。只有大约 2000 名患者,所以我们认为这是更好地利用所有数据并防止过拟合的方法。
  • 每个模型的输出之间可以推断出很多信息,这允许我们给模型包含一个有用的偏置。例如,我们知道 T2 序列正好运行在人体的中心,所以他们左侧的所有 T1 关键点都是左侧 T1 关键点,右侧同理。这意味着我们可以 shortcuts 模型必须学习的内容。
在实现方面,这意味着我们做了以下工作:
  • 在关键点检测阶段,我们的 T1 关键点模型将只预测 5 个类别:L1/L2, L2/L3, L3/L4, L4/L5, L5/S1 而不是 10 个。在此阶段不预测左右侧。
  • 在关键点检测阶段,我们的轴向 (Axial) 关键点模型将只预测 2 个类别:左侧和右侧关键点,而不是 10 个。不预测层级。
  • 裁剪分类器的工作是接收一个裁剪图像,并输出 3 个 logits - 轻度 / 中度 / 重度 - 它不预测条件。
  • 裁剪提案阶段做 3 个主要工作:
    • 填充每个 T1 关键点的左右侧(因为关键点模型只知道层级)
    • 填充每个轴向关键点的层级(因为关键点模型只知道左右侧)
    • 将每张图像的预测聚合为每位患者的最终 25 个关键点。

在下面的部分中,我们将更详细地描述每个阶段。

关键点检测阶段

在这里,我们开发了一个分割模型,为每张图像输出关键点地图。对于每个条件,我们使用 timm 骨干网络训练 SMP (Segmentation Model Pytorch) 模型。该模型将 3 个连续的 instance_number 通道作为输入,并输出多通道热力图。

T2 关键点模型

对于 T2 模型,我们直接使用 @brendanartley 在这里分享的数据集:https://www.kaggle.com/datasets/brendanartley/lumbar-coordinate-pretraining-dataset

由于我们在剩下一个月时才加入,我们没有找到利用左侧关键点的方法,所以我们只使用右侧关键点进行训练。

T1 和 轴向 关键点模型

对于 T1 和轴向关键点模型,我们直接信任标注的关键点原样并使用它们训练我们的模型。主要是因为我们要偷懒(去除所有标注噪声),而且我们也稍微有点时间紧迫。

我们认为可以承受一些标注噪声的一个原因是,我们采取了 shortcuts 来最小化模型训练的标签内容,即 T1 模型不关心关键点的左右侧,所以我们对左右翻转具有鲁棒性;轴向模型不关心层级,所以我们对层级标签的任何噪声具有鲁棒性。

裁剪提案启发式方法 (Crop Proposal Heuristic)

我们使用启发式方法从输出关键点到患者的最终 25 个关键点。它需要完成 3 件事:

  • 填充每个 T1 关键点的左右侧(因为 T1 关键点模型只知道层级)
  • 填充每个轴向关键点的层级(因为轴向关键点模型只知道左右侧)
  • 将每张图像的预测聚合为每位患者的最终 25 个关键点。

裁剪提案启发式方法的概述如下所示:

裁剪提案启发式方法概述

步骤 1: Argmax T2 实例编号 (Instance Number)

这一步相当简单:对于 5 个 T2 层级中的每一个,我们从关键点模型中找到置信度最高的实例编号。此步骤结束后,我们为患者获得了 5 个 T2 关键点。

步骤 2: 推断 T1 左右侧

因为我们从上一步知道了 T2 关键点,我们现在可以使用 DICOM 的元数据计算世界坐标系中的 XYZ 位置。
这样做会告诉我们要脊柱的 XYZ 坐标,其中 X 轴从患者的右手方向指向左手。所以现在推断左右侧相当 trivial:

对于 L1/L2 层级上的给定 T1 关键点,如果其 X 值高于其 L1/L2 层级上的 T2 值,那么它是左侧关键点,否则它是右侧关键点。

此操作在确定每个 T1 关键点的左右侧方面具有 97% 的准确率,其余 3% 要么是 T1 关键点未被检测到,要么是标注噪声。

有一些边缘情况需要处理,这将此步骤的逻辑转变为:

对于 L1/L2 层级上的给定 T1 关键点,如果其 X 值高于其 L1/L2 层级上的 T2 值,那么它是左侧关键点,否则它是右侧关键点

但是如果 L1/L2 层级上的 T2 未被检测到,则改用 L2/L3 层级上的 T2,如果那个也缺失,则使用 L3/L4 上的 T2,依此类推。

步骤 3: Argmax T1 实例编号

差不多是将步骤 1 应用于 T1 关键点 - 对于每个左右侧和层级,我们找到哪个 instance_number 具有最高的置信度。
这一步为我们提供了患者的 10 个最终 T1 关键点。

步骤 4: 猜测缺失的 T1 关键点

在任何 T1 关键点缺失的情况下,如果其“双胞胎”存在,则只需将其镜像过来即可:

如果 T1 左侧 L1/L2 缺失,围绕 T2 L1/L2 镜像 T1 右侧 L1/L2,并盲目地声称那是 T1 左侧 L1/L2 的位置。

这一步对 CV(交叉验证)分数有轻微改进(大约 0.001 到 0.002)。

步骤 5: 推断轴向层级

因为我们知道 T2 关键点,每个都有其层级。然后我们可以用它来猜测每个轴向关键点应该具有什么层级。

对于给定的轴向关键点,使用其 XYZ 坐标查找其最近的 T2 关键点,并将该 T2 点的层级作为轴向点的层级。

此步骤容易受到缺失 T2 关键点的影响(例如,如果 T2 的 L2/L3 缺失,则没有轴向关键点可以正确地将 L2/L3 作为层级)。为了 combating 这个问题,
我们在推断轴向层级之前,对所有缺失的 T2 关键点进行线性插值。

此操作在每个轴向关键点的层级上也具有 97% 的准确率,其余 3% 主要是由 T2 关键点错误驱动的,这影响了层级查找,或者轴向关键点完全缺失。

步骤 6: Argmax 轴向实例编号

差不多是步骤 1,但现在应用于轴向关键点 - 对于每个左右侧和层级,我们找到哪个实例编号具有最高的置信度。
这一步为我们提供了患者的 10 个最终轴向关键点。

步骤 7: 猜测缺失的轴向关键点

遗憾的是,这一步对我们来说不存在。我尝试了许多方法来估算这些缺失的轴向关键点,但没有一个效果很好。
一个原因是,与通常只有一个点缺失且镜像可以解决问题的 T1 关键点不同,同一层级的轴向关键点通常一起缺失。

这里的所有实验都导致更差的 CV 分数,所以我们接受了事实,即我们无法做到这一点,只能缺失关键点..

裁剪分类阶段

在我们 pipeline 的最后是一个分类模型,它是一个 9 分类模型,构建如下:

裁剪分类模型结构

它是一个 timm 骨干网络和 3 个头 (heads),每个序列类型一个。每个头输出 3 个类别 - 给定图像的严重程度 如果 图像来自该序列类型。例如,如果图像是轴向图像,前向传递将其通过 timm 骨干网络 + 轴向头的红色路径,只有最后 3 个条目(关节下严重程度)被填充,T1 和 T2 logits 填充为 -100,以便 softmax 后的概率为 0。


非常感谢您阅读到这里。我们希望这提供了信息,或者至少具有娱乐性 :)

同比赛其他方案