kaggle RSNA 比赛过程总结(python,教程,人工智能,随笔,编程语言)

时间:2023-9-24 作者 : 石家庄SEO 分类 : 编程语言
  • TAG :

引言

算算时间,有差不多两年多没在打kaggle了,自20年最后一场后(其实之前也就打过两场,一场打铁,一场表格赛是金是银不太记得,当时相当于刺激战场,过拟合lb大赛太刺激了,各种trick只有敢想就敢做,但最近发现账号都忘了),RSNA开赛那段时期,有个群里正好有人说要参加,具体啥情况忘了,然后我正值年底,阳了后又恍恍惚惚参加了一场考试,转阴后方觉大梦一场,梦醒茶凉(当然,这只是我现在的说辞,从11月发生了太多意料之外的事情,我现在也只能用一梦黄粱来搪塞),需要做一些事情排解一下新年的迷茫与惆怅,于是顺势就加入开整。不过这一整,又收获了更多煎熬,但也把我过剩的精神内耗挥霍了一部分,这不得不说也算另一种buff转移了。关于最后拿到了bronze medal,我只能说很遗憾,又比较幸运,因为整个比赛过程期间我都苦于算力,很多想法没有付诸于行动,做了Rashaad,虽然我并不想。比赛最后几天,我将lb中0.52的方案融进了自己的base里,然后就没有跑了,可能我离我心中的成功就差两张3090或者4080的距离,但这距离,已经形如沟壑(PS:其实应该去用云平台的,中途也看到几个不错的),所以本篇主题,算是对之前的一个回忆帖,也算一个总结帖。

赛题数据分析

赛题说明为:

The goal of this competition is to identify breast cancer. You’ll train your model with screening mammograms obtained from regular screening.

Your work improving the automation of detection in screening mammography may enable radiologists to be more accurate and efficient, improving the quality and safety of patient care. It could also help reduce costs and unnecessary medical procedures.

赛题图像数据为:

one fold only.train images : num_patient = 9530 num_image = 43771 cancer0 = 42854 (0.979) cancer1 = 917 (0.021)validation images : num_patient = 2383 num_image = 10935 cancer0 = 10694 (0.978) cancer1 = 241 (0.022)

即总共加起来5w多张,可视化为:

def has_cancer(l): return len(l) == 2 or (len(l) == 1 and l[0] == 1)patient_cancer_map = train.groupby('patient_id').cancer.unique().apply(lambda l: has_cancer(l))fig, ax = plt.subplots(1,2,figsize=(20,5))sns.countplot(patient_cancer_map, palette='Paired', ax=ax[0]);ax[0].set_title('Number of patients with cancer');sns.countplot(train.groupby('patient_id').size(), ax=ax[1])ax[1].set_title('Number of images per patient')ax[1].set_xlabel('Number of images')ax[1].set_ylabel('Counts of patients');

在这里插入图片描述

我们能得出来的信息为:

  • 数据样本是高度不平衡的,比例差距接近50:1
  • 而在大多数情况下,患者的样本数一般为4张,但有些患者的picture提供了10张,这很奇怪

进一步针对target分析为:

biopsy_counts = train.groupby('cancer').biopsy.value_counts().unstack().fillna(0) biopsy_perc = biopsy_counts.transpose() / biopsy_counts.sum(axis=1)fig, ax = plt.subplots(1,2,figsize=(20,5))sns.countplot(train.cancer, palette='Reds', ax=ax[0])ax[0].set_title('Number of images displaying cancer');sns.heatmap(biopsy_perc.transpose(), ax=ax[1], annot=True, cmap='Oranges');

在这里插入图片描述
这里可以获得的insight为:

  • 显示癌症的图像数量非常少。这应该比癌症患者的人数还要少。
  • 从活检特征来看,我们可以说所有癌症患者都进行了活检。但只有大约3%的没有癌症的图像进行了后续活检。也许我们应该在患者层面上了解一下这一功能。

