imaterialist-product-2019比赛总结

为了更好地学习pytorch,同时大佬榕也推荐了这个比赛,就拿这个比赛练手。经过2个月左右的奋斗(划水),比赛结束了,成绩是34/96。不是一个很好的成绩,但是也不是一个很差的成绩。这次主要是对这次的比赛做个总结,总结经验,为后面的比赛做一个预备吧。

这次比赛是由三个人小队组成,我,大佬榕和小许。我是队长,写了所有的pytorch代码,负责模型的训练。大佬榕和小许负责了数据集的下载。数据的下载花费了几个星期,同时训练模型也花了一个多月时间。

比赛的内容

首先讲下这个比赛的内容,是产品的细粒度的图像分类任务。什么是细粒度分类?细粒度图像分类任务中,有一些大类别,每个大类别底下还有小类别。小类别之间的差异比大类别之间的差异更加细微。在imaterialist-product-2019中,主要有4层类别,第一层共有5类,然后第二层有45类,第三层大约有百来类,最后一层则共有2019类。所有的类别的具体名字不知道,只有一个代名字,最后一层则有类别的标号。

具体的类别信息在:

​link https://storage.googleapis.com/kaggle-competitions-data/kaggle/13773/368464/product_tree.pdf?GoogleAccessId=web-data@kaggle-161607.iam.gserviceaccount.com&Expires=1562147488&Signature=QUPL60xTxNZW5c4whytfOWYuQfR5eEY0JFIpZE%2F5CE6RQXA6bPia6XpUjOtQRrkw1lhXr7HQiSdBEP1C3X23G4MkBV0CtDY2Uvyzfv3WSVQWUhEt4cbZCj68AoZKr8gtI6%2BFqddv%2FRF%2F%2FWXnbrydhKjjT6mUgg0gSVsSjAKFZJC0mO8SUwbaR9x9%2FJuGX4yxdXSv5Th5Hy%2BFskpXH24fmcbCsfQGRo5Y6hilx3UfaZAYTYZ1b2bIfmk9qvahTWuaYBtP%2F6Ta2Rhig4M3CSFx3dFR7Q79AFH0wBywd1viMRSIiNbprPcTL4spqDxy%2BS3%2FXv1Km93GlsydNBmtjMdfKQ%3D%3D

数据集的信息

类别总共是2019类。

训练样本总数是:1,004,360

验证集样本总数是:10,095

测试集样本总数是:90,834

其中训练集的图片有缺失,验证集也有。测试集没有。

训练集中,每个类样本数最多的有 1045 ;最少的有: 157 ;

样本个数的分布图为:

1561895928822

对于验证集合,所有的类别个数都为5个。样本个数分布图为:

1561896059345

可以看出训练样本集中各个类的样本数量相差很大,多的上千个,而少的一百来个,样本不均衡这个问题是一个需要解决的问题。

环境

一台带titan Xp的windows 10 机子,pytorch1.0

分类模型

采用的分类模型主要有:resnet(resnet50,resnet101,resnet161),densent(densenet161),其最好的性能列表如下:

model top-1 top-5
resnet50 59.7 86.25
resnet101 61.4 87.2
resnet161 59.5 85.7
densenet161 - 87.56

后来使用了model average的方法(其中使用了一些非最佳的模型),大概集成了8个model得到了一个最好的验证精度90.585938

训练过程的细节

数据集预处理

去除了下载中出现错误的图片

图像增强

训练:

resize(224)

randomcrop(224,224)

ColorJitter

RandomHorizontalFlip

RandomRotation

normalize

测试(验证):

resize(224)

centorcrop(224)

normalize

数据读取

用pytorch自带的dataloader,pin_memory=True, num_workers=4,batch_size 根据模型的不同,尽量取大的,并将所有的数据集放在SSD中,加快读取。

没有pin_memory 和ssd大概要4个小时一个epoch(resnet50)。

加了这两个设置,大概1.5个小时一个epoch,加速了很多。

但是一般训练一个模型还是需要2天时间(20epoches)。毕竟xp的显存只有11GB,实际中用的最多只能用10GB。

为了节省显存,采用更节约显存的sgd模型。Adam需要保存很多二阶和二阶的梯度信息,同时也没有比SGD好到那里去,因此采用SGD。

优化

所有的模型都使用了pretrained model.

所有的模型训练的epochs都小于20.

优化器:SGD with momentum

学习率调度:SGDR 和CyclicLR(由于采用了SGDR和CyclicLR,lr的一个调度的结果也被我用于集成。参考黄高的论文)

学习率区间评估:lr_find+eye see

大佬的比赛方案

比赛结束了,kaggle上出现了大佬的方案,有以下我没有做到的:

  1. 采用更好的分类模型SENET
  2. 考虑使用autoAugment图像增强
  3. 考虑类的不均衡问题
  4. 数据集中去除小图片
  5. TTA

值得一说的处理不均衡问题,我目前了解有三个方法:

  1. 上采用和下采样;同时pytorch里面也有一个加权采样器;
  2. 将训练集分成两个部分,第一部分是均衡的样本集合,每个类个数相同,该部分先用于训练模型;第二个部分是训练集剩下的部分,用于finetune上面的模型
  3. 使用加权loss比如focal loss等。