竞赛排名:第2名
作者:qdv206 和 Pham Van Linh
2023年8月4日
衷心感谢Kaggle和HuBMAP组织了这场非常有趣的比赛。这是与我的长期队友@phamvanlinh143的联合撰写,他在这次比赛中完成了大部分艰苦工作。
总结
这场比赛特别棘手,需要解决几个关键问题:
- 公共测试集和私有测试集结构不同,私有测试集来自未见过的WSI(全切片图像)。公共测试集规模很小,导致LB(排行榜)完全不可靠
- 扩张操作在公共LB上产生的奇怪效果
幸运的是,我们制定了应对这些问题的策略:
- 建立可靠的CV(交叉验证)并信任它
- 训练大型多样化的模型集成以确保稳定性
- 提交两个版本:带扩张和不带扩张的集成模型
交叉验证
要建立值得信赖的CV,必须尽可能模拟私有测试集的生成方式:
- 验证必须使用Dataset1的标签
- 训练集和验证集不能包含相同的WSI
简单的方案是使用Dataset1-WSI1作为验证折,Dataset1-WSI2作为另一折,但这会丢失大量训练样本。我们采用的方法是:
- 利用元数据将每个WSI的Dataset1切片分为左侧和右侧,形成4折:
- Dataset1 – WSI1 - 左侧
- Dataset1 – WSI1 - 右侧
- Dataset1 – WSI2 - 左侧
- Dataset1 – WSI2 - 右侧
- 使用
staintools为每个训练切片生成9个转换样式后的变体(模仿Dataset3中的9个额外WSI)。当采样切片与验证集来自相同WSI时,改用生成的变体进行训练

模型训练
输入数据
使用两种数据类型:
- 原始切片
- 填充切片(类似@hengck提出的方案):使用相邻切片在原始切片周围填充128像素,推理时预测填充区域后中心裁剪

数据增强
应用了强增强策略:
- 染色增强:与验证集同WSI的切片p=1.0,否则p=0.5
- 几何与色彩变换:RandomRotate90、RandomFlip、ElasticTransform、ShiftScaleRotate、RandomBrightnessContrast、HueSaturationValue等
- AutoAugment(类似DETR训练配置)
训练细节
仅针对血管类别进行两阶段训练:
- 阶段1:使用3折Dataset1 + 全部Dataset2训练30个epoch
- 阶段2:仅在3折Dataset1上微调15个epoch
- 从微调阶段选取5个检查点进行SWA(随机权重平均)得到最终模型
模型架构
采用Cascade Mask-RCNN模型,包含以下骨干网络:
- swin-t
- coat-small
- convnext-t
- convnext-s
在mmdet 2.x框架下训练,最终集成包含折模型和全数据模型。
后处理
按以下标准过滤掩码:
- 肾小球过滤:移除在肾小球区域内面积超过60%的掩码
- 置信度过滤:移除置信度<0.01的掩码
- 像素集成过滤:统计每个像素被多少模型预测为血管,计算q=0.05分位数作为阈值,移除所有像素计数均低于阈值的掩码
- 实例集成过滤:执行NMS(IoU=0.65),移除重叠掩码数量低于q=0.075分位数的掩码
- 小掩码过滤:移除像素数少于64的掩码
扩张与否的抉择
我们观察到扩张操作在公共LB上产生显著分数变化,但CV中完全无效。虽然主办方确认公私测试集使用相同验证流程,我们仍无法信任扩张。利用双提交机会:
- 带扩张:公共0.551,私有0.526
- 不带扩张:公共0.465,私有0.588
后续测试表明,单个骨干网络不带扩张的提交即可进入私有金牌区(公共LB仅0.4x)。尽管我们因信任CV做出了正确选择,公共LB的这种行为仍是未解之谜。
感谢阅读,欢迎提问交流。