Bag of Tricks for Image Classification

发布 : 2020-10-04 分类 : 深度学习 浏览 :

加快模型训练

image.png
image.png

选用更大的 batch size

选用更大的 batch size 能够在整体上加快模型的训练,但是一般而言如果只增大 batch size,效果不会太理想.这部分目前有比较多的研究论文,比如 Facebook 的这篇:Accurate, Large Minibatch SGD:Training ImageNet in 1 Hour. 作者也总结了主要的几个解决方案:

  1. *增大学习率, *因为更大的 batch size 意味着基于每个 batch 数据计算得到的梯度更加贴近整个数据集(数学上来讲就是方差更小),因此当更新方向更加准确后,迈的步子也可以更大了.
    1. 一般而言将 batch size 修改为原来的几倍,那么初始学习率也需要修改为原来的几倍
  2. *用一个小的学习率先训几个 epoch(warmup), *因为网络的参数是随机初始化的,假如一开始就采用较大的学习率容易出现数值不稳定,这是使用 warmup 的原因。等到训练过程基本稳定了就可以使用原先设定的初始学习率进行训练了。
    1. 作者在实现 warmup 的过程中采用线性增加的策略.
    2. 举例而言,假设 warmup 阶段的初始学习率是 0,warmup 阶段共需要训练 m 个 batch 的数据(实现中 m 个 batch 共 5 个 epoch),假设训练阶段的初始学习率是 L,那么在 batch i 的学习率就设置为 i*L/m。
  3. 每个残差块的最后一个 BN 层的 γ 参数初始化为 0,我们知道 BN 层的 γ、β 参数是用来对标准化后的输入做线性变换的,也就是 γx^+β,一般 γ 参数都会初始化为 1,作者认为初始化为 0 更有利于模型的训练。
  4. 不对 bias 参数执行 weight decay 操作,weight decay 主要的作用就是通过对网络层的参数(包括 weight 和 bias)做约束(L2 正则化会使得网络层的参数更加平滑)达到减少模型过拟合的效果。

采用 16 位浮点型进行训练。

采用低精度(16 位浮点型)训练是从数值层面来做加速。一般而言现在大部分的深度学习网络的输入、网络参数、网络输出都采用 32 位浮点型,现在随着 GPU 的迭代更新(比如 V100 支持 16 为浮点型的模型训练),如果能使用 16 位浮点型参数进行训练,就可以大大加快模型的训练速度,这是作者加速训练最主要的措施,不过目前来看应该只有 V100 才能支持这样的训练。

优化网络结构部分

image.png

文章主要用的是 resnet, 所以关注了对于其结构的改造. 关于 residual block 的改进可以参考 Figure2,主要有 3 点。

  1. ResNet-B,改进部分就是将 stage 中做 downsample 的 residual block 的 downsample 操作从第一个 1x1 卷积层换成第二个 3x3 卷积层.
    1. 如果 downsample 操作放在 stride 为 2 的 1x1 卷积层,那么就会丢失较多特征信息(默认是缩减为 1/4),可以理解为有 3/4 的特征点都没有参与计算,而将 downsample 操作放在 33 卷积层则能够减少这种损失,因为即便 stride 设置为 2,但是卷积核尺寸够大,因此可以覆盖特征图上几乎所有的位置。
  2. ResNet-C,改进部分就是将 Figure1 中 input stem 部分的 7x7 卷积层用 3 个 3x3 卷积层替换。
    1. 这部分借鉴了 Inception v2 的思想,主要的考虑是计算量,毕竟大尺寸卷积核带来的计算量要比小尺寸卷积核多不少,不过如果仔细计算会发现 ResNet-C 中 3 个 3x3 卷积层的计算量并不比原来的少,这也是 Table5 中 ResNet-C 的 FLOPs 反而增加的原因。
  3. ResNet-D,改进部分是将 stage 部分做 downsample 的 residual block 的支路从 stride 为 2 的 1x1 卷积层换成 stride 为 1 的卷积层,并在前面添加一个池化层用来 downsample。
    1. 这部分参考文章的作者的个人理解是虽然池化层也会丢失信息,但至少是经过选择(比如这里是均值操作)后再丢失冗余信息,相比 stride 设置为 2 的 1*1 卷积层要好一些。

模型训练调优部分

image.png

  1. 学习率衰减策略采用 cosine 函数,这部分的实验结果对比可以参考 Figure3.
    1. 其中(a)是 cosine decay 和 step decay 的示意图,step decay 是目前比较常用的学习率衰减方式,表示训练到指定 epoch 时才衰减学习率。
    2. (b)是 2 种学习率衰减策略在效果上的对比
  2. 采用 label smoothing,这部分是将原来常用的 one-hot 类型标签做软化,这样在计算损失值时能够在一定程度上减少过拟合。
  3. 知识蒸馏(knowledge distillation),这部分其实是模型加速压缩领域的一个重要分支,表示用一个效果更好的 teacher model 训练 student model,使得 student model 在模型结构不改变的情况下提升效果。
    1. 作者采用 ResNet-152 作为 teacher model,用 ResNet-50 作为 student model,代码上通过在 ResNet 网络后添加一个蒸馏损失函数实现,这个损失函数用来评价 teacher model 输出和 student model 输出的差异,因此整体的损失函数原损失函数和蒸馏损失函数的结合.
    2. 其中 p 表示真实标签,z 表示 student model 的全连接层输出,r 表示 teacher model 的全连接层输出,T 是超参数,用来平滑 softmax 函数的输出。

image.png

  1. 引入 mixup,mixup 其实也是一种数据增强方式,假如采用 mixup 训练方式,那么每次读取 2 张输入图像,假设用(xi,yi)和(xj,yj)表示,那么通过下面这两个式子就可以合成得到一张新的图像(x, y)(注意, 只使用这个新的样本, 不再使用合成用的样本),然后用这张新图像进行训练,需要注意的是采用这种方式训练模型时要训更多 epoch。
    1. 式子中的 λ 是一个超参数,用来调节合成的比重,取值范围是[0,1], 服从分布 Beta(alpha, alpha)

image.png

在目标检测与语义分割任务上的测试

image.png

本文作者 : HeoLis
原文链接 : https://ishero.net/Bag%20of%20Tricks%20for%20Image%20Classification.html
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

学习、记录、分享、获得

微信扫一扫, 向我投食

微信扫一扫, 向我投食