冠军方案解读|世界人工智能创新大赛-服装风格分类方向
2020年世界人工智能创新大赛菁英挑战赛已经圆满落幕,获奖名单已于前日公布,我们邀请到了服装风格分类赛题的冠军来做竞赛方案解读。
概述
服装风格分类这个赛题跟其他的分类题目并没有很大的区别,本质上还是平常的分类问题。这个题目的难点可以说并不在分类任务本身,而在于:
本次比赛对于工程性要求比较高,需要完成cpu的openvino的部署,同时对速度和精度需要做权衡取舍。 该赛题的数据严重不均衡,多的类别的数据量是少的近20倍(如果没有记错的话)。不过大多数比赛都会存在数据不均衡的问题,这也是实际非特意采集数据的现状。
因此,其实我的方案也跟其他的分类任务的方案没有太大的区别。下面我就对我认为可能是对本赛题有帮助的一些策略做一个简要的阐述。
1. 数据处理
1.1 数据增强
这一个处理大家应该都会做,我做的也没有什么太特殊的地方。在这里我用的是在imagenet数据集上面用auto augmentation搜索得到的处理策略,具体的如下面代码所示:
def rand_augment_list(): # 16 oeprations and their ranges
l = [
(AutoContrast, 0, 1),
(Equalize, 0, 1),
(Invert, 0, 1),
(Rotate, 0, 30),
(Posterize, 0, 4),
(Solarize, 0, 256),
(SolarizeAdd, 0, 110),
(Color, 0.1, 1.9),
(Contrast, 0.1, 1.9),
(Brightness, 0.1, 1.9),
(Sharpness, 0.1, 1.9),
(ShearX, 0., 0.3),
(ShearY, 0., 0.3),
(CutoutAbs, 0, 40),
(TranslateXabs, 0., 100),
(TranslateYabs, 0., 100),
]
return l
做变换的时候,并不是每次所有变换都用上,而是每一次都是从里面随机抽取n个,然后每个变换的参数也是从范围里面随机取。
随机翻转,光照(用imagenet上算出来的特征向量)这些是每次都做的。
1.2 数据重(欠)采样
一般来说,这个方法也是处理数据不均衡的常用方法之一。一般来说,重采样或者欠采样都是可以的,并且我觉得他们并没有很大的区别(在我的处理方法下)。
我的处理方法是自己重新写了一个数据采样器,这个采样器会保证每次出来的batch里面的不同类别的数据量是一样的,而每个batch包含多少个类别也是可以设定的。我的训练应该是每个batch包含4类样本,然后batch的大小设置为64。不过值得一提的是,这个处理虽然是有效的,但是跟后面的一个处理策略是具有差不多作用的,这两个可能选一个做也可以了。
1.3 mixup
mixup这个策略在很多任务(比如目标检测)上面都被证明是有一定作用的。在这个赛题上面我也一样使用了这个策略。具体的细节还是直接上代码吧。
def mixup(alpha, num_classes, data, target):
with torch.no_grad():
bs = data.size(0)
c = np.random.beta(alpha, alpha)
perm = torch.randperm(bs).cuda()
md = c * data + (1-c) * data[perm, :]
mt = c * target + (1-c) * target[perm, :]
return md, mt
主要函数如上所示,可能跟一些人不同的是,这里的c是从beta分布里面取的,alpha取的0.2,然后根据这个c的比例进行混合。np.random.beta(0.2, 0.2)的概率密度如下图所示:
2. 学习率调整
这也是深度学习常用的策略,我也就不多说了。在这个赛题中我用的是半周期的cos的调整策略,在cos之前先做了线性warming up。
3. loss tricks
3.1 label smoothing
其实这是跟mixup一起的,mixup本身就带有标签的平滑的作用。如果做mixup,label smooth需要单独做,一般来说这对大多数分类任务都是有效的。
3.2 triplet loss
triplet loss的原理细节就不在这里赘述了。通俗的说,它的作用就是把同类的特征拉近,异类的特征推远。这也是数据不平衡以及few shot leaning常用的策略之一。不过有一点需要注意,triplet loss比较难调参,而且在我的实验中,它在小网络的时候会导致更加难以收敛。最后我的网络模型应该是没有加这个loss的(因为没有积分调了),但是之前的网络我试过,调得好它确实会提升一些。
4. 类间平衡转移
数据极度不平衡训练出来的模型一般来说都会偏向数据多的类别,从混淆矩阵可以看出这点。那么我们就可以根据这个,对预测出来的类别在按一定的规则进行转移。基本思路就是如果预测出来标签如果是数据多的类别,如果那么我们把它转移为top2的标签。参数的调节可以根据验证集的混淆矩阵以及输出作为基础进行调节。
这个具体实现方式可以有很多种,主要是要方便自己调, 我用的方式是转移矩阵的方式。
5. 网络
其实这个赛题由于精度原因在网络调整上做的工作几乎没有,都是因为速度的问题而去选择更小的网络,也因为速度,几乎不可能在网络做什么改动,因为改动带来的速度降低比精度提升可能更多,所以这没什么好说的。我用过的网络有:resnet,shufflenet,squeezenet。其中resnet比较简单的训练一下都可以达到0.7560的精度,相信如果不需要考虑速度的话,调一调应该可以得到0.8以上的精度。其实shufflenet跟squeezenet相差并不多,速度差距应该20fps以内(squeezenet快一点,但是精度应该是差点的),最后选择了squeezenet。
其实我认为网络方面,在这个赛题上,可能重要的不是网络结构,而是预训练模型。因为就我试过的几个网络来看,比较简单的训练就可以达到0.7左右的精度(加载了imagenet预训练)。所以如果想要做的更快,可能可以自己写更小的网络(网络结构合理的前提下),然后在imagenet上面做训练,再到衣服风格数据集上训练,可能可以做到速度和精度都比较好。