404. RSNA STR Pulmonary Embolism Detection | rsna-str-pulmonary-embolism-detection
感谢北美放射学会 (RSNA®)、胸放射学会 (STR) 和 Kaggle 主办这场有趣的比赛。感谢 Nvidia 提供计算资源。
这是我参加过的最喜欢的比赛之一。我 enjoyed 构建一个复杂的多阶段堆叠模型管道!处理 3D 图像很有趣,相比 2D 图像提供了额外的挑战。我特别喜欢解决在训练数据量达到 1_000_000_000_000 bytes(1万亿字节!)的情况下构建快速实验管道的挑战。这是我处理过的最大的数据集。
在下图中,每一行代表一次检查(即研究,即单个患者)。这一行图像是患者胸部 3D 图像的 CT 扫描“切片”。在本次比赛中,我们需要为每位患者(每一行)预测 9 个目标(如左侧是否有 PE?右侧是否有?等),并且需要对每张图像进行分类(是否存在 PE?)。如果下图是所有数据,那么我们需要预测 3 行 * 9 个目标 = 27 个检查目标 和 15 张图像 * 1 个目标 = 15 个图像目标。总共需要预测 42 个目标。
在描述页面上,该指标看起来非常令人困惑。然而,它只是 10 个对数损失(log losses)的加权平均值(9 种类型的检查预测和 1 种类型的图像预测)。(我在这里解释了该指标)。计算完 10 个权重后,我们发现 LB 分数的 50% 来自 9 个检查预测,50% 来自图像预测。此外,图像预测的对数损失本身也是一个加权对数损失,其中属于没有肺栓塞的检查的图像权重为零(非常重要的发现!)
inp = tf.keras.Input(shape=(320, 320, 1)) # 输入为 UINT8
x = tf.keras.layers.Concatenate()([inp/255., inp/255., inp/255.])
base_model = efn.EfficientNetB4(weights='imagenet', include_top=False)
x = base_model(x)
x = tf.keras.layers.GlobalAveragePooling2D()(x)
x = tf.keras.layers.Dense(1, activation='sigmoid')(x)
model = tf.keras.Model(inputs=inp, outputs=x)
opt = tf.keras.optimizers.Adam(lr=0.000005)
model.compile(loss='binary_crossentropy', optimizer = opt)
model.fit(X, y, sample_weight = X.groupby('StudyInstanceUID')
.pe_present_on_image.transform('mean') * 5.6222 )
我构建了两个模型。模型一预测图像级预测(即 pe_present_on_image),模型二预测患者级预测(即检查/研究,如 leftsided_pe 等)。
imagenet 上预训练的 EfficientNet B4uint8LR = 5e-6