第一次完整打下kaggle,写一个记录贴。
这个比赛是多标签分类,要求检测多个器官是否有创伤。CT数据,数据集明显的分布不均,不损伤:损伤大概是在1:10左右。
我们整个完整的解决方案分成三个部分:
Part1: 2D segmentation模型[Stage 1]
Part2: 2DCNN + 3D融合整张图检测[Stage 2]
Part3:2.5DCNN 单个器官检测[Stage 2]
Data Preprocessing
1.dicom文件读取需要做一些预处理,不然对比度很差。
预处理的地方我们其实还踩了挺大的坑,因为在扫描的时候如果佩戴金属时图像会有一些亮度很高的地方,如果预处理方法不当就会导致图像全黑。
2.归一化是最简单的/255。
3.所有人扫描的张数是不一样多的,器官出现的范围也不相同,因此我们需要根据分割结果选择切片范围。
【这个地方我们也花费了很多时间,因为分割的时候有些器官容易误分,这会导致很多没有器官的切片被选中】。
Augmentations
我们看了历年RSNA举办的比赛,发现有些比赛私榜和公榜shake得非常厉害,因此我们其实挺注重过拟合的问题,但在我们的尝试下,最终只选择了以下的数据增强方式:
transforms_train = A.Compose([
A.Resize(image_sizes[0], image_sizes[1], interpolation=cv2.INTER_LINEAR),
A.HorizontalFlip(p=0.5),
A.VerticalFlip(p=0.5),
A.ShiftScaleRotate(shift_limit=0.2, scale_limit=0.2, rotate_limit=20, p=0.5),
A.OneOf([
A.GaussianBlur(),
A.MotionBlur(),
], p=0.3),
A.OneOf([
A.GridDistortion(num_steps=5, distort_limit=0.05, p=1.0),
A.OpticalDistortion(distort_limit=0.05, shift_limit=0.05, p=1.0),
A.ElasticTransform(alpha=1, sigma=50, alpha_affine=50, p=1.0)
], p=0.3),
])
但实际上我到后期已经放飞了,由于一开始我们划分五折每一折单独训,但后来变成每个epoch训一折循环训,所以验证集也加了transform希望能验得准一点但发现也没什么用。
Stage2:整图检测
-
切片范围选择
首先,每个器官卡阈值得到器官出现范围。除了误分以外,由于扫描的范围不同,有的人是半身有的人是全身,因此有的器官根本就没出现。我们希望切片的范围包括这个人扫描到的所有器官的大部分,再卡了个上下界。 -
2.5D切片块
我们在这个得到的范围内正态采样,取每个采样切片的前后一张组成切片块。比如采样9张,最后得到的就是[9,3,256,256]形状。 -
网络结构
首先这9个是先和Batch size维度拼在一起进2DCNN,最后几层再回去进3DCNN。Backbone选择的是EfficientNetv2,试过ResNet,感觉容易过拟合。 -
Loss
由于分布不均,一开始简单用了Focal loss和weighted cross entropy。曾经精细确定weighted参数但是发现不如随手一设的好用。后来加上了Mean-Variance loss涨了34个点。
Stage2: 单个器官检测
因为一开始训的时候,整图有些器官检测得很差,并且有些器官是二分类,有些器官是三分类。所以花了挺大力气打算训一个超级巨无霸,但是效果没有预想中的好,我觉得可能是因为切片采的不够多。
器官就采用单个器官出现的范围采样,加上±1张切片和mask,形状是[num, 3,256,256]。每个器官采样的张数不一样,器官大小本身不一样。
肾有两个,因此右肾我们水平翻转了一下和左肾拼起来送进去。
backbone是EfficientNetv2+RNN。
Ensemble:
整图预测挑了两折,和单器官预测融合。本来权重上想把整图里分的不是很好的器官设低的,但最后发现单器官检测效果也没有很好。
其他无效尝试:
- 引入Patero尝试在平衡多loss,发现没用,因为时间不多没有接着尝试,感觉可能在哪一步出现问题。
- PAN,因为觉得器官大小不一需要多尺度的感觉效果不大。
- 加了all injury分支,发现容易过拟合。
没尝试但可能会有用的:
- StratifiedKFold
- 单张slice的标签信息,因为测试集不会有这个信息所以当时没用
一些经验
我们用分割模型其实有点晚,导致后面其实时间很紧,最后的模型完全是在一周之内训出来的,非常极限。下一次一定要同步各个部分。