434. Human Protein Atlas - Single Cell Classification | hpa-single-cell-image-classification
首先,感谢主办方举办这场有趣(且非常激烈)的比赛。这是我尝试的第二个计算机视觉项目,在此过程中我学到了很多东西。
我首先阅读了二十到三十篇关于弱标记图像分类和分割的最新论文,包括论坛上分享的论文以及我遇到的其他论文。我坚持每天记录进度,并维护一个单独的“待办事项”列表,随时记录我的想法。每当我感到停滞不前时,我总能回去找到新的方向。
当我加入比赛时,@bestfitting 在所有参赛者中处于绝对领先地位。因为 @bestfitting 赢得了第一届 HPA 比赛,我意识到他可能大量复用了之前的解决方案来取得这一成绩。他在之前的比赛后公开了代码和模型,所以我决定以此为起点,而不是 fork 任何公共 kernel。
我的第一个(可运行的)基线是使用 @bestfitting 的一个预训练模型,简单地将 HPAv1 的类别预测映射到 HPAv2。我对每张图像中的所有细胞应用相同的类别,没有尝试进行定位。HPAv1 集中没有“Negative(阴性)”这一类别,所以我从一个公共 kernel 复制了这些标签。在完全没有进行任何训练的情况下,这个基线让我超过了当时所有可用的公共 kernel。
尽管主办方试图挑选单细胞差异大的样本,但同一张切片中细胞之间的类别相关性仍然极高。因此,我认为本次比赛的决定性因素按降序排列为:
分割排在最后有两个原因:1. HPA 细胞分割器已经非常稳健,任何与其输出有显著偏差的行为都可能受到严厉惩罚;2. 缺乏细胞级真实标签,在我看来,这使得任何使用 Mask-RCNN 或其他分割模型来定义细胞边界的尝试都注定失败。如果有顶尖团队在这方面取得成功,我会感到惊讶。
因此,我在比赛初期花了大量时间完善我的图像级分类器,我怀疑这与当时大多数团队的做法相反。一旦 @h053473666 的 kernel 发布,比赛动态发生了显著变化,许多其他团队开始将图像级分类器整合到他们的集成模型中。
来自训练集和外部的 4 通道 RGBY 图像。我使用多线程文件下载器尽早获取了所有外部图像(即便如此,这也花了好几天时间下载)。没有尝试去除重复项等。
我的图像分类器将所有图像调整为 768x768,没有额外的预处理。
我的细胞分类器首先使用 HPA 细胞分割,然后将每个细胞填充为正方形,再进行掩膜和裁剪至 768x768。
相当标准的水平翻转、垂直翻转、转置以及随机裁剪。这对我的目的来说似乎已经足够了。
我使用了一种 HPA 分割器的实现,允许通过网络进行批处理,因为默认实现似乎是一次处理一张图像。我修改了标记函数,使其在 25% 缩放的掩膜上运行,以节省大量时间,尽管准确率有极轻微的损失。
我实施了一些启发式方法,根据细胞和细胞核相对于图像中平均细胞和细胞核的大小来排除边缘细胞。讨论区建议这不太重要,但我发现这对我的分数有非常显著的影响。
我使用了 @bestfitting 在 HPAv1 比赛中的架构,仅做了微调。该架构使用 DenseNet121 骨干网络,后接:
我还使用了 @bestfitting 的一个预训练模型作为微调的起点,这无疑减少了我的一点电费账单。😊
我对图像分类器和细胞分类器使用了相同的架构,并且两者都使用了相同的预训练模型。
我尝试了各种损失函数的组合。@bestfitting 将三个损失函数组合成一个总损失进行训练,而我尝试基于单一损失训练模型,然后将它们集成在一起。
在比赛中期,我转而使用混合精度训练,这给了我巨大的速度提升,而且需要的代码改动很少。我在以后的所有比赛中肯定会这样做。我在 Quadro RTX 5000 和 RTX 2080S 上进行训练。由于内存大小不匹配,并行运行时我只能使用 Quadro RTX 一半的内存