这也是后续我将介绍的一个trick,这里先按下不提。

至于更详细的EDA,可以查看public公开的gold medal notebooks,以及discussion,这里不再详述。

该赛题的评价函数为:

p F 1 = 2 p P r e c i s i o n ⋅ p R e c a l l p P r e c i s i o n + p R e c a l l pF_1 = 2\frac{pPrecision \cdot pRecall}{pPrecision+pRecall} pF1=2pPrecision+pRecallpPrecisionpRecall

其中 p P r e c i s i o n = p T P p T P + p F P pPrecision = \frac{pTP}{pTP+pFP} pPrecision=pTP+pFPpTP p R e c a l l = p T P T P + F N pRecall = \frac{pTP}{TP+FN} pRecall=TP+FNpTP

这就是常说的pf1值了,但是在这种高度不平衡类别下,用pf1值是有很大波动情况的,所以这里也算是一个不稳定的trick,好用是真好用,但过拟合可能也是真过拟合。介绍完赛题,下面是我的一个心路历程。

初期——摇摇乐环节

为什么取这个名字,是因为可能相当多人,如果不是非常纯小白,都算是有自己的一个弹药库的,即或多或少看过以及会去找之前的方案,然后直接套用,就简单过一下数据,先用之前方案跑了再说,生死有命富贵在天,一人得道鸡犬升天。这个时期,public是混乱的,但也是文艺复兴,不管专业不专业,先提出自己见解,有人觉得不对就delete,emmm。。。

然后我这边也是豪言壮语,各路大神各显神通,有位老板直接说上efficientb8,batchsize为128,参数拉大(但往往,越带有别样激情的,被拷打后,也是越容易放弃的),我的另一个高中生队友,直接给了一个large_kernel,为:

class LargeKernel_debias(nn.Conv2d): def forward(self, input: torch.Tensor): finput = input.flatten(0, 1)[:, None] target = abs(self.weight) target = target / target.sum((-1, -2), True) joined_kernel = torch.cat([self.weight, target], 0) reals = target.new_zeros( [1, 1] + [s + p * 2 for p, s in zip(self.padding, input.shape[-2:])] ) reals[ [slice(None)] * 2 + [slice(p, -p) if p != 0 else slice(None) for p in self.padding] ].fill_(1) output, power = torch.nn.functional.conv2d( finput, joined_kernel, padding=self.padding ).chunk(2, 1) ratio = torch.div(*torch.nn.functional.conv2d(reals, joined_kernel).chunk(2, 1)) power_ = torch.mul(power, ratio) output = torch.sub(output,power_) out = output.unflatten(0, input.shape[:2]).flatten(1, 2) return out

听说在上一个比赛是好用的,但这个比赛因为前期没做好预处理,300G数据我这服务器磁盘空间都不够,根本处理不了,就直接使用public公开的512 * 512的数据集,顺带加了个二阶优化器,结果就是代码没什么问题,数据问题很大,一个epochs用我的rtx 5000单卡就三小时一个,跑得我惊了,直接惊为天人,还是改回了adam,后续老板机跑得咋样我忘了,因为模型就没给我了。

当然,中间还发生了很多事情,做了很多奇思妙想以及胡思乱想式编码,因为我也是两年多没学套路了,顺带把没走过的坑再重新走一遍,当成一种学习与修炼(大雾)?紧接着就到了新的一年。

baseline前——无序转有序

如果说为什么在队友全躺的时候,我连算力都没有,但还依然坚持走完全程,大概就是有青蛙佬hengck23的方案公开吧,从前期到最后,他的大部分工作都出于分享式的,算是在这个比赛对我影响最大的,我也学会了很多,在1月的时候,发觉不能这样毫无方向实验了,于是开始看他的实验记录:

本文:kaggle RSNA 比赛过程总结的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:Kaggle比赛:用深度学习模型寻找外星人下一篇:

17 人围观 / 0 条评论 ↓快速评论↓