PaddleClas-SSLD知识蒸馏方法梳理(82.4%ResNet50系列模型养成之路)

简介

PaddleClas是PaddlePaddle最近开源的图像分类代码库,里面包括了目前比较常用的分类模型,ResNet、HRNet、DenseNet、ResNeXt等,配置文件里也提供了这些模型的训练脚本,总共大概是117个模型,当然pretrained model权重文件也都给出来了,github地址在这里:https://github.com/PaddlePaddle/PaddleClas

模型库其实还是比较丰富,不过里面最吸引人的可能还是ImageNet1k val数据集上**top1 acc 82.4%**的ResNet50-Vd预训练模型,这个是224的图像分类情况下得到的,也是目前开源的精度最高的ResNet50系列模型。

这个模型主要是基Paddle自研的SSLD这个知识蒸馏方案得到的,全称是:Simple Semi-supervised Label Distillation,当然仅仅用ImageNet1k数据是很难做到这个高的指标的,PaddleClas里面引入了ImageNet22k数据集,并且对数据进行了抽样选择训练,这里主要是说下82.4%的指标实现思路,主要参考了PaddleClas的蒸馏文档:https://github.com/PaddlePaddle/PaddleClas/blob/master/docs/zh_CN/advanced_tutorials/distillation/distillation.md

预训练模型可以从这里下载:https://github.com/PaddlePaddle/PaddleClas/blob/master/docs/zh_CN/models/models_intro.md

带ssld后缀的模型都是使用SSLD知识蒸馏方案得到的模型。

SSLD知识蒸馏策略

2.1 简介

SSLD的流程图如下图所示。

在这里插入图片描述

数据还是毋庸置疑地有效,要想提升精度,额外数据是必须的。

首先从ImageNet22k中挖掘出了近400万张图片,与ImageNet-1k训练集整合在一起,得到了一个新的包含500万张图片的数据集。然后,将学生模型与教师模型组合成一个新的网络,该网络分别输出学生模型和教师模型的预测分布,与此同时,固定教师模型整个网络的梯度,而学生模型可以做正常的反向传播。最后,将两个模型的logits经过softmax激活函数转换为soft label,并将二者的soft label做JS散度作为损失函数,用于蒸馏模型训练。这里其实PaddleClas也开源了79%地MobileNetV3 large模型,主要也是以这个模型蒸馏为例,给出了一些消融实验结论。

  • 教师模型的选择。在进行知识蒸馏时,如果教师模型与学生模型的结构差异太大,蒸馏得到的结果反而不会有太大收益。相同结构下,精度更高的教师模型对结果也有很大影响。相比于79.12%的ResNet50_vd教师模型,使用82.4%的ResNet50_vd教师模型可以带来0.4%的绝对精度收益(75.6%->76.0%)。

  • 改进loss计算方法。分类loss计算最常用的方法就是cross entropy loss,实验发现,在使用soft label进行训练时,相对于cross entropy loss,KL div loss对模型性能提升几乎无帮助,但是使用具有对称特性的JS div loss时,在多个蒸馏任务上相比cross entropy loss均有0.2%左右的收益(76.0%->76.2%),SSLD中也基于JS div loss展开实验。

    扫描二维码关注公众号,回复: 11322838 查看本文章
  • 更多的迭代轮数。蒸馏的baseline实验只迭代了120个epoch。实验发现,迭代轮数越多,蒸馏效果越好,最终迭代了360epoch,精度指标可以达到77.1%(76.2%->77.1%)。

  • 无需数据集的真值标签,很容易扩展训练集。SSLD的loss在计算过程中,仅涉及到教师和学生模型对于相同图片的处理结果(经过softmax激活函数处理之后的soft label),因此即使图片数据不包含真值标签,也可以用来进行训练并提升模型性能。该蒸馏方案的无标签蒸馏策略也大大提升了学生模型的性能上限(77.1%->78.5%)。

  • ImageNet1k蒸馏finetune。仅使用ImageNet1k数据,使用蒸馏方法对上述模型进行finetune,最终仍然可以获得0.4%的性能提升(75.8%->78.9%)。

指标上升情况大概如下

在这里插入图片描述

数据选择

  • ImageNet22k数据包含1400W张图像,如果全部用来训练的话,训练成本太高,因此PaddleClas里面参考了FaceBook之前的一个做法,用大模型去预测所有图片,这个大模型是包含1000类的图像分类模型(ImageNet 1k)对于每一个类别,都找到得分Top-k的图片,这样总共可以找到1000k张图片,再和ImageNet1k 训练集融合在一起,组成最后的500W张图片的训练集。

  • 在这里需要注意的是,因为引入了新的数据,因此为了防止引入的新数据中包含ImageNet1k val的数据,因此需要对数据进行去重。PaddleClas里面是使用了SIFT特征相似度匹配的方法进行去重,防止添加的ImageNet22k数据集中包含ImageNet1k val的数据,但是这块去重的代码目前还没有开源。

实验部分

  • PaddleClas的蒸馏策略为大数据集训练+ImageNet1k蒸馏finetune的策略。选择合适的教师模型,首先在挑选得到的500万数据集上进行训练,然后在ImageNet1k训练集上进行finetune,最终得到蒸馏后的学生模型。
  • 在这里PaddleClas里也给出了实验的超参,有了数据,按照这个超参,是可以复现给出的精度的。主要的实验有以下几组。

