转载于Gary https://zhuanlan.zhihu.com/p/54743461
任务介绍
本次比赛的问题是场景识别 定位的是蛋白质所处位置的识别,例如在细胞液,细胞核里之类的 依输出分所属多标签分类(Multi-lable Classification)
难点及数据介绍
首先一张示例图如下:
外部数据处理后加入训练集,要制作一个好的验证集就得跨过两道坎
model config1
数据增广(亮度对比度调整,crop_resize,flip,other)
1.1、 我们总共用了12倍的TTA
1.2、亮度对比度主要用于让模型对外部数据和官方数据差异的鲁棒性更好
1.3、crop_resize对于显微镜下实例大小方差巨大的情况,带来了较好的线下收益 受限于调试成本,为了不避免数据增广带来的分布偏移问题,于是只选择性的尝试了上述几种
def get_augumentor(mode):
if mode =='train':
return iaa.SomeOf(n=(1,6),children=[
iaa.Noop(),
iaa.Sequential([
iaa.Add((-5,5),per_channel=True),
iaa.Multiply((0.8,1.2),per_channel=True)
]),
iaa.Crop(percent=(0,0.15)),
iaa.Affine(shear=(-16, 16)),
iaa.OneOf([
iaa.Affine(rotate=90),
iaa.Affine(rotate=180),
iaa.Affine(rotate=270),
iaa.Fliplr(1),
iaa.Flipud(1),
])
])
elif mode == 'TTA0':
return iaa.Noop()
elif mode == 'TTA1':
return iaa.Flipud(1)
elif mode == 'TTA2':
return iaa.Fliplr(1)
elif mode == 'TTA3':
return iaa.Affine(rotate=90)
elif mode == 'TTA4':
return iaa.Affine(rotate=180)
elif mode == 'TTA5':
return iaa.Affine(rotate=270)
elif mode == 'TTA6':
return iaa.Sequential([
iaa.Crop(percent=0.15),
iaa.Flipud(1)
])
elif mode == 'TTA7':
return iaa.Sequential([
iaa.Crop(percent=0.15),
iaa.Fliplr(1)
])
elif mode == 'TTA8':
return iaa.Sequential([
iaa.Crop(percent=0.15),
iaa.Affine(rotate=90)
])
elif mode == 'TTA9':
return iaa.Sequential([
iaa.Crop(percent=0.15),
iaa.Affine(rotate=180)
])
elif mode == 'TTA10':
return iaa.Sequential([
iaa.Crop(percent=0.15),
iaa.Affine(rotate=270)
])
elif mode == 'TTA11':
return iaa.Crop(percent=0.15)
else:
raise ValueError("aug error")
res18 (batchsize=64)
res34 (batchsize=32)
bninception (batchsize=32)
inceptionv3 (batchsize=32)
xception (batchsize=24, P40-24G)
se-resnext50(batchsize=24, P40-24G)
其中模型对batchsize大小十份敏感,正确来说是模型对参与batchnorm计算的样本数十分敏感,需用sync-bn或者P40(24G)显存实现
同时,如果按照榜上的分数来体现,融合有效的模型为res18,xception,se-resnext50,融合无效的模型原来是模型之间的差异性较小。
model config2
只简述一下与config1差异的部分
1. 优化器和schedule的不同
1.1、lr schedule
1.2、SGD 优化器(init=5e-2, momontum=0.9, weight_decay=4e-4)
1.3、cosine lr
2. 数据增强
fair_img_tsfm = Compose([
Flip(p=0.75),
Transpose(),
RandomBrightnessContrast(brightness_limit=(-0.25, 0.1), contrast_limit=(-0, 0)),
])weighted_img_tsfm = Compose([
ShiftScaleRotate(rotate_limit=45, shift_limit=0.1, scale_limit=0.1, p=1,
border_mode=cv2.BORDER_CONSTANT)
])
3. custom f1 loss
fair_img_tsfm = Compose([
Flip(p=0.75),
Transpose(),
RandomBrightnessContrast(brightness_limit=(-0.25, 0.1), contrast_limit=(-0, 0)),
])weighted_img_tsfm = Compose([
ShiftScaleRotate(rotate_limit=45, shift_limit=0.1, scale_limit=0.1, p=1,
border_mode=cv2.BORDER_CONSTANT)
])
4. 杂项
res18/34 (96batchsize + float16 + 过采样)
Threshold
在阈值的选取上,我们试过多种固定阈值,和search不同类不同阈值,但根据public榜的分数都没有很好的效果,最终选取了我手调适应public最高分的threshold=0.205
postprocess
基本是利用了伪重的性质 将测试集中的相似图片的预测进行共享,其中预测选择图片质量较高的那张,约0.002的收益
ensemble
外部数据灰度化和外部数据取高范数的通道两种方案得到了两份数据 两份数据上训练出来的模型进行差异化集成 model config1 和 config2进行集成
其中一个比较具有通用性的trick,可供大家参考 cnn with image patches (lb 0.619) 图片分成多个patch,将baseline模型对这些块输出分数,拿那些响应最高的patch重新训练一次模型, 相当于一个hard attention