返回列表

4th place solution

558. Vesuvius Challenge - Ink Detection | vesuvius-challenge-ink-detection

开始: 2023-03-15 结束: 2023-06-14 医学影像分析 数据算法赛
第四名解决方案 - 火山口挑战墨水检测
比赛排名: 第4名
作者: 3rd Company 3rd Platoon Leader
发布时间: 2023-06-17

第四名解决方案

致谢

我非常感激组织这次极具挑战性和精彩绝伦的比赛。 我感觉到有很多非常优秀的人,我尊敬他们所有人。 我想向比赛的组织和参与者表达我的感激之情。


解决方案

我想按照性能改进的贡献程度来描述我的解决方案。 下面描述中的★数量表示对性能改进的贡献程度。


1. 时序随机裁剪 & 随机粘贴 & 随机遮挡 (★★★★★)

1.1 对数据本身的思考

如上图所示,我认为碎片的特定层不会与其他碎片的相同层相对应。基于这些点,我想出了一种增强方法,通过反映数据的特征来给模型提供强烈的正则化。

1.2 应用方法

如上图所示,有三个步骤:
1) 时序随机裁剪

  • 首先,我决定使用65层中的22层(21-42层)。在这22层中,随机裁剪cropping_min到cropping_max范围内的层。经过多次消融实验,我设置cropping_min = 12,cropping_max = 22。

2) 随机粘贴

  • 随机裁剪的层在保持时序信息的同时被粘贴到22个随机区域。
    这种裁剪和粘贴方法使模型能够学习广泛、多样的层范围,而不是固定区域的碎片,从而泛化到学习各种碎片。

3) 随机遮挡

  • 类似于空间遮挡增强,我应用了时序遮挡增强。在粘贴的层中,0到2个随机层被填充为0值。

以上三个过程可以通过查看下面的PyTorch Dataset代码部分来简单理解。


2. 低假阳性权重选择 (★★★★)

如下图所示,我为每个epoch保存了预测掩码。文件名包含epoch、分数、tp、fp和fn,其中fp值很重要。即使分数相似,如果fp很大,在公开分数中往往表现很差。 因此,我希望选择fp值小且分数值高的权重,我通过多次提交为每个fold选择了合适的fp值。此外,我尝试通过集成具有不同fp值范围的模型来提高泛化性能。


3. 使用的模型与集成 (★★★★)

我集成了3个模型:

  • 3D resnet152, 3D resnet200, 3D resnext101,带有unet-like解码器。

  • 参考模型首先受到JEBASTIN NADAR的启发并应用。感谢你的努力,尊敬你。
    3D resnet152, 3D resnet200来自 https://github.com/kenshohara/3D-ResNets-PyTorch
    3D resnext101来自 https://github.com/okankop/Efficient-3DCNNs
    所有模型都有MIT许可证,不违反规则。

  • 3D Resnet在Kinetic 710上预训练,3D resnext101在Kinetic 600上预训练。
    在kinetics上训练与不训练之间有巨大差异。 因此,在比赛期间,我试图找到在kinetic 600或700上训练的模型。

  • 所有模型都结合了unet-like简单解码器。3D编码器的特征通过解码器上采样并连接。
    详细信息在代码中。


4. 标签平滑(0.3)、cutmix增强、数据裁剪 (★★★)

  • 带标签平滑的交叉熵提高了性能。经过消融实验,我将标签平滑参数设置为0.3
  • Cutmix增强在交叉验证和公开分数中提高了性能
  • 受AJLAND启发,我将图像裁剪在50以下和200以上。也感谢你的努力,尊敬你。
    (image = np.clip(image, 50, 200))


5. 对本地交叉验证的信念 (★★)

如下表所示,这两个模型是我最终提交的。
Ensemble 2的公开分数比ensemble1低,但在交叉验证中表现更好。 还有其他可以采用的模型,但考虑到它在交叉验证中表现良好,所以被采用,在私有分数中性能进一步提升,最终获得了更好的第一名成绩。

模型 CV分数 阈值 公开分数 私有分数
Ensemble 1 0.66 / 0.762/ 0.723 / 0.68 0.5 0.795835 0.663542
Ensemble 2 0.67 / 0.764 / 0.724 / 0.69 0.47 0.789024 0.674544


6. 其他训练细节 (★)

6.1 损失、优化器、调度器

  • 损失:带标签平滑0.3的CrossEntropyLoss
  • 优化器 = AdamW(lr=1e-4)
  • 调度器 = 带warmup的余弦退火

6.2 交叉验证策略与结果

我用4折训练模型:

  • fold1:碎片1
  • fold3:碎片3
  • fold2, 4:碎片2分成2个子碎片(9506 x 14830 -> (4300 x 14830) & (5206 x 14830))

结果如下表所示。
Ensemble表示用相同权重集成3个模型。

模型 CV分数 阈值 公开分数 私有分数
3D Resnet152 0.64 / 0.71 / 0.71 / 0.69 0.5 0.78 -
3D Resnet200 0.66 / 0.71 / 0.69 / 0.66 0.5 0.77 -
3D Resnext101 0.61 / 0.72 / 0.71 / 0.64 0.5 0.77 -
Ensemble 0.66 / 0.762/ 0.723 / 0.68 0.5 0.795835 0.663542
Ensemble 0.67 / 0.764 / 0.724 / 0.69 0.47 0.789024 0.674544

6.3 图像增强

所有概率设为0.6

  • 水平、垂直翻转
  • RandomGamma(limit=(50, 150))
  • RandomBrightnessContrast(brightness=0.2, contrast=0.2)
  • 高斯噪声(10, 30)、高斯模糊
  • 平移0.1、缩放0.1、旋转360度
  • coarsedropout(孔洞=4, 大小=0.2 * 图像尺寸)

6.4 数据准备

  • 步长率3
  • 图像尺寸256

6.5 其他

  • 为了获得一致且稳定的结果,我基于阈值0.5选择了最佳方法。
  • 推理步长为(256 / 5)


7. 尝试但未奏效的方法

  • mixup增强
  • 时序通道混洗增强
  • 3D transformer编码器(uniformerv2, video swin transformer) - 无法训练... 不知道为什么损失不下降。
  • 空间TTA
  • 时序TTA - 因为上述的裁剪粘贴方法,我尝试了时序TTA。也就是说,我尝试通过以各种方式裁剪22、20和18层然后平均3次预测来进行TTA,有时性能提高有时下降。因为太耗时所以没有应用。
  • 其他损失(tversky focal loss, fbeta loss)


8. 代码

8.1 GitHub版本(基于Docker)

8.2 Kaggle Notebook版本

同比赛其他方案