教师模型的选择

为了验证教师模型和学生模型的模型大小差异和教师模型的模型精度对蒸馏结果的影响,PaddleClas提供了几组实验。训练策略统一为:cosine_decay_warmup,lr=1.3, epoch=120, bs=2048,学生模型均为从头训练。

Teacher Model Teacher Top1 Student Model Student Top1
ResNeXt101_32x16d_wsl 84.2% MobileNetV3_large_x1_0 75.78%
ResNet50_vd 79.12% MobileNetV3_large_x1_0 75.60%
ResNet50_vd 82.35% MobileNetV3_large_x1_0 76.00%

从表中可以看出

教师模型结构相同时,其精度越高,最终的蒸馏效果也会更好一些。

教师模型与学生模型的模型大小差异不宜过大,否则反而会影响蒸馏结果的精度。

因此最终在蒸馏实验中,对于ResNet系列学生模型,使用ResNeXt101_32x16d_wsl作为教师模型;对于MobileNet系列学生模型,使用蒸馏得到的ResNet50_vd作为教师模型。

大数据蒸馏

基于PaddleClas的蒸馏策略为大数据集训练+imagenet1k finetune的策略。

针对从ImageNet22k挑选出的400万数据,融合imagenet1k训练集,组成共500万的训练集进行训练,具体地,在不同模型上的训练超参及效果如下。

Student Model num_epoch l2_ecay batch size/gpu cards base lr learning rate decay top1 acc
MobileNetV1 360 3e-5 4096/8 1.6 cosine_decay_warmup 77.65%
MobileNetV2 360 1e-5 3072/8 0.54 cosine_decay_warmup 76.34%
MobileNetV3_large_x1_0 360 1e-5 5760/24 3.65625 cosine_decay_warmup 78.54%
MobileNetV3_small_x1_0 360 1e-5 5760/24 3.65625 cosine_decay_warmup 70.11%
ResNet50_vd 360 7e-5 1024/32 0.4 cosine_decay_warmup 82.07%
ResNet101_vd 360 7e-5 1024/32 0.4 cosine_decay_warmup 83.41%

ImageNet1k训练集finetune

对于在大数据集上训练的模型,其学习到的特征可能与ImageNet1k数据特征有偏,因此在这里使用ImageNet1k数据集对模型进行finetune。finetune的超参和finetune的精度收益如下。

Student Model num_epoch l2_ecay batch size/gpu cards base lr learning rate decay top1 acc
MobileNetV1 30 3e-5 4096/8 0.016 cosine_decay_warmup 77.89%
MobileNetV2 30 1e-5 3072/8 0.0054 cosine_decay_warmup 76.73%
MobileNetV3_large_x1_0 30 1e-5 2048/8 0.008 cosine_decay_warmup 78.96%
MobileNetV3_small_x1_0 30 1e-5 6400/32 0.025 cosine_decay_warmup 71.28%
ResNet50_vd 60 7e-5 1024/32 0.004 cosine_decay_warmup 82.39%
ResNet101_vd 30 7e-5 1024/32 0.004 cosine_decay_warmup 83.73%

实验过程中的一些问题

  • 在蒸馏的过程中,有一些地方和正常模型训练的思路还是有些出入的,在这里也需要注意一下其中的一些细节。

bn的计算方法

  • 在预测过程中,batch norm的平均值与方差是通过加载预训练模型得到(设其模式为test mode)。在训练过程中,batch norm是通过统计当前batch的信息(设其模式为train mode),与历史保存信息进行滑动平均计算得到,在蒸馏任务中,PaddleClas里提到,通过train mode,即教师模型的bn实时变化的模式,去指导学生模型,比通过test mode蒸馏,得到的学生模型性能更好一些,下面是一组实验结果。因此在该蒸馏方案中,均使用train mode去得到教师模型的soft label。
Teacher Model Teacher Top1 Student Model Student Top1
ResNet50_vd 82.35% MobileNetV3_large_x1_0 76.00%
ResNet50_vd 82.35% MobileNetV3_large_x1_0 75.84%

模型名字冲突问题的解决办法

  • 在蒸馏过程中,如果遇到命名冲突的问题,如使用ResNet50_vd蒸馏ResNet34_vd,此时直接训练,会提示相同variable名称不匹配的问题,此时可以通过给学生模型或者教师模型中的变量名添加名称的方式解决该问题,如下所示。在训练之后也可以直接根据后缀区分学生模型和教师模型各自包含的参数。
def net(self, input, class_dim=1000):
    student = ResNet34_vd(postfix_name="_student")
    out_student = student.net( input, class_dim=class_dim )

    teacher = ResNet50_vd()
    out_teacher = teacher.net( input, class_dim=class_dim )
    out_teacher.stop_gradient = True

    return  out_teacher, out_student
  • 训练完成后,可以通过批量重名的方式修改学生模型的参数,以上述代码为例,批量重命名的命令行如下。
cd model_final # enter model dir
for var in ./*_student; do cp "$var" "../student_model/${var%_student}"; done # batch copy and rename

应用

猜你喜欢

转载自blog.csdn.net/u012526003/article/details/106160464
今日推荐