2021科大讯飞广告图片素材分类算法挑战赛—参赛总结
发布于 2021-09-28 12:15
摘要
比赛网址
:https://challenge.xfyun.cn/topic/info?type=ad-2021&ch=dc-zmt-05赛题任务
:本次分类算法任务中,讯飞AI营销将提供海量现网流量中的广告图片素材作为训练数据,参赛选手基于提供的训练数据构建模型,实现自动化广告图片素材分类。数据分析
:对类别标签进行可视化得知,类别标签不均衡,有些类别有几千张图片,而有的只有十几二十张。接着计算出整个数据集的均值和标准差,用于后续的归一化处理。模型选择
:一开始用了之前验证码识别的模型去做,结果准确率只有不到60%,然后接着试了下baseline的模型efficientnet_b0,准确率也只有70+。后来从resnet, alexnet, vgg, squeezenet, densenet, inception模型中试了个遍,最后确定了resnext50_32x4d模型最优。训练方案
:基于resnext50_32x4d模型构建自己的baseline。期间,试过常规数据增强、以及针对类别不均衡做的自定义数据增强:即根据类别占比来确定以多大的概率执行数据增强,占比越小则数据增强就越大,得到用于训练的图片就越多;试过用FocalLoss来应对类别不均衡;试过用不同的损失函数和优化器;试过使用灰度图和彩色图进行训练;试过用不同大小的图片尺寸输入网络;试过……,最后才确定了最终的方案。模型融合
:最终通过改变学习率训练不同的模型,采用加权平均进行模型融合,得到最终的预测输出。赛题得分
:初赛最终成绩:0.88391分,排名:第22名;复赛最终成绩:0.87551分,排名:第23名。总结结论
:这是我参加比赛以来第一次进入复赛阶段的比赛,很有纪念意义,虽然跟前排大佬还有很大的差距,但是从中也学习到了很多知识,有机会下次再来~
赛题任务
数据分析
首先查看各个类别的数据量情况:可以看到,类别越往后数据量越少。
在求数据集的均值和标准差时,如果convert为RGB,那么有些图片会报警告:
UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
,如图片:训练集/1/87982.jpg,我不清楚这样去算三通道RGB的均值和标准差会不会有什么影响,所以就全部先convert为RGBA,再用opencv将RGBA转为RGB去计算了(强迫症不想看到任何warning)。计算均值和标准差的代码如下:
模型选择
本次比赛所用到的模型均来自与timm
模块(在kaggle上很受欢迎),是一个类似torchvision.models
模块一样,可直接调用各种预训练模型。下面定义自己的模型:
训练方案
构建自己的baseline方案:
训练周期:17 学习率:0.0001 批次大小:50 类别不均衡:不作相应处理 数据集划分:训练集的90%训练模型,10%验证模型 数据增强:不增强,只做简单缩放以及归一化处理 损失函数:多标签损失函数MultiLabelSoftMarginLoss 优化器:Adam
基于baseline,各个点所做的尝试:
训练周期,限于kaggle单次session的时间限制(9h),最大训练周期只能设置为17(一个周期大约0.5h) 批次大小,限于kaggle内存的限制,最大限度的批次大小为50 数据集划分,前期采用固定seed来更好地比较不同改变下的得分情况;后期不固定seed去训练多个模型;以及最后全量训练 数据增强,一套组合拳:RandomHorizontalFlip、RandomVerticalFlip、ColorJitter、RandomErasing 类别不均衡,按类别占比赋予权重,再根据概率是否执行这套组合拳,即这套组合拳打下来样本越少的类别数据增强就越厉害 损失函数,使用FocalLoss损失函数去应对类别不均衡的现象,即如果预测错了样本量越少的类别,其损失值就越大;尝试使用交叉熵损失函数CrossEntropyLoss 优化器,尝试改用随机梯度下降SGD 学习率,在使用Adam时,学习率在0.0001 ~ 0.001范围内尝试;在使用SGD时,学习率在0.01 ~ 0.5范围内尝试
最终方案:
模型融合
根据最终方案,调整学习率训练多个模型;调整学习率再全量训练多个模型。然后尝试采用以下融合方法进行模型融合,得出最终的预测结果。
投票法 加权平均法
最后发现加权平均法要略胜一筹,具体的模型融合核心代码:
赛题得分
初赛,排名:22/197,最终得分:0.88391,晋级复赛(前20%名晋级)
复赛,排名:23/28,最终得分:0.87551,没能进入决赛(前三名)
写在最后
这次比赛的时间跨度算是比较长的了,初赛两个月,复赛一个月,虽然不是每天都有在研究赛题上分,而是用周末空闲的时间来打比赛都觉得时间是足够的。
还有,这是我第一次打CV类比赛,很多东西学的不是很全面(只是完成过验证码识别),不知道我哪来的自信,就报名了这次比赛。
中间遇到几次瓶颈,第一次是我用验证码识别的模型来对比赛数据集进行拟合,分数连0.6都上不去,我那时候一度怀疑我之前写的验证码识别的模型,实在是太垃圾了,这种模型就只能勉强用在这种规格小的验证码图片上了。
第二次是在我逛kaggle时无意中发现了有人在使用timm模块,并且用的模型是resnext50_32x4d即本文最终确定的模型,于是我抱着试一试的想法用了一下这个模型去训练,结果分数直接上到了0.80,我一下子觉得自己似乎又可以了,然而不管怎么调参,分数都上不去了。
第三次也是最后一次,是在我看了datawhale他们写的baseline之后,我惊奇地发现,他们竟然也是用timm模块里的模型,仔细看了一遍后,我注意到他们的损失函数用的是CrossEntropyLoss。因为当时我一直是沿用了验证码识别时的损失函数和优化器,于是我试着去更换这两个东西,最后才确定了损失函数用CrossEntropyLoss,优化器用SGD是最好的,分数一直在涨,最高分是达到了线上0.86,可是再怎么调参分数又都上不去了。
最后采用了竞赛中的杀手锏模型融合,分数最终定格在了0.88391,当然这是初赛的成绩,进入复赛后,只是更换了测试集,然而使用初赛时最好成绩的模型来预测提交分数只有0.87441,直接降了一个百分点。然后我尝试了将初赛的测试集作伪标签,然而后来举办方说不允许使用,后面也就不考虑了。接着试了一下全量训练集训练模型,然而全量训练的话很难确定训练周期,于是我选择了最大的训练周期即17,结果分数有一定的上升,最终复赛分数定格在了0.87551。
最后,提前祝我们的祖国生日快乐,大家国庆节快乐~
本文来自网络或网友投稿,如有侵犯您的权益,请发邮件至:aisoutu@outlook.com 我们将第一时间删除。
相关素材